From 4ab4b247e6c9ad3781001d2bf95e95447b1d760a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Mon, 26 Sep 2022 11:59:25 +0200 Subject: [PATCH 01/51] Bump backport to 8.9.4 (#141741) --- package.json | 2 +- yarn.lock | 94 +++++++++++++++++++++++++++++++++++----------------- 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index be723374e4356..3c439a01a9b3d 100644 --- a/package.json +++ b/package.json @@ -1265,7 +1265,7 @@ "babel-plugin-require-context-hook": "^1.0.0", "babel-plugin-styled-components": "^2.0.7", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", - "backport": "^8.9.2", + "backport": "^8.9.4", "callsites": "^3.1.0", "chance": "1.0.18", "chokidar": "^3.5.3", diff --git a/yarn.lock b/yarn.lock index 374d3119e018e..23369504cad0a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4284,6 +4284,11 @@ resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-12.10.1.tgz#57b5cc6c7b4e55d8642c93d06401fb1af4839899" integrity sha512-P+SukKanjFY0ZhsK6wSVnQmxTP2eVPPE8OPSNuxaMYtgVzwJZgfGdwlYjf4RlRU4vLEw4ts2fsE2icG4nZ5ddQ== +"@octokit/openapi-types@^13.4.0": + version "13.4.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-13.4.0.tgz#06fe8fda93bf21bdd397fe7ef8805249efda6c06" + integrity sha512-2mVzW0X1+HDO3jF80/+QFZNzJiTefELKbhMu6yaBYbp/1gSMkVDm4rT472gJljTokWUlXaaE63m7WrWENhMDLw== + "@octokit/plugin-paginate-rest@^1.1.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz#004170acf8c2be535aba26727867d692f7b488fc" @@ -4291,12 +4296,12 @@ dependencies: "@octokit/types" "^2.0.1" -"@octokit/plugin-paginate-rest@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-3.0.0.tgz#df779de686aeb21b5e776e4318defc33b0418566" - integrity sha512-fvw0Q5IXnn60D32sKeLIxgXCEZ7BTSAjJd8cFAE6QU5qUp0xo7LjFUjjX1J5D7HgN355CN4EXE4+Q1/96JaNUA== +"@octokit/plugin-paginate-rest@^4.0.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-4.1.0.tgz#670ac9ac369448c69a2371bfcd7e2b37d95534f2" + integrity sha512-2O5K5fpajYG5g62wjzHR7/cWYaCA88CextAW3vFP+yoIHD0KEdlVMHfM5/i5LyV+JMmqiYW7w5qfg46FR+McNw== dependencies: - "@octokit/types" "^6.39.0" + "@octokit/types" "^7.1.1" "@octokit/plugin-request-log@^1.0.0", "@octokit/plugin-request-log@^1.0.4": version "1.0.4" @@ -4411,17 +4416,17 @@ once "^1.4.0" universal-user-agent "^4.0.0" -"@octokit/rest@^19.0.3": - version "19.0.3" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.3.tgz#b9a4e8dc8d53e030d611c053153ee6045f080f02" - integrity sha512-5arkTsnnRT7/sbI4fqgSJ35KiFaN7zQm0uQiQtivNQLI8RQx8EHwJCajcTUwmaCMNDg7tdCvqAnc7uvHHPxrtQ== +"@octokit/rest@^19.0.4": + version "19.0.4" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.4.tgz#fd8bed1cefffa486e9ae46a9dc608ce81bcfcbdd" + integrity sha512-LwG668+6lE8zlSYOfwPj4FxWdv/qFXYBpv79TWIQEpBLKA9D/IMcWsF/U9RGpA3YqMVDiTxpgVpEW3zTFfPFTA== dependencies: "@octokit/core" "^4.0.0" - "@octokit/plugin-paginate-rest" "^3.0.0" + "@octokit/plugin-paginate-rest" "^4.0.0" "@octokit/plugin-request-log" "^1.0.4" "@octokit/plugin-rest-endpoint-methods" "^6.0.0" -"@octokit/types@6.40.0", "@octokit/types@^6.0.0", "@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.39.0": +"@octokit/types@6.40.0", "@octokit/types@^6.0.0", "@octokit/types@^6.0.3", "@octokit/types@^6.16.1": version "6.40.0" resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.40.0.tgz#f2e665196d419e19bb4265603cf904a820505d0e" integrity sha512-MFZOU5r8SwgJWDMhrLUSvyJPtVsqA6VnbVI3TNbsmw+Jnvrktzvq2fYES/6RiJA/5Ykdwq4mJmtlYUfW7CGjmw== @@ -4442,6 +4447,13 @@ dependencies: "@types/node" ">= 8" +"@octokit/types@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-7.1.1.tgz#a30fd6ca3279d59d532fa75583d65d93b7588e6d" + integrity sha512-Dx6cNTORyVaKY0Yeb9MbHksk79L8GXsihbG6PtWqTpkyA2TY1qBWE26EQXVG3dHwY9Femdd/WEeRUEiD0+H3TQ== + dependencies: + "@octokit/openapi-types" "^13.4.0" + "@openpgp/web-stream-tools@^0.0.10": version "0.0.10" resolved "https://registry.yarnpkg.com/@openpgp/web-stream-tools/-/web-stream-tools-0.0.10.tgz#4496390da9715c9bfc581ad144f9fb8a36a37775" @@ -10478,18 +10490,18 @@ babel-runtime@6.x, babel-runtime@^6.26.0: core-js "^2.4.0" regenerator-runtime "^0.11.0" -backport@^8.9.2: - version "8.9.2" - resolved "https://registry.yarnpkg.com/backport/-/backport-8.9.2.tgz#cf0ec69428f9e86c20e1898dd77e8f6c12bf5afa" - integrity sha512-0ghVAwSssE0mamADGnsOybWn7RroKLSf9r4uU1IpAlxxa2zkRecfnGuSfEa5L1tQjh7lJwI/2i01JR6154r+qg== +backport@^8.9.4: + version "8.9.4" + resolved "https://registry.yarnpkg.com/backport/-/backport-8.9.4.tgz#2bbe58fd766ebda6c760852d029630a277098a54" + integrity sha512-REMiogdMQ+TOLQoEABttcCevbxJ14xlCMkHn7es0ZTeCleHz6T2bl93w/Fe+JIttuyZ0e8oPQW2DVe1feTG1pw== dependencies: - "@octokit/rest" "^19.0.3" + "@octokit/rest" "^19.0.4" axios "^0.27.2" dedent "^0.7.0" del "^6.1.1" - dotenv "^16.0.1" + dotenv "^16.0.2" find-up "^5.0.0" - graphql "^16.5.0" + graphql "^16.6.0" graphql-tag "^2.12.6" inquirer "^8.2.3" lodash "^4.17.21" @@ -10499,9 +10511,9 @@ backport@^8.9.2: strip-json-comments "^3.1.1" terminal-link "^2.1.1" utility-types "^3.10.0" - winston "^3.8.1" + winston "^3.8.2" yargs "^17.5.1" - yargs-parser "^21.0.1" + yargs-parser "^21.1.1" bail@^1.0.0: version "1.0.2" @@ -13642,10 +13654,10 @@ dotenv-expand@^5.1.0: resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== -dotenv@^16.0.1: - version "16.0.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d" - integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ== +dotenv@^16.0.2: + version "16.0.2" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.2.tgz#0b0f8652c016a3858ef795024508cddc4bffc5bf" + integrity sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA== dotenv@^8.0.0: version "8.2.0" @@ -16136,10 +16148,10 @@ graphql-tag@^2.12.6: dependencies: tslib "^2.1.0" -graphql@^16.5.0: - version "16.5.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.5.0.tgz#41b5c1182eaac7f3d47164fb247f61e4dfb69c85" - integrity sha512-qbHgh8Ix+j/qY+a/ZcJnFQ+j8ezakqPiHwPiZhV/3PgGlgf96QMBB5/f2rkiC9sgLoy/xvT6TSiaf2nTHJh5iA== +graphql@^16.6.0: + version "16.6.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb" + integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw== growly@^1.3.0: version "1.3.0" @@ -28716,7 +28728,7 @@ winston-transport@^4.5.0: readable-stream "^3.6.0" triple-beam "^1.3.0" -winston@^3.3.3, winston@^3.8.1: +winston@^3.3.3: version "3.8.1" resolved "https://registry.yarnpkg.com/winston/-/winston-3.8.1.tgz#76f15b3478cde170b780234e0c4cf805c5a7fb57" integrity sha512-r+6YAiCR4uI3N8eQNOg8k3P3PqwAm20cLKlzVD9E66Ch39+LZC+VH1UKf9JemQj2B3QoUHfKD7Poewn0Pr3Y1w== @@ -28732,6 +28744,23 @@ winston@^3.3.3, winston@^3.8.1: triple-beam "^1.3.0" winston-transport "^4.5.0" +winston@^3.8.2: + version "3.8.2" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.8.2.tgz#56e16b34022eb4cff2638196d9646d7430fdad50" + integrity sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew== + dependencies: + "@colors/colors" "1.5.0" + "@dabh/diagnostics" "^2.0.2" + async "^3.2.3" + is-stream "^2.0.0" + logform "^2.4.0" + one-time "^1.0.0" + readable-stream "^3.4.0" + safe-stable-stringify "^2.3.1" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.5.0" + wkt-parser@^1.2.4: version "1.3.2" resolved "https://registry.yarnpkg.com/wkt-parser/-/wkt-parser-1.3.2.tgz#deeff04a21edc5b170a60da418e9ed1d1ab0e219" @@ -29000,11 +29029,16 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^21.0.0, yargs-parser@^21.0.1: +yargs-parser@^21.0.0: version "21.0.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + yargs-unparser@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" From c17a468cf79c5481cbce5ddb3c3f086efd212b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Mon, 26 Sep 2022 12:48:39 +0200 Subject: [PATCH 02/51] [APM] Use bundled version of APM integration (#141624) --- .../client/apm_synthtrace_kibana_client.ts | 52 +++++++++++-------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts b/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts index 7bd2443031c80..133ec096370b9 100644 --- a/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts +++ b/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_kibana_client.ts @@ -7,7 +7,6 @@ */ import fetch from 'node-fetch'; -import Semver from 'semver'; import { Logger } from '../../utils/create_logger'; export class ApmSynthtraceKibanaClient { @@ -53,31 +52,33 @@ export class ApmSynthtraceKibanaClient { return kibanaUrl; }); } - async fetchLatestApmPackageVersion(currentKibanaVersion: string) { - const url = `https://epr-snapshot.elastic.co/search?package=apm&prerelease=true&all=true&kibana.version=${currentKibanaVersion}`; - const response = await fetch(url, { method: 'GET' }); - const json = (await response.json()) as Array<{ version: string }>; - const packageVersions = (json ?? []).map((item) => item.version).sort(Semver.rcompare); - const validPackageVersions = packageVersions.filter((v) => Semver.valid(v)); - const bestMatch = validPackageVersions[0]; - if (!bestMatch) { - throw new Error( - `None of the available APM package versions matches the current Kibana version (${currentKibanaVersion}). The latest available version is ${packageVersions[0]}. This can happen if the Kibana version was recently bumped, and no matching APM package was released. Reach out to the fleet team if this persists.` - ); - } - return bestMatch; + + async fetchLatestApmPackageVersion( + kibanaUrl: string, + version: string, + username: string, + password: string + ) { + const url = `${kibanaUrl}/api/fleet/epm/packages/apm`; + const response = await fetch(url, { + method: 'GET', + headers: kibanaHeaders(username, password), + }); + const json = (await response.json()) as { item: { latestVersion: string } }; + const { latestVersion } = json.item; + return latestVersion; } async installApmPackage(kibanaUrl: string, version: string, username: string, password: string) { - const packageVersion = await this.fetchLatestApmPackageVersion(version); + const packageVersion = await this.fetchLatestApmPackageVersion( + kibanaUrl, + version, + username, + password + ); const response = await fetch(`${kibanaUrl}/api/fleet/epm/packages/apm/${packageVersion}`, { method: 'POST', - headers: { - Authorization: 'Basic ' + Buffer.from(username + ':' + password).toString('base64'), - Accept: 'application/json', - 'Content-Type': 'application/json', - 'kbn-xsrf': 'kibana', - }, + headers: kibanaHeaders(username, password), body: '{"force":true}', }); @@ -93,3 +94,12 @@ export class ApmSynthtraceKibanaClient { } else this.logger.error(responseJson); } } + +function kibanaHeaders(username: string, password: string) { + return { + Authorization: 'Basic ' + Buffer.from(username + ':' + password).toString('base64'), + Accept: 'application/json', + 'Content-Type': 'application/json', + 'kbn-xsrf': 'kibana', + }; +} From 668a9899d34de12c1e3a90925b0c30bad1edee32 Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov <53621505+mibragimov@users.noreply.github.com> Date: Mon, 26 Sep 2022 17:04:09 +0500 Subject: [PATCH 03/51] [Console] Add tests for context menu and its actions (#141202) * Add tests for context menu and its actions * Skip test if clipboard permission is not granted * Fix type checks * Remove log statement Co-authored-by: Muhammad Ibragimov --- .../application/components/console_menu.tsx | 3 +- test/functional/apps/console/_context_menu.ts | 104 ++++++++++++++++++ test/functional/apps/console/index.js | 1 + test/functional/page_objects/console_page.ts | 36 ++++++ 4 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 test/functional/apps/console/_context_menu.ts diff --git a/src/plugins/console/public/application/components/console_menu.tsx b/src/plugins/console/public/application/components/console_menu.tsx index 3f5113b3ac44f..b22fd7db9baab 100644 --- a/src/plugins/console/public/application/components/console_menu.tsx +++ b/src/plugins/console/public/application/components/console_menu.tsx @@ -128,6 +128,7 @@ export class ConsoleMenu extends Component { const items = [ { @@ -174,7 +175,7 @@ export class ConsoleMenu extends Component { panelPaddingSize="none" anchorPosition="downLeft" > - + ); diff --git a/test/functional/apps/console/_context_menu.ts b/test/functional/apps/console/_context_menu.ts new file mode 100644 index 0000000000000..8114d4d05097e --- /dev/null +++ b/test/functional/apps/console/_context_menu.ts @@ -0,0 +1,104 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const log = getService('log'); + const retry = getService('retry'); + const PageObjects = getPageObjects(['common', 'console']); + const browser = getService('browser'); + const toasts = getService('toasts'); + + describe('console context menu', function testContextMenu() { + before(async () => { + await PageObjects.common.navigateToApp('console'); + // Ensure that the text area can be interacted with + await PageObjects.console.closeHelpIfExists(); + await PageObjects.console.clearTextArea(); + }); + + it('should open context menu', async () => { + expect(await PageObjects.console.isContextMenuOpen()).to.be(false); + await PageObjects.console.enterRequest(); + await PageObjects.console.clickContextMenu(); + expect(PageObjects.console.isContextMenuOpen()).to.be.eql(true); + }); + + it('should have options to copy as curl, open documentation, and auto indent', async () => { + await PageObjects.console.clickContextMenu(); + expect(PageObjects.console.isContextMenuOpen()).to.be.eql(true); + expect(PageObjects.console.isCopyAsCurlButtonVisible()).to.be.eql(true); + expect(PageObjects.console.isOpenDocumentationButtonVisible()).to.be.eql(true); + expect(PageObjects.console.isAutoIndentButtonVisible()).to.be.eql(true); + }); + + it('should copy as curl and show toast when copy as curl button is clicked', async () => { + await PageObjects.console.clickContextMenu(); + await PageObjects.console.clickCopyAsCurlButton(); + + const resultToast = await toasts.getToastElement(1); + const toastText = await resultToast.getVisibleText(); + + if (toastText.includes('Write permission denied')) { + log.debug('Write permission denied, skipping test'); + return; + } + + expect(toastText).to.be('Request copied as cURL'); + + const canReadClipboard = await browser.checkBrowserPermission('clipboard-read'); + if (canReadClipboard) { + const clipboardText = await browser.getClipboardValue(); + expect(clipboardText).to.contain('curl -XGET'); + } + }); + + it('should open documentation when open documentation button is clicked', async () => { + await PageObjects.console.clickContextMenu(); + await PageObjects.console.clickOpenDocumentationButton(); + + await retry.tryForTime(10000, async () => { + await browser.switchTab(1); + }); + + // Retry until the documentation is loaded + await retry.try(async () => { + const url = await browser.getCurrentUrl(); + expect(url).to.contain('search-search.html'); + }); + + // Close the documentation tab + await browser.closeCurrentWindow(); + await browser.switchTab(0); + }); + + it('should auto indent when auto indent button is clicked', async () => { + await PageObjects.console.clearTextArea(); + await PageObjects.console.enterRequest('GET _search\n{"query": {"match_all": {}}}'); + await PageObjects.console.clickContextMenu(); + await PageObjects.console.clickAutoIndentButton(); + // Retry until the request is auto indented + await retry.try(async () => { + const request = await PageObjects.console.getRequest(); + expect(request).to.be.eql('GET _search\n{\n "query": {\n "match_all": {}\n }\n}'); + }); + }); + + it('should condense when auto indent button is clicked again', async () => { + await PageObjects.console.clickContextMenu(); + await PageObjects.console.clickAutoIndentButton(); + // Retry until the request is condensed + await retry.try(async () => { + const request = await PageObjects.console.getRequest(); + expect(request).to.be.eql('GET _search\n{"query":{"match_all":{}}}'); + }); + }); + }); +} diff --git a/test/functional/apps/console/index.js b/test/functional/apps/console/index.js index 9dee3cda26e83..06c29f0e031ec 100644 --- a/test/functional/apps/console/index.js +++ b/test/functional/apps/console/index.js @@ -24,6 +24,7 @@ export default function ({ getService, loadTestFile }) { loadTestFile(require.resolve('./_variables')); loadTestFile(require.resolve('./_xjson')); loadTestFile(require.resolve('./_misc_console_behavior')); + loadTestFile(require.resolve('./_context_menu')); } }); } diff --git a/test/functional/page_objects/console_page.ts b/test/functional/page_objects/console_page.ts index 50cc2e7029d48..9f662a09146e9 100644 --- a/test/functional/page_objects/console_page.ts +++ b/test/functional/page_objects/console_page.ts @@ -368,4 +368,40 @@ export class ConsolePageObject extends FtrService { const textArea = await this.testSubjects.find('console-textarea'); await textArea.pressKeys([Key[process.platform === 'darwin' ? 'COMMAND' : 'CONTROL'], '/']); } + + public async clickContextMenu() { + const contextMenu = await this.testSubjects.find('toggleConsoleMenu'); + await contextMenu.click(); + } + + public async isContextMenuOpen() { + return await this.testSubjects.exists('consoleMenu'); + } + + public async isCopyAsCurlButtonVisible() { + return await this.testSubjects.exists('consoleMenuCopyAsCurl'); + } + + public async isOpenDocumentationButtonVisible() { + return await this.testSubjects.exists('consoleMenuOpenDocs'); + } + + public async isAutoIndentButtonVisible() { + return await this.testSubjects.exists('consoleMenuAutoIndent'); + } + + public async clickCopyAsCurlButton() { + const button = await this.testSubjects.find('consoleMenuCopyAsCurl'); + await button.click(); + } + + public async clickOpenDocumentationButton() { + const button = await this.testSubjects.find('consoleMenuOpenDocs'); + await button.click(); + } + + public async clickAutoIndentButton() { + const button = await this.testSubjects.find('consoleMenuAutoIndent'); + await button.click(); + } } From 24b7d34c55949e47b1d085190900dc8376acc5c9 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Mon, 26 Sep 2022 05:16:29 -0700 Subject: [PATCH 04/51] =?UTF-8?q?[ML]=20Explain=20Log=20Rate=20Spikes:=20A?= =?UTF-8?q?dd=20tooltip=20for=20group=20columns=20and=20adjust=20copy=20to?= =?UTF-8?q?=20reflect=20groups=20in=20ot=E2=80=A6=20(#141687)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates the groups table column tooltips to reflect group language and adds a tooltip to the Group column for clarification of column values. --- .../spike_analysis_table_groups.tsx | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx index 5bbc0cecae4d4..6c8da64cb0e89 100644 --- a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx +++ b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table_groups.tsx @@ -228,9 +228,26 @@ export const SpikeAnalysisGroupsTable: FC = ({ { 'data-test-subj': 'aiopsSpikeAnalysisGroupsTableColumnGroup', field: 'group', - name: i18n.translate('xpack.aiops.explainLogRateSpikes.spikeAnalysisTableGroups.groupLabel', { - defaultMessage: 'Group', - }), + name: ( + + <> + + + + + ), render: (_, { group, repeatedValues }) => { const valuesBadges = []; for (const fieldName in group) { @@ -287,7 +304,7 @@ export const SpikeAnalysisGroupsTable: FC = ({ 'xpack.aiops.explainLogRateSpikes.spikeAnalysisTableGroups.logRateColumnTooltip', { defaultMessage: - 'A visual representation of the impact of the field on the message rate difference', + 'A visual representation of the impact of the group on the message rate difference', } )} > @@ -361,9 +378,9 @@ export const SpikeAnalysisGroupsTable: FC = ({ From 62820968a76c521036bc7a2f41a2de313576bbbf Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 26 Sep 2022 14:23:01 +0200 Subject: [PATCH 05/51] [Security Solution][Detections] Format execution gap in a human readable way (#141363) **Fixes:** [#138872](https://github.com/elastic/kibana/issues/138872) ## Summary The patch formats the rule execution gap column on the rule monitoring tab in a human readable way. Before: ![image](https://user-images.githubusercontent.com/3775283/191710889-9b3fde9d-32c8-4beb-8a9f-28a0143cf41c.png) After: ![image](https://user-images.githubusercontent.com/3775283/191710563-fe74e6fc-1a88-4b5a-aac5-10b6e61945b5.png) ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [x] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --- .../pages/detection_engine/rules/all/use_columns.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_columns.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_columns.tsx index 3b413cf67e4d5..c5032a1eb9b72 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_columns.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_columns.tsx @@ -9,6 +9,7 @@ import type { EuiBasicTableColumn, EuiTableActionsColumnType } from '@elastic/eu import { EuiBadge, EuiLink, EuiText, EuiToolTip } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import React, { useMemo } from 'react'; +import moment from 'moment'; import { IntegrationsPopover } from '../../../../components/rules/related_integrations/integrations_popover'; import { DEFAULT_RELATIVE_DATE_THRESHOLD, @@ -387,7 +388,7 @@ export const useMonitoringColumns = ({ hasPermissions }: ColumnsProps): TableCol ), render: (value: DurationMetric | undefined) => ( - {value != null ? value.toFixed() : getEmptyTagValue()} + {value != null ? moment.duration(value, 'seconds').humanize() : getEmptyTagValue()} ), sortable: !!isInMemorySorting, From add2a1240de10fdb6243d8bd80b0bd6c4719989f Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 26 Sep 2022 14:25:47 +0200 Subject: [PATCH 06/51] [Files] Dispose of subscriptions on unmount (#141597) * added dispose logic to state * hook dispose logic in to component lifecycle --- .../components/upload_file/upload_file.tsx | 2 + .../components/upload_file/upload_state.ts | 60 +++++++++++-------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/files/public/components/upload_file/upload_file.tsx b/x-pack/plugins/files/public/components/upload_file/upload_file.tsx index c3b958c12d22d..8e0d8ed59392b 100644 --- a/x-pack/plugins/files/public/components/upload_file/upload_file.tsx +++ b/x-pack/plugins/files/public/components/upload_file/upload_file.tsx @@ -117,6 +117,8 @@ export const UploadFile = ({ return () => subs.forEach((sub) => sub.unsubscribe()); }, [uploadState, onDone, onError]); + useEffect(() => uploadState.dispose, [uploadState]); + return ( (); + private subscriptions: Subscription[]; + constructor( private readonly fileKind: FileKind, private readonly client: FilesClient, private readonly opts: UploadOptions = { allowRepeatedUploads: false } ) { const latestFiles$ = this.files$$.pipe(switchMap((files$) => combineLatest(files$))); - - latestFiles$ - .pipe( - map((files) => files.some((file) => file.status === 'uploading')), - distinctUntilChanged() - ) - .subscribe(this.uploading$); - - latestFiles$ - .pipe( - map((files) => { - const errorFile = files.find((file) => Boolean(file.error)); - return errorFile ? errorFile.error : undefined; - }), - filter(Boolean) - ) - .subscribe(this.error$); - - latestFiles$ - .pipe( - filter( - (files) => Boolean(files.length) && files.every((file) => file.status === 'uploaded') - ), - map((files) => files.map((file) => ({ id: file.id!, kind: this.fileKind.id }))) - ) - .subscribe(this.done$); + this.subscriptions = [ + latestFiles$ + .pipe( + map((files) => files.some((file) => file.status === 'uploading')), + distinctUntilChanged() + ) + .subscribe(this.uploading$), + + latestFiles$ + .pipe( + map((files) => { + const errorFile = files.find((file) => Boolean(file.error)); + return errorFile ? errorFile.error : undefined; + }), + filter(Boolean) + ) + .subscribe(this.error$), + + latestFiles$ + .pipe( + filter( + (files) => Boolean(files.length) && files.every((file) => file.status === 'uploaded') + ), + map((files) => files.map((file) => ({ id: file.id!, kind: this.fileKind.id }))) + ) + .subscribe(this.done$), + ]; } public isUploading(): boolean { @@ -226,6 +230,10 @@ export class UploadState { return upload$; }; + + public dispose = (): void => { + for (const sub of this.subscriptions) sub.unsubscribe(); + }; } export const createUploadState = ({ From adffaa48d611051301d581d40280963928aeea0a Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Mon, 26 Sep 2022 14:33:20 +0200 Subject: [PATCH 07/51] [Fleet] added cardinality agg when counting acks in action_status (#141651) * added cardinality agg when counting acks in action_status * added precision_threshold, added tests for activity flyout * fixed tests * fixed tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../components/agent_activity_flyout.test.tsx | 316 ++++++++++++++++++ .../components/agent_activity_flyout.tsx | 26 +- .../server/services/agents/action_status.ts | 8 +- 3 files changed, 341 insertions(+), 9 deletions(-) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.test.tsx diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.test.tsx new file mode 100644 index 0000000000000..68a3420780039 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.test.tsx @@ -0,0 +1,316 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { act, render, fireEvent } from '@testing-library/react'; +// eslint-disable-next-line @kbn/eslint/module_migration +import { IntlProvider } from 'react-intl'; + +import { useActionStatus } from '../hooks'; +import { useGetAgentPolicies, useStartServices } from '../../../../hooks'; + +import { AgentActivityFlyout } from './agent_activity_flyout'; + +jest.mock('../hooks'); +jest.mock('../../../../hooks'); + +const mockUseActionStatus = useActionStatus as jest.Mock; +const mockUseGetAgentPolicies = useGetAgentPolicies as jest.Mock; +const mockUseStartServices = useStartServices as jest.Mock; + +describe('AgentActivityFlyout', () => { + const mockOnClose = jest.fn(); + const mockOnAbortSuccess = jest.fn(); + const mockAbortUpgrade = jest.fn(); + + beforeEach(() => { + mockOnClose.mockReset(); + mockOnAbortSuccess.mockReset(); + mockAbortUpgrade.mockReset(); + mockUseActionStatus.mockReset(); + mockUseGetAgentPolicies.mockReturnValue({ + data: { + items: [ + { id: 'policy1', name: 'Policy 1' }, + { id: 'policy2', name: 'Policy 2' }, + ], + }, + }); + mockUseStartServices.mockReturnValue({ + docLinks: { links: { fleet: { upgradeElasticAgent: 'https://elastic.co' } } }, + }); + }); + + beforeEach(() => { + jest.useFakeTimers('modern').setSystemTime(new Date('2022-09-15T10:00:00.000Z')); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + const renderComponent = () => { + return render( + + + + ); + }; + + it('should render agent activity for in progress upgrade', () => { + const mockActionStatuses = [ + { + actionId: 'action2', + nbAgentsActionCreated: 5, + nbAgentsAck: 0, + version: '8.5.0', + startTime: '2022-09-15T10:00:00.000Z', + type: 'UPGRADE', + nbAgentsActioned: 5, + status: 'IN_PROGRESS', + expiration: '2099-09-16T10:00:00.000Z', + creationTime: '2022-09-15T10:00:00.000Z', + nbAgentsFailed: 0, + }, + ]; + mockUseActionStatus.mockReturnValue({ + currentActions: mockActionStatuses, + abortUpgrade: mockAbortUpgrade, + isFirstLoading: true, + }); + const result = renderComponent(); + + expect(result.getByText('Agent activity')).toBeInTheDocument(); + + expect( + result.container.querySelector('[data-test-subj="upgradeInProgressTitle"]')!.textContent + ).toEqual('Upgrading 5 agents to version 8.5.0'); + // compare without whitespace,   doesn't match + expect( + result.container + .querySelector('[data-test-subj="upgradeInProgressDescription"]')! + .textContent?.replace(/\s/g, '') + ).toContain('Started on Sep 15, 2022 10:00 AM. Learn more'.replace(/\s/g, '')); + + act(() => { + fireEvent.click(result.getByText('Abort upgrade')); + }); + + expect(mockAbortUpgrade).toHaveBeenCalled(); + }); + + it('should render agent activity for scheduled upgrade', () => { + const mockActionStatuses = [ + { + actionId: 'action2', + nbAgentsActionCreated: 5, + nbAgentsAck: 0, + version: '8.5.0', + startTime: '2022-09-16T10:00:00.000Z', + type: 'UPGRADE', + nbAgentsActioned: 5, + status: 'IN_PROGRESS', + expiration: '2099-09-17T10:00:00.000Z', + creationTime: '2022-09-15T10:00:00.000Z', + nbAgentsFailed: 0, + }, + ]; + mockUseActionStatus.mockReturnValue({ + currentActions: mockActionStatuses, + abortUpgrade: mockAbortUpgrade, + isFirstLoading: true, + }); + const result = renderComponent(); + + expect(result.getByText('Agent activity')).toBeInTheDocument(); + + expect( + result.container.querySelector('[data-test-subj="upgradeInProgressTitle"]')!.textContent + ).toEqual('5 agents scheduled to upgrade to version 8.5.0'); + expect( + result.container + .querySelector('[data-test-subj="upgradeInProgressDescription"]')! + .textContent?.replace(/\s/g, '') + ).toContain('Scheduled for Sep 16, 2022 10:00 AM. Learn more'.replace(/\s/g, '')); + + act(() => { + fireEvent.click(result.getByText('Abort upgrade')); + }); + + expect(mockAbortUpgrade).toHaveBeenCalled(); + }); + + it('should render agent activity for complete upgrade', () => { + const mockActionStatuses = [ + { + actionId: 'action3', + nbAgentsActionCreated: 2, + nbAgentsAck: 2, + type: 'UPGRADE', + nbAgentsActioned: 2, + status: 'COMPLETE', + expiration: '2099-09-16T10:00:00.000Z', + creationTime: '2022-09-15T10:00:00.000Z', + nbAgentsFailed: 0, + completionTime: '2022-09-15T12:00:00.000Z', + }, + ]; + mockUseActionStatus.mockReturnValue({ + currentActions: mockActionStatuses, + abortUpgrade: mockAbortUpgrade, + isFirstLoading: true, + }); + const result = renderComponent(); + + expect(result.container.querySelector('[data-test-subj="statusTitle"]')!.textContent).toEqual( + '2 agents upgraded' + ); + expect( + result.container + .querySelector('[data-test-subj="statusDescription"]')! + .textContent?.replace(/\s/g, '') + ).toContain('Completed Sep 15, 2022 12:00 PM'.replace(/\s/g, '')); + }); + + it('should render agent activity for expired unenroll', () => { + const mockActionStatuses = [ + { + actionId: 'action4', + nbAgentsActionCreated: 3, + nbAgentsAck: 0, + type: 'UNENROLL', + nbAgentsActioned: 3, + status: 'EXPIRED', + expiration: '2022-09-14T10:00:00.000Z', + creationTime: '2022-09-15T10:00:00.000Z', + nbAgentsFailed: 0, + }, + ]; + mockUseActionStatus.mockReturnValue({ + currentActions: mockActionStatuses, + abortUpgrade: mockAbortUpgrade, + isFirstLoading: true, + }); + const result = renderComponent(); + + expect(result.container.querySelector('[data-test-subj="statusTitle"]')!.textContent).toEqual( + 'Agent unenrollment expired' + ); + expect( + result.container + .querySelector('[data-test-subj="statusDescription"]')! + .textContent?.replace(/\s/g, '') + ).toContain('Expired on Sep 14, 2022 10:00 AM'.replace(/\s/g, '')); + }); + + it('should render agent activity for cancelled upgrade', () => { + const mockActionStatuses = [ + { + actionId: 'action5', + nbAgentsActionCreated: 3, + nbAgentsAck: 0, + startTime: '2022-09-15T10:00:00.000Z', + type: 'UPGRADE', + nbAgentsActioned: 3, + status: 'CANCELLED', + expiration: '2099-09-16T10:00:00.000Z', + creationTime: '2022-09-15T10:00:00.000Z', + nbAgentsFailed: 0, + cancellationTime: '2022-09-15T11:00:00.000Z', + }, + ]; + mockUseActionStatus.mockReturnValue({ + currentActions: mockActionStatuses, + abortUpgrade: mockAbortUpgrade, + isFirstLoading: true, + }); + const result = renderComponent(); + + expect(result.container.querySelector('[data-test-subj="statusTitle"]')!.textContent).toEqual( + 'Agent upgrade cancelled' + ); + expect( + result.container + .querySelector('[data-test-subj="statusDescription"]')! + .textContent?.replace(/\s/g, '') + ).toContain('Cancelled on Sep 15, 2022 11:00 AM'.replace(/\s/g, '')); + }); + + it('should render agent activity for failed reassign', () => { + const mockActionStatuses = [ + { + actionId: 'action7', + nbAgentsActionCreated: 1, + nbAgentsAck: 0, + type: 'POLICY_REASSIGN', + nbAgentsActioned: 1, + status: 'FAILED', + expiration: '2099-09-16T10:00:00.000Z', + newPolicyId: 'policy1', + creationTime: '2022-09-15T10:00:00.000Z', + nbAgentsFailed: 1, + completionTime: '2022-09-15T11:00:00.000Z', + }, + ]; + mockUseActionStatus.mockReturnValue({ + currentActions: mockActionStatuses, + abortUpgrade: mockAbortUpgrade, + isFirstLoading: true, + }); + const result = renderComponent(); + + expect(result.container.querySelector('[data-test-subj="statusTitle"]')!.textContent).toEqual( + '0 of 1 agent assigned to a new policy' + ); + expect( + result.container + .querySelector('[data-test-subj="statusDescription"]')! + .textContent?.replace(/\s/g, '') + ).toContain( + 'A problem occurred during this operation. Started on Sep 15, 2022 10:00 AM.'.replace( + /\s/g, + '' + ) + ); + }); + + it('should render agent activity for unknown action', () => { + const mockActionStatuses = [ + { + actionId: 'action8', + nbAgentsActionCreated: 3, + nbAgentsAck: 0, + type: 'UNKNOWN', + nbAgentsActioned: 3, + status: 'COMPLETE', + expiration: '2022-09-14T10:00:00.000Z', + creationTime: '2022-09-15T10:00:00.000Z', + completionTime: '2022-09-15T12:00:00.000Z', + nbAgentsFailed: 0, + }, + ]; + mockUseActionStatus.mockReturnValue({ + currentActions: mockActionStatuses, + abortUpgrade: mockAbortUpgrade, + isFirstLoading: true, + }); + const result = renderComponent(); + + expect(result.container.querySelector('[data-test-subj="statusTitle"]')!.textContent).toEqual( + '0 of 3 agents actioned' + ); + expect( + result.container + .querySelector('[data-test-subj="statusDescription"]')! + .textContent?.replace(/\s/g, '') + ).toContain('Completed Sep 15, 2022 12:00 PM'.replace(/\s/g, '')); + }); +}); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.tsx index 929eb4bbf54d1..dfa6623f4a90a 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.tsx @@ -176,6 +176,7 @@ export const AgentActivityFlyout: React.FunctionComponent<{ ) : null} {Object.keys(otherDays).map((day) => ( } actions={otherDays[day]} abortUpgrade={abortUpgrade} @@ -215,9 +216,13 @@ const ActivitySection: React.FunctionComponent<{ {actions.map((currentAction) => currentAction.type === 'UPGRADE' && currentAction.status === 'IN_PROGRESS' ? ( - + ) : ( - + ) )} @@ -272,7 +277,7 @@ const inProgressTitle = (action: ActionStatus) => ( defaultMessage="{inProgressText} {nbAgents} {agents} {reassignText}{upgradeText}" values={{ nbAgents: - action.nbAgentsAck === action.nbAgentsActioned + action.nbAgentsAck >= action.nbAgentsActioned ? action.nbAgentsAck : action.nbAgentsAck === 0 ? action.nbAgentsActioned @@ -438,14 +443,19 @@ const ActivityItem: React.FunctionComponent<{ action: ActionStatus }> = ({ actio {displayByStatus[action.status].icon} - + {displayByStatus[action.status].title} - {displayByStatus[action.status].description} + + {displayByStatus[action.status].description} + @@ -486,7 +496,7 @@ export const UpgradeInProgressActivityItem: React.FunctionComponent<{ {isScheduled ? : } - + {isScheduled && action.startTime ? ( - +

{isScheduled && action.startTime ? ( <> @@ -541,7 +551,7 @@ export const UpgradeInProgressActivityItem: React.FunctionComponent<{ size="s" onClick={onClickAbortUpgrade} isLoading={isAborting} - data-test-subj="currentBulkUpgrade.abortBtn" + data-test-subj="abortBtn" > bucket.key === action.actionId ); - const nbAgentsAck = matchingBucket?.doc_count ?? 0; + const nbAgentsAck = (matchingBucket?.agent_count as any)?.value ?? 0; const completionTime = (matchingBucket?.max_timestamp as any)?.value_as_string; const nbAgentsActioned = action.nbAgentsActioned || action.nbAgentsActionCreated; const complete = nbAgentsAck >= nbAgentsActioned; From 0a7a1a9200f2677635156019e9df28bc454c6090 Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Mon, 26 Sep 2022 09:02:07 -0400 Subject: [PATCH 08/51] Create GetSLO application service (#141518) Co-authored-by: Faisal Kanout --- .../observability/server/routes/slo/route.ts | 27 ++++++++- .../server/services/slo/get_slo.test.ts | 55 +++++++++++++++++++ .../server/services/slo/get_slo.ts | 31 +++++++++++ .../server/services/slo/index.ts | 1 + .../server/types/rest_specs/slo.ts | 26 ++++----- 5 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 x-pack/plugins/observability/server/services/slo/get_slo.test.ts create mode 100644 x-pack/plugins/observability/server/services/slo/get_slo.ts diff --git a/x-pack/plugins/observability/server/routes/slo/route.ts b/x-pack/plugins/observability/server/routes/slo/route.ts index dc1db41e44995..3f04d5e0b13c6 100644 --- a/x-pack/plugins/observability/server/routes/slo/route.ts +++ b/x-pack/plugins/observability/server/routes/slo/route.ts @@ -11,14 +11,20 @@ import { DefaultResourceInstaller, DefaultTransformManager, KibanaSavedObjectsSLORepository, + GetSLO, } from '../../services/slo'; + import { ApmTransactionDurationTransformGenerator, ApmTransactionErrorRateTransformGenerator, TransformGenerator, } from '../../services/slo/transform_generators'; import { SLITypes } from '../../types/models'; -import { createSLOParamsSchema, deleteSLOParamsSchema } from '../../types/rest_specs'; +import { + createSLOParamsSchema, + deleteSLOParamsSchema, + getSLOParamsSchema, +} from '../../types/rest_specs'; import { createObservabilityServerRoute } from '../create_observability_server_route'; const transformGenerators: Record = { @@ -78,4 +84,21 @@ const deleteSLORoute = createObservabilityServerRoute({ }, }); -export const slosRouteRepository = { ...createSLORoute, ...deleteSLORoute }; +const getSLORoute = createObservabilityServerRoute({ + endpoint: 'GET /api/observability/slos/{id}', + options: { + tags: [], + }, + params: getSLOParamsSchema, + handler: async ({ context, params }) => { + const soClient = (await context.core).savedObjects.client; + const repository = new KibanaSavedObjectsSLORepository(soClient); + const getSLO = new GetSLO(repository); + + const response = await getSLO.execute(params.path.id); + + return response; + }, +}); + +export const slosRouteRepository = { ...createSLORoute, ...getSLORoute, ...deleteSLORoute }; diff --git a/x-pack/plugins/observability/server/services/slo/get_slo.test.ts b/x-pack/plugins/observability/server/services/slo/get_slo.test.ts new file mode 100644 index 0000000000000..768424d6b9eec --- /dev/null +++ b/x-pack/plugins/observability/server/services/slo/get_slo.test.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createAPMTransactionErrorRateIndicator, createSLO } from './fixtures/slo'; +import { GetSLO } from './get_slo'; +import { createSLORepositoryMock } from './mocks'; +import { SLORepository } from './slo_repository'; + +describe('GetSLO', () => { + let mockRepository: jest.Mocked; + let getSLO: GetSLO; + + beforeEach(() => { + mockRepository = createSLORepositoryMock(); + getSLO = new GetSLO(mockRepository); + }); + + describe('happy path', () => { + it('retrieves the SLO from the repository', async () => { + const slo = createSLO(createAPMTransactionErrorRateIndicator()); + mockRepository.findById.mockResolvedValueOnce(slo); + + const result = await getSLO.execute(slo.id); + + expect(mockRepository.findById).toHaveBeenCalledWith(slo.id); + expect(result).toEqual({ + id: slo.id, + name: 'irrelevant', + description: 'irrelevant', + budgeting_method: 'occurrences', + indicator: { + params: { + environment: 'irrelevant', + good_status_codes: ['2xx', '3xx', '4xx'], + service: 'irrelevant', + transaction_name: 'irrelevant', + transaction_type: 'irrelevant', + }, + type: 'slo.apm.transaction_error_rate', + }, + objective: { + target: 0.999, + }, + time_window: { + duration: '7d', + is_rolling: true, + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/observability/server/services/slo/get_slo.ts b/x-pack/plugins/observability/server/services/slo/get_slo.ts new file mode 100644 index 0000000000000..1730dec464964 --- /dev/null +++ b/x-pack/plugins/observability/server/services/slo/get_slo.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SLO } from '../../types/models'; +import { GetSLOResponse } from '../../types/rest_specs'; +import { SLORepository } from './slo_repository'; + +export class GetSLO { + constructor(private repository: SLORepository) {} + + public async execute(sloId: string): Promise { + const slo = await this.repository.findById(sloId); + return this.toResponse(slo); + } + + private toResponse(slo: SLO): GetSLOResponse { + return { + id: slo.id, + name: slo.name, + description: slo.description, + indicator: slo.indicator, + time_window: slo.time_window, + budgeting_method: slo.budgeting_method, + objective: slo.objective, + }; + } +} diff --git a/x-pack/plugins/observability/server/services/slo/index.ts b/x-pack/plugins/observability/server/services/slo/index.ts index 895a7f4497ad5..7515262628f08 100644 --- a/x-pack/plugins/observability/server/services/slo/index.ts +++ b/x-pack/plugins/observability/server/services/slo/index.ts @@ -10,3 +10,4 @@ export * from './slo_repository'; export * from './transform_manager'; export * from './create_slo'; export * from './delete_slo'; +export * from './get_slo'; diff --git a/x-pack/plugins/observability/server/types/rest_specs/slo.ts b/x-pack/plugins/observability/server/types/rest_specs/slo.ts index dec07a5d4174f..7ee912cfc3303 100644 --- a/x-pack/plugins/observability/server/types/rest_specs/slo.ts +++ b/x-pack/plugins/observability/server/types/rest_specs/slo.ts @@ -8,17 +8,8 @@ import * as t from 'io-ts'; import { commonSLOSchema } from '../schema'; -const createSLOBodySchema = t.intersection([ - commonSLOSchema, - t.partial({ - settings: t.partial({ - destination_index: t.string, - }), - }), -]); - const createSLOParamsSchema = t.type({ - body: createSLOBodySchema, + body: commonSLOSchema, }); const createSLOResponseSchema = t.type({ @@ -31,8 +22,17 @@ const deleteSLOParamsSchema = t.type({ }), }); -type CreateSLOParams = t.TypeOf; +const getSLOParamsSchema = t.type({ + path: t.type({ + id: t.string, + }), +}); + +const getSLOResponseSchema = t.intersection([t.type({ id: t.string }), commonSLOSchema]); + +type CreateSLOParams = t.TypeOf; type CreateSLOResponse = t.TypeOf; +type GetSLOResponse = t.TypeOf; -export { createSLOParamsSchema, deleteSLOParamsSchema }; -export type { CreateSLOParams, CreateSLOResponse }; +export { createSLOParamsSchema, deleteSLOParamsSchema, getSLOParamsSchema }; +export type { CreateSLOParams, CreateSLOResponse, GetSLOResponse }; From 7f4608bf669ee860cdf969c685c640e416e98c5f Mon Sep 17 00:00:00 2001 From: Andrew Tate Date: Mon, 26 Sep 2022 08:04:37 -0500 Subject: [PATCH 09/51] [Lens] use min metric height from theme (#141683) * use min height from charts theme * update test mock Co-authored-by: Stratoula Kalafateli --- .../expression_metric/public/__mocks__/theme_service.ts | 1 + .../expression_metric/public/components/metric_vis.tsx | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/plugins/chart_expressions/expression_metric/public/__mocks__/theme_service.ts b/src/plugins/chart_expressions/expression_metric/public/__mocks__/theme_service.ts index 9690bd4a2d486..b00ec8a6ee569 100644 --- a/src/plugins/chart_expressions/expression_metric/public/__mocks__/theme_service.ts +++ b/src/plugins/chart_expressions/expression_metric/public/__mocks__/theme_service.ts @@ -9,5 +9,6 @@ export const getThemeService = () => { return { useChartsTheme: () => ({}), + useChartsBaseTheme: () => ({ metric: { minHeight: 64 } }), }; }; diff --git a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx b/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx index 539b41950a23c..f3e7a2864ec86 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx +++ b/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx @@ -311,15 +311,18 @@ export const MetricVis = ({ const scrollContainerRef = useRef(null); const scrollDimensions = useResizeObserver(scrollContainerRef.current); + const { + metric: { minHeight }, + } = getThemeService().useChartsBaseTheme(); + useEffect(() => { - const minTileHeight = 64; // TODO - magic number from the @elastic/charts side. would be nice to deduplicate - const minimumRequiredVerticalSpace = minTileHeight * grid.length; + const minimumRequiredVerticalSpace = minHeight * grid.length; setScrollChildHeight( (scrollDimensions.height ?? -Infinity) > minimumRequiredVerticalSpace ? '100%' : `${minimumRequiredVerticalSpace}px` ); - }, [grid.length, scrollDimensions.height]); + }, [grid.length, minHeight, scrollDimensions.height]); return (

Date: Mon, 26 Sep 2022 15:12:18 +0200 Subject: [PATCH 10/51] Move save button into connector config form (#141361) * move save button into connector config form --- .../translations/translations/fr-FR.json | 3 - .../translations/translations/ja-JP.json | 3 - .../translations/translations/zh-CN.json | 3 - .../create_connector_flyout/footer.tsx | 70 +---- .../create_connector_flyout/index.test.tsx | 204 ++++++------- .../create_connector_flyout/index.tsx | 69 ++++- .../edit_connector_flyout/footer.tsx | 75 +---- .../edit_connector_flyout/index.test.tsx | 234 +++++++++------ .../edit_connector_flyout/index.tsx | 284 +++++++++++------- .../components/actions_connectors_list.tsx | 2 +- .../apps/triggers_actions_ui/connectors.ts | 15 +- 11 files changed, 488 insertions(+), 474 deletions(-) diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 4b06b5ae9b13e..1066277da776f 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -32422,7 +32422,6 @@ "xpack.triggersActionsUI.ruleSnoozeScheduler.saveSchedule": "Enregistrer le calendrier", "xpack.triggersActionsUI.ruleSnoozeScheduler.timezoneLabel": "Fuseau horaire", "xpack.triggersActionsUI.sections.actionConnectorAdd.backButtonLabel": "Retour", - "xpack.triggersActionsUI.sections.actionConnectorAdd.cancelButtonLabel": "Annuler", "xpack.triggersActionsUI.sections.actionConnectorAdd.manageLicensePlanBannerLinkTitle": "Gérer la licence", "xpack.triggersActionsUI.sections.actionConnectorAdd.saveAndTestButtonLabel": "Enregistrer et tester", "xpack.triggersActionsUI.sections.actionConnectorAdd.saveButtonLabel": "Enregistrer", @@ -32528,11 +32527,9 @@ "xpack.triggersActionsUI.sections.connectorAddInline.unableToLoadConnectorTitle'": "Impossible de charger le connecteur", "xpack.triggersActionsUI.sections.connectorAddInline.unauthorizedToCreateForEmptyConnectors": "Seuls les utilisateurs autorisés peuvent configurer un connecteur. Contactez votre administrateur.", "xpack.triggersActionsUI.sections.deprecatedTitleMessage": "(déclassé)", - "xpack.triggersActionsUI.sections.editConnectorForm.cancelButtonLabel": "Annuler", "xpack.triggersActionsUI.sections.editConnectorForm.descriptionText": "Ce connecteur est en lecture seule.", "xpack.triggersActionsUI.sections.editConnectorForm.flyoutPreconfiguredTitle": "Modifier un connecteur", "xpack.triggersActionsUI.sections.editConnectorForm.preconfiguredHelpLabel": "En savoir plus sur les connecteurs préconfigurés.", - "xpack.triggersActionsUI.sections.editConnectorForm.saveAndCloseButtonLabel": "Enregistrer et fermer", "xpack.triggersActionsUI.sections.editConnectorForm.saveButtonLabel": "Enregistrer", "xpack.triggersActionsUI.sections.editConnectorForm.tabText": "Configuration", "xpack.triggersActionsUI.sections.editConnectorForm.updateErrorNotificationText": "Impossible de mettre à jour un connecteur.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 95f9d1a2494be..e077421392645 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -32396,7 +32396,6 @@ "xpack.triggersActionsUI.ruleSnoozeScheduler.saveSchedule": "スケジュールを保存", "xpack.triggersActionsUI.ruleSnoozeScheduler.timezoneLabel": "タイムゾーン", "xpack.triggersActionsUI.sections.actionConnectorAdd.backButtonLabel": "戻る", - "xpack.triggersActionsUI.sections.actionConnectorAdd.cancelButtonLabel": "キャンセル", "xpack.triggersActionsUI.sections.actionConnectorAdd.manageLicensePlanBannerLinkTitle": "ライセンスの管理", "xpack.triggersActionsUI.sections.actionConnectorAdd.saveAndTestButtonLabel": "保存してテスト", "xpack.triggersActionsUI.sections.actionConnectorAdd.saveButtonLabel": "保存", @@ -32502,11 +32501,9 @@ "xpack.triggersActionsUI.sections.connectorAddInline.unableToLoadConnectorTitle'": "コネクターを読み込めません", "xpack.triggersActionsUI.sections.connectorAddInline.unauthorizedToCreateForEmptyConnectors": "許可されたユーザーのみがコネクターを構成できます。管理者にお問い合わせください。", "xpack.triggersActionsUI.sections.deprecatedTitleMessage": "(非推奨)", - "xpack.triggersActionsUI.sections.editConnectorForm.cancelButtonLabel": "キャンセル", "xpack.triggersActionsUI.sections.editConnectorForm.descriptionText": "このコネクターは読み取り専用です。", "xpack.triggersActionsUI.sections.editConnectorForm.flyoutPreconfiguredTitle": "コネクターを編集", "xpack.triggersActionsUI.sections.editConnectorForm.preconfiguredHelpLabel": "あらかじめ構成されたコネクターの詳細をご覧ください。", - "xpack.triggersActionsUI.sections.editConnectorForm.saveAndCloseButtonLabel": "保存して閉じる", "xpack.triggersActionsUI.sections.editConnectorForm.saveButtonLabel": "保存", "xpack.triggersActionsUI.sections.editConnectorForm.tabText": "構成", "xpack.triggersActionsUI.sections.editConnectorForm.updateErrorNotificationText": "コネクターを更新できません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 3d8f0576aa13d..41c4320dae010 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -32430,7 +32430,6 @@ "xpack.triggersActionsUI.ruleSnoozeScheduler.saveSchedule": "保存计划", "xpack.triggersActionsUI.ruleSnoozeScheduler.timezoneLabel": "时区", "xpack.triggersActionsUI.sections.actionConnectorAdd.backButtonLabel": "返回", - "xpack.triggersActionsUI.sections.actionConnectorAdd.cancelButtonLabel": "取消", "xpack.triggersActionsUI.sections.actionConnectorAdd.manageLicensePlanBannerLinkTitle": "管理许可证", "xpack.triggersActionsUI.sections.actionConnectorAdd.saveAndTestButtonLabel": "保存并测试", "xpack.triggersActionsUI.sections.actionConnectorAdd.saveButtonLabel": "保存", @@ -32536,11 +32535,9 @@ "xpack.triggersActionsUI.sections.connectorAddInline.unableToLoadConnectorTitle'": "无法加载连接器", "xpack.triggersActionsUI.sections.connectorAddInline.unauthorizedToCreateForEmptyConnectors": "只有获得授权的用户才能配置连接器。请联系您的管理员。", "xpack.triggersActionsUI.sections.deprecatedTitleMessage": "(已过时)", - "xpack.triggersActionsUI.sections.editConnectorForm.cancelButtonLabel": "取消", "xpack.triggersActionsUI.sections.editConnectorForm.descriptionText": "此连接器为只读。", "xpack.triggersActionsUI.sections.editConnectorForm.flyoutPreconfiguredTitle": "编辑连接器", "xpack.triggersActionsUI.sections.editConnectorForm.preconfiguredHelpLabel": "详细了解预配置的连接器。", - "xpack.triggersActionsUI.sections.editConnectorForm.saveAndCloseButtonLabel": "保存并关闭", "xpack.triggersActionsUI.sections.editConnectorForm.saveButtonLabel": "保存", "xpack.triggersActionsUI.sections.editConnectorForm.tabText": "配置", "xpack.triggersActionsUI.sections.editConnectorForm.updateErrorNotificationText": "无法更新连接器。", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/footer.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/footer.tsx index 4c4ccfe965716..c73c6ed042810 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/footer.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/footer.tsx @@ -6,35 +6,16 @@ */ import React, { memo } from 'react'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiFlyoutFooter, - EuiButton, - EuiButtonEmpty, -} from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiFlexGroup, EuiFlexItem, EuiFlyoutFooter, EuiButtonEmpty } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; interface Props { - isSaving: boolean; - disabled: boolean; hasConnectorTypeSelected: boolean; - onSubmit: () => Promise; - onTestConnector?: () => void; onBack: () => void; onCancel: () => void; } -const FlyoutFooterComponent: React.FC = ({ - isSaving, - disabled, - hasConnectorTypeSelected, - onCancel, - onBack, - onTestConnector, - onSubmit, -}) => { +const FlyoutFooterComponent: React.FC = ({ hasConnectorTypeSelected, onCancel, onBack }) => { return ( @@ -49,57 +30,16 @@ const FlyoutFooterComponent: React.FC = ({ )} ) : ( - + {i18n.translate( - 'xpack.triggersActionsUI.sections.actionConnectorAdd.cancelButtonLabel', + 'xpack.triggersActionsUI.sections.actionConnectorAdd.closeButtonLabel', { - defaultMessage: 'Cancel', + defaultMessage: 'Close', } )} )} - {hasConnectorTypeSelected ? ( - - - <> - {onTestConnector && ( - - - - - - )} - - - - - - - - - ) : null} ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.test.tsx index f432f8fd6634c..a0ca1a501dc9c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.test.tsx @@ -102,6 +102,106 @@ describe('CreateConnectorFlyout', () => { expect(await getByTestId(`${actionTypeModel.id}-card`)).toBeInTheDocument(); }); + it('shows the correct buttons without an action type selected', async () => { + const { getByTestId, queryByTestId } = appMockRenderer.render( + + ); + await act(() => Promise.resolve()); + + expect(getByTestId('create-connector-flyout-close-btn')).toBeInTheDocument(); + expect(queryByTestId('create-connector-flyout-save-test-btn')).toBe(null); + expect(queryByTestId('create-connector-flyout-save-btn')).toBe(null); + }); + + it('shows the correct buttons when selecting an action type', async () => { + const { getByTestId } = appMockRenderer.render( + + ); + await act(() => Promise.resolve()); + + act(() => { + userEvent.click(getByTestId(`${actionTypeModel.id}-card`)); + }); + + await waitFor(() => { + expect(getByTestId('create-connector-flyout-back-btn')).toBeInTheDocument(); + expect(getByTestId('create-connector-flyout-save-test-btn')).toBeInTheDocument(); + expect(getByTestId('create-connector-flyout-save-btn')).toBeInTheDocument(); + }); + }); + + it('does not show the save and test button if the onTestConnector is not provided', async () => { + const { queryByTestId } = appMockRenderer.render( + + ); + await act(() => Promise.resolve()); + + expect(queryByTestId('create-connector-flyout-save-test-btn')).not.toBeInTheDocument(); + }); + + it('disables the buttons when the user does not have permissions to create a connector', async () => { + appMockRenderer.coreStart.application.capabilities = { + ...appMockRenderer.coreStart.application.capabilities, + actions: { save: false, show: true }, + }; + + const { getByTestId } = appMockRenderer.render( + + ); + await act(() => Promise.resolve()); + + expect(getByTestId('create-connector-flyout-close-btn')).not.toBeDisabled(); + }); + + it('disables the buttons when there are error on the form', async () => { + const { getByTestId } = appMockRenderer.render( + + ); + await act(() => Promise.resolve()); + + act(() => { + userEvent.click(getByTestId(`${actionTypeModel.id}-card`)); + }); + + await waitFor(() => { + expect(getByTestId('test-connector-text-field')).toBeInTheDocument(); + }); + + act(() => { + userEvent.click(getByTestId('create-connector-flyout-save-btn')); + }); + + await waitFor(() => { + expect(getByTestId('create-connector-flyout-back-btn')).not.toBeDisabled(); + expect(getByTestId('create-connector-flyout-save-test-btn')).toBeDisabled(); + expect(getByTestId('create-connector-flyout-save-btn')).toBeDisabled(); + }); + }); + describe('Licensing', () => { it('renders banner with subscription links when gold features are disabled due to licensing', async () => { const disabledActionType = actionTypeRegistryMock.createMockActionTypeModel(); @@ -509,44 +609,6 @@ describe('CreateConnectorFlyout', () => { }); describe('Footer', () => { - it('shows the correct buttons without an action type selected', async () => { - const { getByTestId, queryByTestId } = appMockRenderer.render( - - ); - await act(() => Promise.resolve()); - - expect(getByTestId('create-connector-flyout-cancel-btn')).toBeInTheDocument(); - expect(queryByTestId('create-connector-flyout-save-test-btn')).toBe(null); - expect(queryByTestId('create-connector-flyout-save-btn')).toBe(null); - }); - - it('shows the correct buttons when selecting an action type', async () => { - const { getByTestId } = appMockRenderer.render( - - ); - await act(() => Promise.resolve()); - - act(() => { - userEvent.click(getByTestId(`${actionTypeModel.id}-card`)); - }); - - await waitFor(() => { - expect(getByTestId('create-connector-flyout-back-btn')).toBeInTheDocument(); - expect(getByTestId('create-connector-flyout-save-test-btn')).toBeInTheDocument(); - expect(getByTestId('create-connector-flyout-save-btn')).toBeInTheDocument(); - }); - }); - it('shows the action types when pressing the back button', async () => { const { getByTestId } = appMockRenderer.render( { expect(getByTestId(`${actionTypeModel.id}-card`)).toBeInTheDocument(); }); - it('does not show the save and test button if the onTestConnector is not provided', async () => { - const { queryByTestId } = appMockRenderer.render( - - ); - await act(() => Promise.resolve()); - - expect(queryByTestId('create-connector-flyout-save-test-btn')).not.toBeInTheDocument(); - }); - - it('closes the flyout when pressing cancel', async () => { + it('closes the flyout when pressing close', async () => { const { getByTestId } = appMockRenderer.render( { await act(() => Promise.resolve()); act(() => { - userEvent.click(getByTestId('create-connector-flyout-cancel-btn')); + userEvent.click(getByTestId('create-connector-flyout-close-btn')); }); expect(onClose).toHaveBeenCalled(); }); - - it('disables the buttons when the user does not have permissions to create a connector', async () => { - appMockRenderer.coreStart.application.capabilities = { - ...appMockRenderer.coreStart.application.capabilities, - actions: { save: false, show: true }, - }; - - const { getByTestId } = appMockRenderer.render( - - ); - await act(() => Promise.resolve()); - - expect(getByTestId('create-connector-flyout-cancel-btn')).not.toBeDisabled(); - }); - - it('disables the buttons when there are error on the form', async () => { - const { getByTestId } = appMockRenderer.render( - - ); - await act(() => Promise.resolve()); - - act(() => { - userEvent.click(getByTestId(`${actionTypeModel.id}-card`)); - }); - - await waitFor(() => { - expect(getByTestId('test-connector-text-field')).toBeInTheDocument(); - }); - - act(() => { - userEvent.click(getByTestId('create-connector-flyout-save-btn')); - }); - - await waitFor(() => { - expect(getByTestId('create-connector-flyout-back-btn')).not.toBeDisabled(); - expect(getByTestId('create-connector-flyout-save-test-btn')).toBeDisabled(); - expect(getByTestId('create-connector-flyout-save-btn')).toBeDisabled(); - }); - }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.tsx index f25d86458632a..32bd7931aecc8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/create_connector_flyout/index.tsx @@ -6,9 +6,10 @@ */ import React, { memo, ReactNode, useCallback, useEffect, useRef, useState } from 'react'; -import { EuiFlyout, EuiFlyoutBody } from '@elastic/eui'; +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiFlyout, EuiFlyoutBody } from '@elastic/eui'; import { getConnectorCompatibility } from '@kbn/actions-plugin/common'; +import { FormattedMessage } from '@kbn/i18n-react'; import { ActionConnector, ActionType, @@ -163,15 +164,7 @@ const CreateConnectorFlyoutComponent: React.FC = ({ : null} > - {actionType == null ? ( - - ) : null} - {actionType != null ? ( + {hasConnectorTypeSelected ? ( <> = ({ isEdit={false} onChange={setFormState} /> - {preSubmitValidationErrorMessage} + {!!preSubmitValidationErrorMessage &&

{preSubmitValidationErrorMessage}

} + + + + <> + {onTestConnector && ( + + + + + + )} + + + + + + + + + - ) : null} + ) : ( + + )}
); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/footer.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/footer.tsx index 5f19449df2bb5..75d5e8aba4000 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/footer.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/footer.tsx @@ -6,84 +6,25 @@ */ import React, { memo } from 'react'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiFlyoutFooter, - EuiButton, - EuiButtonEmpty, -} from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiFlexGroup, EuiFlexItem, EuiFlyoutFooter, EuiButtonEmpty } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; interface Props { - isSaving: boolean; - showButtons: boolean; - disabled: boolean; - onCancel: () => void; - onSubmit: () => void; - onSubmitAndClose: () => void; + onClose: () => void; } -const FlyoutFooterComponent: React.FC = ({ - isSaving, - showButtons, - disabled, - onCancel, - onSubmit, - onSubmitAndClose, -}) => { +const FlyoutFooterComponent: React.FC = ({ onClose }) => { return ( - - {i18n.translate( - 'xpack.triggersActionsUI.sections.editConnectorForm.cancelButtonLabel', - { - defaultMessage: 'Cancel', - } - )} + + {i18n.translate('xpack.triggersActionsUI.sections.editConnectorForm.closeButtonLabel', { + defaultMessage: 'Close', + })} - - - {showButtons ? ( - <> - - - - - - - - - - - - ) : null} - - + ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.test.tsx index 8a828fcfc9539..23793d3c5766b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.test.tsx @@ -88,6 +88,52 @@ describe('EditConnectorFlyout', () => { expect(getByTestId('edit-connector-flyout-footer')).toBeInTheDocument(); }); + it('enables save button when the form is modified', async () => { + const { getByTestId } = appMockRenderer.render( + + ); + expect(getByTestId('edit-connector-flyout-save-btn')).toBeDisabled(); + + await act(async () => { + await userEvent.clear(getByTestId('nameInput')); + await userEvent.type(getByTestId('nameInput'), 'My new name', { + delay: 10, + }); + }); + + expect(getByTestId('edit-connector-flyout-save-btn')).not.toBeDisabled(); + }); + + it('shows a confirmation modal on close if the form is modified', async () => { + const { getByTestId, getByText } = appMockRenderer.render( + + ); + expect(getByTestId('edit-connector-flyout-save-btn')).toBeDisabled(); + + await act(async () => { + await userEvent.clear(getByTestId('nameInput')); + await userEvent.type(getByTestId('nameInput'), 'My new name', { + delay: 10, + }); + }); + + act(() => { + userEvent.click(getByTestId('edit-connector-flyout-close-btn')); + }); + + expect(getByText('Discard unsaved changes to connector?')).toBeInTheDocument(); + }); + it('renders the connector form correctly', async () => { const { getByTestId, queryByText } = appMockRenderer.render( { expect(getByText('This connector is readonly.')).toBeInTheDocument(); }); + it('shows the buttons', async () => { + const { getByTestId } = appMockRenderer.render( + + ); + + expect(getByTestId('edit-connector-flyout-save-btn')).toBeInTheDocument(); + expect(getByTestId('edit-connector-flyout-close-btn')).toBeInTheDocument(); + }); + + it('does not show the save button if the use does not have permissions to update connector', async () => { + appMockRenderer.coreStart.application.capabilities = { + ...appMockRenderer.coreStart.application.capabilities, + actions: { save: false, show: true }, + }; + + const { queryByTestId } = appMockRenderer.render( + + ); + + expect(queryByTestId('edit-connector-flyout-save-btn')).not.toBeInTheDocument(); + }); + + it('does not show the save button if the connector is preconfigured', async () => { + const { queryByTestId } = appMockRenderer.render( + + ); + + expect(queryByTestId('edit-connector-flyout-save-btn')).not.toBeInTheDocument(); + }); + + it('disables the buttons when there are error on the form', async () => { + const { getByTestId } = appMockRenderer.render( + + ); + + await waitFor(() => { + expect(getByTestId('test-connector-text-field')).toBeInTheDocument(); + }); + + act(() => { + /** + * Clear the name so the form can be invalid + */ + userEvent.clear(getByTestId('nameInput')); + }); + act(() => { + userEvent.click(getByTestId('edit-connector-flyout-save-btn')); + }); + + await waitFor(() => { + expect(getByTestId('edit-connector-flyout-close-btn')).not.toBeDisabled(); + expect(getByTestId('edit-connector-flyout-save-btn')).toBeDisabled(); + }); + }); + describe('Header', () => { it('shows the icon', async () => { const { getByTestId } = appMockRenderer.render( @@ -327,7 +448,7 @@ describe('EditConnectorFlyout', () => { }); it('updates the connector and close the flyout correctly', async () => { - const { getByTestId } = appMockRenderer.render( + const { getByTestId, getByText } = appMockRenderer.render( { }); act(() => { - userEvent.click(getByTestId('edit-connector-flyout-save-close-btn')); + userEvent.click(getByTestId('edit-connector-flyout-save-btn')); }); await waitFor(() => { @@ -363,6 +484,12 @@ describe('EditConnectorFlyout', () => { ); }); + expect(getByText('Changes Saved')).toBeInTheDocument(); + + act(() => { + userEvent.click(getByTestId('edit-connector-flyout-close-btn')); + }); + expect(onClose).toHaveBeenCalled(); expect(onConnectorUpdated).toHaveBeenCalledWith({ actionTypeId: 'test', @@ -395,6 +522,13 @@ describe('EditConnectorFlyout', () => { expect(getByTestId('test-connector-error-text-field')).toBeInTheDocument(); }); + await act(async () => { + await userEvent.clear(getByTestId('nameInput')); + await userEvent.type(getByTestId('nameInput'), 'My new name', { + delay: 100, + }); + }); + act(() => { userEvent.click(getByTestId('edit-connector-flyout-save-btn')); }); @@ -559,100 +693,4 @@ describe('EditConnectorFlyout', () => { expect(getByTestId('executeActionButton')).toBeDisabled(); }); }); - - describe('Footer', () => { - it('shows the buttons', async () => { - const { getByTestId } = appMockRenderer.render( - - ); - - expect(getByTestId('edit-connector-flyout-cancel-btn')).toBeInTheDocument(); - expect(getByTestId('edit-connector-flyout-save-btn')).toBeInTheDocument(); - expect(getByTestId('edit-connector-flyout-save-close-btn')).toBeInTheDocument(); - }); - - it('does not show the save and save and close button if the use does not have permissions to update connector', async () => { - appMockRenderer.coreStart.application.capabilities = { - ...appMockRenderer.coreStart.application.capabilities, - actions: { save: false, show: true }, - }; - - const { queryByTestId } = appMockRenderer.render( - - ); - - expect(queryByTestId('edit-connector-flyout-save-btn')).not.toBeInTheDocument(); - expect(queryByTestId('edit-connector-flyout-save-close-btn')).not.toBeInTheDocument(); - }); - - it('does not show the save and save and close button if the connector is preconfigured', async () => { - const { queryByTestId } = appMockRenderer.render( - - ); - - expect(queryByTestId('edit-connector-flyout-save-btn')).not.toBeInTheDocument(); - expect(queryByTestId('edit-connector-flyout-save-close-btn')).not.toBeInTheDocument(); - }); - - it('closes the flyout when pressing cancel', async () => { - const { getByTestId } = appMockRenderer.render( - - ); - - act(() => { - userEvent.click(getByTestId('edit-connector-flyout-cancel-btn')); - }); - - expect(onClose).toHaveBeenCalled(); - }); - - it('disables the buttons when there are error on the form', async () => { - const { getByTestId } = appMockRenderer.render( - - ); - - await waitFor(() => { - expect(getByTestId('test-connector-text-field')).toBeInTheDocument(); - }); - - act(() => { - /** - * Clear the name so the form can be invalid - */ - userEvent.clear(getByTestId('nameInput')); - userEvent.click(getByTestId('edit-connector-flyout-save-btn')); - }); - - await waitFor(() => { - expect(getByTestId('edit-connector-flyout-cancel-btn')).not.toBeDisabled(); - expect(getByTestId('edit-connector-flyout-save-close-btn')).toBeDisabled(); - expect(getByTestId('edit-connector-flyout-save-btn')).toBeDisabled(); - }); - }); - }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx index 452a89d04f9c1..e00349cecd62b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx @@ -6,7 +6,14 @@ */ import React, { memo, ReactNode, useCallback, useEffect, useRef, useState } from 'react'; -import { EuiFlyout, EuiText, EuiFlyoutBody, EuiLink } from '@elastic/eui'; +import { + EuiFlyout, + EuiText, + EuiFlyoutBody, + EuiLink, + EuiButton, + EuiConfirmModal, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { ActionTypeExecutorResult, isActionTypeExecutorResult } from '@kbn/actions-plugin/common'; @@ -73,6 +80,7 @@ const EditConnectorFlyoutComponent: React.FC = ({ docLinks, application: { capabilities }, } = useKibana().services; + const isMounted = useRef(false); const canSave = hasSaveActionsCapability(capabilities); const { isLoading: isUpdatingConnector, updateConnector } = useUpdateConnector(); @@ -117,7 +125,9 @@ const EditConnectorFlyoutComponent: React.FC = ({ ); const [isFormModified, setIsFormModified] = useState(false); - + const [showConfirmModal, setShowConfirmModal] = useState(false); + const [isEdit, setIsEdit] = useState(true); + const [isSaved, setIsSaved] = useState(false); const { preSubmitValidator, submit, isValid: isFormValid, isSubmitting } = formState; const hasErrors = isFormValid === false; const isSaving = isUpdatingConnector || isSubmitting || isExecutingConnector; @@ -146,6 +156,9 @@ const EditConnectorFlyoutComponent: React.FC = ({ const onFormModifiedChange = useCallback( (formModified: boolean) => { + if (formModified) { + setIsSaved(false); + } setIsFormModified(formModified); setTestExecutionResult(none); }, @@ -153,76 +166,72 @@ const EditConnectorFlyoutComponent: React.FC = ({ ); const closeFlyout = useCallback(() => { + if (isFormModified) { + setShowConfirmModal(true); + return; + } onClose(); - }, [onClose]); + }, [onClose, isFormModified, setShowConfirmModal]); - const onClickSave = useCallback( - async (closeAfterSave: boolean = true) => { - setPreSubmitValidationErrorMessage(null); + const onClickSave = useCallback(async () => { + setPreSubmitValidationErrorMessage(null); - const { isValid, data } = await submit(); - if (!isMounted.current) { - // User has closed the flyout meanwhile submitting the form - return; - } + const { isValid, data } = await submit(); + if (!isMounted.current) { + // User has closed the flyout meanwhile submitting the form + return; + } - if (isValid) { - if (preSubmitValidator) { - const validatorRes = await preSubmitValidator(); + if (isValid) { + if (preSubmitValidator) { + const validatorRes = await preSubmitValidator(); - if (validatorRes) { - setPreSubmitValidationErrorMessage(validatorRes.message); - return; - } + if (validatorRes) { + setPreSubmitValidationErrorMessage(validatorRes.message); + return; } + } + + /** + * At this point the form is valid + * and there are no pre submit error messages. + */ + const { name, config, secrets } = data; + const validConnector = { + id: connector.id, + name: name ?? '', + config: config ?? {}, + secrets: secrets ?? {}, + }; + + const updatedConnector = await updateConnector(validConnector); + + if (updatedConnector) { /** - * At this point the form is valid - * and there are no pre submit error messages. + * ConnectorFormSchema has been saved. + * Set the from to clean state. */ + onFormModifiedChange(false); - const { name, config, secrets } = data; - const validConnector = { - id: connector.id, - name: name ?? '', - config: config ?? {}, - secrets: secrets ?? {}, - }; - - const updatedConnector = await updateConnector(validConnector); - - if (updatedConnector) { - /** - * ConnectorFormSchema has been saved. - * Set the from to clean state. - */ - onFormModifiedChange(false); - - if (onConnectorUpdated && updatedConnector) { - onConnectorUpdated(updatedConnector); - } - - if (closeAfterSave) { - closeFlyout(); - } + if (onConnectorUpdated) { + onConnectorUpdated(updatedConnector); } - - return updatedConnector; + setIsSaved(true); + setIsEdit(false); + setIsEdit(true); } - }, - [ - submit, - preSubmitValidator, - connector.id, - updateConnector, - onFormModifiedChange, - onConnectorUpdated, - closeFlyout, - ] - ); - const onSubmit = useCallback(() => onClickSave(false), [onClickSave]); - const onSubmitAndClose = useCallback(() => onClickSave(true), [onClickSave]); + return updatedConnector; + } + }, [ + onConnectorUpdated, + submit, + preSubmitValidator, + connector.id, + updateConnector, + onFormModifiedChange, + ]); useEffect(() => { isMounted.current = true; @@ -233,59 +242,114 @@ const EditConnectorFlyoutComponent: React.FC = ({ }, []); return ( - - - - {selectedTab === EditConnectorTabs.Configuration ? ( - !connector.isPreconfigured ? ( - <> - - {preSubmitValidationErrorMessage} - + <> + + + + {selectedTab === EditConnectorTabs.Configuration ? ( + !connector.isPreconfigured ? ( + <> + {isEdit && ( + <> + + {!!preSubmitValidationErrorMessage &&

{preSubmitValidationErrorMessage}

} + {showButtons && ( + + {isSaved ? ( + + ) : ( + + )} + + )} + + )} + + ) : ( + + ) ) : ( - - ) - ) : ( - + )} +
+ +
+ {showConfirmModal && ( + { + setShowConfirmModal(false); + }} + onConfirm={onClose} + cancelButtonText={i18n.translate( + 'xpack.triggersActionsUI.sections.confirmConnectorEditClose.cancelButtonLabel', + { + defaultMessage: 'Cancel', + } + )} + confirmButtonText={i18n.translate( + 'xpack.triggersActionsUI.sections.confirmConnectorEditClose.discardButtonLabel', + { + defaultMessage: 'Discard Changes', + } + )} + > + - )} -
- -
+ + )} + ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx index 249f9f503fcf8..e973fce282dcb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx @@ -525,7 +525,7 @@ const ActionsConnectorsList: React.FunctionComponent = () => { setEditConnectorProps(omit(editConnectorProps, 'initialConnector')); }} onConnectorUpdated={(connector) => { - setEditConnectorProps({ initialConnector: connector }); + setEditConnectorProps({ ...editConnectorProps, initialConnector: connector }); loadActions(); }} actionTypeRegistry={actionTypeRegistry} diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts index 0abb9bd7a395e..cabbadb43ac57 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts @@ -88,12 +88,14 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await testSubjects.setValue('slackWebhookUrlInput', 'https://test.com'); await find.clickByCssSelector( - '[data-test-subj="edit-connector-flyout-save-close-btn"]:not(disabled)' + '[data-test-subj="edit-connector-flyout-save-btn"]:not(disabled)' ); const toastTitle = await pageObjects.common.closeToast(); expect(toastTitle).to.eql(`Updated '${updatedConnectorName}'`); + await testSubjects.click('euiFlyoutCloseButton'); + await pageObjects.triggersActionsUI.searchConnectors(updatedConnectorName); const searchResultsAfterEdit = await pageObjects.triggersActionsUI.getConnectorsList(); @@ -130,7 +132,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); await find.clickByCssSelector( - '[data-test-subj="edit-connector-flyout-cancel-btn"]:not(disabled)' + '[data-test-subj="edit-connector-flyout-close-btn"]:not(disabled)' ); }); @@ -158,7 +160,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); await find.clickByCssSelector( - '[data-test-subj="edit-connector-flyout-cancel-btn"]:not(disabled)' + '[data-test-subj="edit-connector-flyout-close-btn"]:not(disabled)' ); }); @@ -174,9 +176,10 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await find.clickByCssSelector('[data-test-subj="connectorsTableCell-name"] button'); await testSubjects.setValue('nameInput', 'some test name to cancel'); - await testSubjects.click('edit-connector-flyout-cancel-btn'); + await testSubjects.click('edit-connector-flyout-close-btn'); + await testSubjects.click('confirmModalConfirmButton'); - await find.waitForDeletedByCssSelector('[data-test-subj="edit-connector-flyout-cancel-btn"]'); + await find.waitForDeletedByCssSelector('[data-test-subj="edit-connector-flyout-close-btn"]'); await pageObjects.triggersActionsUI.searchConnectors(connectorName); @@ -265,7 +268,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await find.clickByCssSelector('[data-test-subj="connectorsTableCell-name"] button'); expect(await testSubjects.exists('preconfiguredBadge')).to.be(true); - expect(await testSubjects.exists('edit-connector-flyout-save-close-btn')).to.be(false); + expect(await testSubjects.exists('edit-connector-flyout-save-btn')).to.be(false); }); }); From 85c8d379253e4f3b60bad0f70286f4243e4d5b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Mon, 26 Sep 2022 15:22:35 +0200 Subject: [PATCH 11/51] [Guided onboarding] Updated the examples to only use the Observable for the active step check (#141265) --- .../public/components/step_one.tsx | 5 ++-- .../public/components/step_two.tsx | 26 +++++++++---------- .../public/constants/search.ts | 2 +- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/examples/guided_onboarding_example/public/components/step_one.tsx b/examples/guided_onboarding_example/public/components/step_one.tsx index bacb43ad0f67a..3441b4d8e5d99 100644 --- a/examples/guided_onboarding_example/public/components/step_one.tsx +++ b/examples/guided_onboarding_example/public/components/step_one.tsx @@ -55,9 +55,8 @@ export const StepOne = ({ guidedOnboarding }: GuidedOnboardingExampleAppDeps) =>

diff --git a/examples/guided_onboarding_example/public/components/step_two.tsx b/examples/guided_onboarding_example/public/components/step_two.tsx index 9f96532450bfc..a79ce2329351e 100644 --- a/examples/guided_onboarding_example/public/components/step_two.tsx +++ b/examples/guided_onboarding_example/public/components/step_two.tsx @@ -11,7 +11,6 @@ import React, { useEffect, useState } from 'react'; import { EuiButton, EuiSpacer, EuiText, EuiTitle, EuiTourStep } from '@elastic/eui'; import { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public/types'; -import { useHistory, useLocation } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiPageContentHeader_Deprecated as EuiPageContentHeader, @@ -26,18 +25,18 @@ export const StepTwo = (props: StepTwoProps) => { const { guidedOnboarding: { guidedOnboardingApi }, } = props; - const { search } = useLocation(); - const history = useHistory(); - - const query = React.useMemo(() => new URLSearchParams(search), [search]); - useEffect(() => { - if (query.get('showTour') === 'true') { - setIsTourStepOpen(true); - } - }, [query]); const [isTourStepOpen, setIsTourStepOpen] = useState(false); + useEffect(() => { + const subscription = guidedOnboardingApi + ?.isGuideStepActive$('search', 'browse_docs') + .subscribe((isStepActive) => { + setIsTourStepOpen(isStepActive); + }); + return () => subscription?.unsubscribe(); + }, [guidedOnboardingApi]); + return ( <> @@ -55,7 +54,8 @@ export const StepTwo = (props: StepTwoProps) => {

@@ -69,13 +69,11 @@ export const StepTwo = (props: StepTwoProps) => { isStepOpen={isTourStepOpen} minWidth={300} onFinish={() => { - history.push('/stepTwo'); - query.set('showTour', 'false'); setIsTourStepOpen(false); }} step={1} stepsTotal={1} - title="Step Add data" + title="Step Search experience" anchorPosition="rightUp" > Date: Mon, 26 Sep 2022 09:11:58 -0500 Subject: [PATCH 12/51] [TIP] Remove feature flag for Threat Intelligence plugin (#141117) --- .../security_solution/common/experimental_features.ts | 1 - .../navigation/use_security_solution_navigation/index.tsx | 3 --- .../security_solution/public/threat_intelligence/links.ts | 1 - .../public/threat_intelligence/routes.tsx | 7 ------- x-pack/test/security_solution_cypress/config.ts | 4 +--- x-pack/test/threat_intelligence_cypress/config.ts | 4 +--- 6 files changed, 2 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index db74802dcb599..fe65aab259395 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -20,7 +20,6 @@ export const allowedExperimentalValues = Object.freeze({ pendingActionResponsesWithAck: true, policyListEnabled: true, policyResponseInFleetEnabled: true, - threatIntelligenceEnabled: false, /** * This is used for enabling the end-to-end tests for the security_solution telemetry. diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx index 3a010bdb4fd7a..0444b183e9425 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx @@ -31,9 +31,6 @@ export const useSecuritySolutionNavigation = () => { const disabledNavTabs = [ ...(!useIsExperimentalFeatureEnabled('kubernetesEnabled') ? ['kubernetes'] : []), - ...(!useIsExperimentalFeatureEnabled('threatIntelligenceEnabled') - ? ['threat-intelligence'] - : []), ]; const enabledNavTabs: GenericNavRecord = omit(disabledNavTabs, navTabs); diff --git a/x-pack/plugins/security_solution/public/threat_intelligence/links.ts b/x-pack/plugins/security_solution/public/threat_intelligence/links.ts index 5b59c0a50799f..c443b74690411 100644 --- a/x-pack/plugins/security_solution/public/threat_intelligence/links.ts +++ b/x-pack/plugins/security_solution/public/threat_intelligence/links.ts @@ -17,7 +17,6 @@ import type { LinkItem } from '../common/links'; */ export const indicatorsLinks: LinkItem = { ...getSecuritySolutionLink('indicators'), - experimentalKey: 'threatIntelligenceEnabled', globalNavPosition: 7, capabilities: [`${SERVER_APP_ID}.show`], }; diff --git a/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx b/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx index ab197f60236c6..774d5ea06a350 100644 --- a/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx +++ b/x-pack/plugins/security_solution/public/threat_intelligence/routes.tsx @@ -6,7 +6,6 @@ */ import React, { memo } from 'react'; -import { Redirect } from 'react-router-dom'; import { TrackApplicationView } from '@kbn/usage-collection-plugin/public'; import type { SecuritySolutionPluginContext } from '@kbn/threat-intelligence-plugin/public'; import { THREAT_INTELLIGENCE_BASE_PATH } from '@kbn/threat-intelligence-plugin/public'; @@ -17,7 +16,6 @@ import { getStore } from '../common/store'; import { useKibana } from '../common/lib/kibana'; import { FiltersGlobal } from '../common/components/filters_global'; import { SpyRoute } from '../common/utils/route/spy_routes'; -import { useIsExperimentalFeatureEnabled } from '../common/hooks/use_experimental_features'; import { licenseService } from '../common/hooks/use_license'; import { SecurityPageName } from '../app/types'; import type { SecuritySubPluginRoutes } from '../app/types'; @@ -30,11 +28,6 @@ const ThreatIntelligence = memo(() => { const sourcererDataView = useSourcererDataView(); - const enabled = useIsExperimentalFeatureEnabled('threatIntelligenceEnabled'); - if (!enabled) { - return ; - } - const securitySolutionStore = getStore() as Store; const securitySolutionContext: SecuritySolutionPluginContext = { diff --git a/x-pack/test/security_solution_cypress/config.ts b/x-pack/test/security_solution_cypress/config.ts index 982d52920e2ac..e77ab1fe4d489 100644 --- a/x-pack/test/security_solution_cypress/config.ts +++ b/x-pack/test/security_solution_cypress/config.ts @@ -49,9 +49,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { // See https://github.com/elastic/kibana/pull/125396 for details '--xpack.alerting.rules.minimumScheduleInterval.value=1s', '--xpack.ruleRegistry.unsafe.legacyMultiTenancy.enabled=true', - `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'threatIntelligenceEnabled', - ])}`, + `--xpack.securitySolution.enableExperimental=${JSON.stringify([])}`, `--home.disableWelcomeScreen=true`, ], }, diff --git a/x-pack/test/threat_intelligence_cypress/config.ts b/x-pack/test/threat_intelligence_cypress/config.ts index 8d638789b61ff..3fc305ab35f74 100644 --- a/x-pack/test/threat_intelligence_cypress/config.ts +++ b/x-pack/test/threat_intelligence_cypress/config.ts @@ -48,9 +48,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { // See https://github.com/elastic/kibana/pull/125396 for details '--xpack.alerting.rules.minimumScheduleInterval.value=1s', '--xpack.ruleRegistry.unsafe.legacyMultiTenancy.enabled=true', - `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'threatIntelligenceEnabled', - ])}`, + `--xpack.securitySolution.enableExperimental=${JSON.stringify([])}`, `--home.disableWelcomeScreen=true`, ], }, From c1dc8671bbc70377e52d062918d793c441d51a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20Zolt=C3=A1n=20Szab=C3=B3?= Date: Mon, 26 Sep 2022 16:33:09 +0200 Subject: [PATCH 13/51] [DOCS] Expands documentation on Explain log rate spikes (#141370) --- docs/user/ml/images/classification.png | Bin 0 -> 82234 bytes .../ml/images/ml-explain-log-rate-before.png | Bin 93841 -> 217826 bytes docs/user/ml/images/ml-explain-log-rate.png | Bin 129559 -> 144957 bytes docs/user/ml/images/outliers.png | Bin 178520 -> 0 bytes docs/user/ml/index.asciidoc | 25 +++++++++--------- 5 files changed, 12 insertions(+), 13 deletions(-) create mode 100644 docs/user/ml/images/classification.png delete mode 100644 docs/user/ml/images/outliers.png diff --git a/docs/user/ml/images/classification.png b/docs/user/ml/images/classification.png new file mode 100644 index 0000000000000000000000000000000000000000..492c44bfa5ce89a39a067ff00f4b126e61670bc1 GIT binary patch literal 82234 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 literal 0 HcmV?d00001 diff --git a/docs/user/ml/images/ml-explain-log-rate-before.png b/docs/user/ml/images/ml-explain-log-rate-before.png index e154ddbeebebfd3059b31df84ee087ae9d40b537..2fcfae89515672a61277191ac279e2ac89902a4c 100644 GIT binary patch literal 217826 zcmeFZXIN8B+cqkQNK+6H1f_`ds-a2fNbem&RUq_UrHdd)@4ZUzy?3P(YUmxMNtZw< zq3z{U-p6|%?{j~D_OE?>IgTVNYt77>HFM3(HRpL=3078=dVoWYbLY;T2Qt#)s(0>S zRo=OCFBc0PIHPQFZ3=v$IjKsC-6@D@UQ z`aj2#XpDF6{^LAQPLRbNjDMw31ipX2qJa1BJpcSg&qDuq3arYkyZ=7Em-{=ZdFZcj z;0xPc8sc>44hh}wH=2wp?XNp`(D5wPwVkyUT&CQM7jg#HZ(Tw92A0HpbOArSL#0I2bb8@$Je)pcu z*6GDR3;B0B;!r1JM+SSl_^1D_VwieDpAc23}1K6#{`kTml^b>!trSE95^}UvY8$CF>uT{*_gL<9B=g z(SHBzoPV4JdPfLHfa8C9S_r4xBMLAzkvlTtqU!I__LlCwC6-#~bin#5W*?OONi~<) zEl727NlwlI=tAIS!=#+0EGrkCKyweLheAvY3n8?9#130tI@okfTyOMkzeF930IwU@ zGs4Zeb{1?0Ar&0I}6HS>5Ov7@Z9Hf`kT)DMSzAbM(Oy4 zPvP$p=>duUZ%O~Ro&K*C{QrEk*x~ajDH8pA#yeNOhmP*QPW0p)^z!EhENe!z!l2FP zTGB^o@_3__;PVIcWtG-!@uLuuDSn+v##h-A;bdL>k|%|aDl^ov|6R)O#asYF4GO=P z;dR01_OE%y-q5d;lp|9B_v9G=1pob4L+1leilU1k=G9#y!33p~S)uXIc;1DHNylRU znG!qqF|e?jmgsW6{c90e-9|?nH55SLdLg)|e{Qf;{X&F1V=;BkOd26(B1{mgqVbir1IgJi$U}fT##+*)AVg;oD_WSeM6+)btz|C_9qwb^d?T9V0 z^hf8F_cG4!33wr{wrjQ=QwT{yNc$Lk(vno#F65A1?R#kye>ggibUu7g4rmupAIaz( zPHoU>u<_kXT;U?C_Dyh^4lA;l$RE$G2?4wiuRG|XqN3L*e4S>m_)R@R2HBSuKN@4` zLagAB>t7hT(2K8YcjPV|7iV7)^+on5t5Yp&Y=#NF^xN_ib)ypUyy6lWk)vtEUh6#x zf4p{=UrO=*pMAS1LH!Xk;OhEXpX~{s<9gC7_w-Y?nv;6>8-eqE2~XiyM%}*i=CaFS`{DfqgP)L(aFaB9M4%;6sG~|U5M@< zgqJDk=GRuk-+0>+DXeJMrjeh3jfG|Vx%Q0cOZ)eIjTq-g@6XTYmV$0LJ{m|yZl()3 zJWI~NAi*H8Cq+x%-Q8Sb039YeKbCzWtog06YB6tf@_+36w`B^^`eBh1$VTrNYq4CS zP-((e{MoBJZ=^aA4K@o$HoK?b$Elo7mU*&|ok0N``5P>nE{AhkTc5o>-Ru_f;}tO* zX4MPr2UxT!=1VN+CyRW+t)t7D@JAx6T||xcM@C06hC69m13x4ZIdo0Z-z}cY5Ya2t zDQc(e5FY(D16<6ECh|gBHQ+cCRX(QewqBpd7sXsvr{~*wVV3qsP zcHal#Y*kfbF68B@y+$u5kWQr^&NLg{j!WZ`Axtl`7F+cvZuGhC&F+zN zQDoDtXVoZCpC0JU$726AF2(e~>Inzsi(oRECJ1JSnco=|N*9Gm_qp$mnyu?aAv-$H zy>*BWl0L?nu=(~EgzJ#8%DAU8Ib8fd%?liLZUc^Inxd>9J86IN@i9fq>Cb2R_TR<8 zx^n@Y_nGX^mfN;Dw|=JSEX{LcV{M;{Un$I0n~qnQoQ_uaMo{PqPV z{lU{oxim(>p-!2aWe}e>%U`Hk{6xd8JH_0caIRDZe14yH^>4k(9%! z?*5BM2o*DolY8q;2?dwH#DbrR@pH?B<ll_%ZLM3M^h@Y-XF~nPL;}JESbu^H`OMW49c^%r5RVaca_=k{=|^e0dbrE z)M26~3vko3Uc7a0rV=_j!+-xJHeBJa&s77=MfLMaqF5)( zA^Q!64@o&Rx#UZ}eFZGtuaZzY>E+jqC0)<6y#yg|osFcPP?F_(cm1G;Hu1zHLU?|C zN|~_Fst(3|C&=KNcWIBz{O+KWqq#S4kR^V7PIW0bV{P>Kk5L0m4xjEgVKs@xgSy11 zRk8z&B_pFo*ZLw2JA5dFeXc5BGxz--X5TcZEhh{27wQs}L_|7c3zTAM6@tLshP4B`-7`ba)}%aGBLDD2YP%$qwKfC32Y@Uemi#+GC{8t(_W_tOyrNE zE)oq{gS|bG=O+{L2^$iji3dv!h6#D}IZ_YgQn-rf^e+x4EjS}7gl!@FGX+}tO3SWI zoC4W- zKT`>!!I4xH4DK+!_}&#n0d||99kd)IW^&xP5|D~`Mpd9hN;l{^G4<^FV)i7thPwsp zZT0#9yg-g+D~ZF7a#*tm5?gLyGn21zY1$&S(qf~-QdWZcBfvQ9i$#WRebRJjKS@yg z72Lr2e`)}Zf!?IZ73^rO&*x%z2;1y-Prq|>?8^(So6t``_ZaOg%+bZPD)cYwp$lpS zx5}r8;}*wlcs#ciue59hr9NF}QLt4pJ~8o$>YNJX^>H7S=h;C+sjR((jIi55Ys^it zStcFsmW8b5;cS)uQ>fJS3)JPM+}pSNCYxNe$GF3DN_I^%wrDlwP z^&+?N6Inj`eXd$SOM7aTN$v}eW~ixh z;V!uDwcCG(XG=K2a}~?xOdw13-a+*GMshil51mj$An1N9FFV`2MnKzrEQyBVw2;fqzkG+v$e7!|AAL zmD)l*Fu+yC#Gn3L)DGBJ%h8?#5Sh{S#(vLze9HF{r?MFW$qjDZZCMp7#G;7{@@KtWt>MUnYgiY5?dMHZ+Mlu*NqVsb)C(`-6lCmVujIFSZ;gzkxA595XOkUDV4`l%*J|C5H_Hqw6oIavqzgEz=JI{^`q$ckTEWK3 zlvcUH<<{WijbUXu1z^h%1$MD?H>*+pir(b3g{M-|{5&zu=g3H+ObLP+eT!@$n%+)` zYp%0OV1pFOHKwj^)3uf!tp@F^VEysP??1dl;8+V zB)WBufJ+W5IkdNUv$t3mG~!q7g|Yzr0T)oxVy>@T|NdOzJMX+g@5|HCG{Lj8*n&x3 zf3Ak>UrXhYLb63BHBHoJwZ>Zqp`;vxL`S1jR$C*PTBI~B{Y24hR?|j3A;hfO)N%Vbc2uAsMA`R3nr@;%E|Ffr zvS~DLphB;yS|*nE6@;!SJm>)x-FJD<3s@qHZk;R?TB3K-=6PlV*xGI6{i#IVa%A83 zgxTl~2NNx3-vY3$ZB+^Lw2>Ss8B6>Pb~C*Q$`1n6{y`Cyct-RW ziDlXwAs?dR7Mq;T>Z~-M+#KakLTadepOx!fyWTvVQ~#nj7fjTv?IS$MtnOn1>!p0hY$f-7yee42 zR7(iyLKs`5X9}ln<_Fv%^*5DvnZqBHLn~6_FRM#cKMvo!V5`6gpsmk6$a!&*_cR$5 z3eIIUWmYcNBik5_G>o{_sgdNC6U4uDR#*F;=_{0v5fJgr`zc+#K;H5#kxGr$Pc7q~ zF!uBS^o$N#YGMz0*}rVTC;-p-(4Me6lHsthUALi5y;4NT#WS;vHM%z}HH#8+39JNc z|E9*N2dEWJp7Pk#jTGfdv!p`#7#Yo%uRgsAT6kZi2I>zDM@0KJ!#p#?pH5pXw?aPa zJdN-AWGZUlw^9vV$Ss;&L$gyexetio4~hqfC@c zO(;|Y-DSrVqCkl>zX1gwO%`#UQdBPK(eUE{1LWlC1X;kZDa^USPtdR6^cSiRWm$0y%HgSc-fiMG6YWe-6_sP3d_1rEP7{n$`p8@P!{Knw8IWY({(gxd|%}mxtwxd0*zf%Av9IPsWpi5c`ld8 zmUz+Zav(S-=e6!rv*<`zYmVIKHRQF+7Zy$sr$343ijUsp*}Z}rD#Z>j7q{xSJI~<^ z6O-=@Ievr>F;J1|Nw?>$hn6d*rx+$&(@5fx@>rIzP`3%Lo5nV_x1}n8@D!tTYla1&yLz^gEk6E@g30>;u!$3E z+NQ&DS{xf|fXMqA^#EBbGVM7)RWh8yqk=AmkW)4|Q&C(2cPNHnKsH#!E?~--pRJCD zTYe%B1Xq|YH%H>%7_cg9rq?OAzONckGt-g1JnDR&H+y}F&j?Gnx80&yqWJ)lAZ(6L z;X}%<8p&TU*TYnTXq6NBc@df=9c={86TuPv6R5zj#(6&{j~o&w6Uu(mqKVoP@;Je` z?lm0FZRC-A%2k*-?A#?zMp16tCV84InzEG0Zm3c1+$0gY!lPVotJIZszufpH<#AO(kJISrM)`vu&DOAlic*!5c112}Z*vP>CP;H>?foL67n9X^ zt}|6?GgqHNB2!=Xm>$=*%@2ky08mbeUR}O(O=Y5#us*pjE(sI+cNxyUbg;K;I{3jl z(()SA<+CfSRWV(xzhcTI-2rms#HR$YE^N6=Moxu_>yXlj;x=i!;}R!>ZSn;)r^&v( zmhccvC{fOnMS{WO)Vs_BM3c=n1t3GsIIWJd1~9Kgp;XwjSU%nIcQ1OAn&u{@60y5B zU{WYWzLE?CdAr`3>9B4}QE+YTwB4*cs!Ilz)2#W(4AM;Jy_B8zj!QZ_i6wyzj{Pq1 zT7UiUkfQ?)mza4vU!URHJgTlkGYqjV9n`UCcBcN5t1VOqfFZG6b7-g5HqxL=}!L zs8vSn4PHKA(Ja%HE!3zQPuAIgVELVNWhve+@}DX%Rv?39En2ff|rxYt0j z>jYe9$?RT#_@0zDwwq0Nxh*p9WJv|Y4}I=do+itOK*7>m+@Kl;FJ3z!YGZ66v%afR z7vzahWTq=Tcx+1W8{4So+c6deZ|%R*cxf!F%Qg>2>Z0KD^%iw+#|hI(FE&=9tftFn zlC$2=_P;{a#qgSNn)YX9_HAlfu$O98L?eauY)mx?^Ke7MVB-~bc0u>$R6^i}QKq|_ zh7IcYycL-%o6}GhO_*-Bm1YIjWrRWkN}8y%TShIHZP^sLM<-ijH;2%eE`!)sn8mbF zbW!WiueDn)t1i)!!u@4A%0W<;p-fKLkhJp7H)w9DrVY4Q4KHy+@F1IR(0Zx$>(nrN zAh!yre^wK@%ga4cU9o2bA-E`>vf``EQH}6=6#h(5vA0OK)!ZPdO|1NxJ|qgK)_THV zOIKyU!b#MqD-WjmOwiH%GiH7bB(6=|qNYTpC8LYGmYBu6V4c%$Bn)Sxqt=Z&cKc0W zM3Uf4uK*3Wr2^9OeZFI6Yc%J{9~tJ@*A}YidBiD`2w9!#QBm1w1=4)Ng=Ix2 z#Mmu*k=jMM2glGVT6=fP#xwW#f%Vgkjz!FF&ehWUHmjehUz8N-Un&A_!NcumFX3#u z*W3nKB0jr!WmZVZ#7DqOF^(twqk|2x&M#x!BAKfiQ_Jm&N{L_K zaf8y|K>|hJpKF$Skq$F!)rSp#mk0b;OA6)0cYfSo(nB5(4&c%xyclc<0kvk}eJ}J; zhwdqK=~#f0iazLhBx6W#f8|&^A9(53=fhV{Jk<&@mQ&(r`a#Nmb1l=0*XMh!Fvt92 zgbBv3Qz>vLD(c}Kq3>)S@)xU%B&4Q3S>8y{ocZE^-}PYrxNY)GOEQv7t4-%|s?)M` zY9a{Z_L9F%KbDk}-(_;-`#a78mmeo&HF2&FcFVv_a4z@#dE{J8eiJ)A?RZwcp?40Y z_L~ABROhsUp@4 ztKF`l)rL0CEJ7w6H;3MF>NYM)z>BIRhnoZ2Qmi#+!4C6bbMWxDCyY|kG~#v+wP+(0Gw(~ zX!l5)@Lof!A)S;;gh8%7+OAAeT-hm!yk?ej5uvQe&)KRqLV}p09#-gJPkbUtG*Xj#%PUMUj%Q)nC?IYB+5+%iojRMuF*_?@}OE> zX5JN=3vyuzt0^uv9H}uI#l$1e&Xh7MQEyRLh=2!X$1jbWaR2wE^!Bv~ zik95Sly_ACPg0>>)!JtL&X;rmOCJCoRT_*IN>VSJ$v(O)f!8{dF3=x1>5zYFYo&R* z8P-qs@uS%r_e&zqz6`l!e&ZF4+l3rRAhwVPiUb}a%?J4Y)X@9|+ z*!Cs(eQCZQiH4YGpy-afa*6C;Xp0L*RS47Ts0Hm1>nyaH#6?2vIzMn-?1Vi9V`*Qr z#bTZQoU$8_+1S})bjZd4G3YU}Xx4ae=LPKFX6ncY_NhM5z@#gvAqgR2$|k1!>Iu2I z3Gz;e8+^HBwX~ z#Oa`MkD*hWAMq+*5M|FUnh2>RJ1tzXm-jQh!n;pn33?hH5T33}Mb^j>wgrm5$jm*O zY%+U(7Mb^81ky7oe)Ld}x+@1(v!;En&}oNdxgCp3UDD5c-zLv_1y zcrBH+!0%>ZBe zPTC_Gp2w!^E8r}R`BkkvJ&c6~$s#2f{JT<3X7fl^ zxEf|qtM*l3e&$=m%z$yDOg^}hH$UWiyW-GTiJM_TA1&*Y)l54qV`;(5+jy>Ie+c4) ze35hNdi4_SD|8wPqKt4FHDB*{$dikAUh0h8nMYj+?v7QZf_osavW41}%cXMhV8Xz5 zk!0WHt5s_dRioXWHoygNAM5o$zS=Ix`GiY~=S@e!_{A;L=M(N@`%;dgyFoQgp`aEDq!I1@B8=^$tTiih^fP1xLN^(XQrR1%sf2&UqseA;dAimk}LQ z&tOkXv|W4|(8S6K`VG{hEyM>DpWKjoX7U4n5)1^a0GRt_*&F5Q$#39pF%j(>x3h@u z?Qy2uOV*IAVBlg0Z;VEa8k5;Aq3+2eBQ%(`7|pHNja)Ja*kC330Q=(uP#hab$*!dh z=n$~Sin}^wlkOU#=j>+$2Rg)^Y)`oEjIjem5q#{$zAhZ~!kdC#KE?Jqriwp0yEsoTxX^h;jafD^N*zP6fXh2LDpo-DmSwRMGhw#cc? zM}6t)3!{9;+4cK|OgT2DW3+?1Z4i)IyZur2&05YJ3r)oc_bXp{0KMqAKHXIUna0g* zZRjIQv?>Nj`+wxIoQ%pz-tak}7yRf6VV*;*k1PSZ+nXD-gg8TA{x7voOzxAo@GJdV zbNkdp6oXyH;*JKaTF;2nCZF(i;udN`KKVy?xYNd9ywestt6`O@@DCc@K7}MM%Wmae z|3EJ2TE5%eS91$mDclS7Hu|Tb@WDge?e$kqo6owW;W1EH`eTBaX(h7Pa!a+A74-?u z&tr;G*WIFgcxG(8Plq}jCN@zsDiQ1}lr^S`8gI*XiP+tu!?Y~U`BmCo*S#Mm<0=O? z57hDk=rF}A%di`}Jc!e#%g-@(YlFSdKOR3Li1~h)?ap^o5P_7yUW*GOs=^AvnNX{oBaov_QEq1L}>Rs~XGjruqCD8>4tF#+zbL4wWHa~Zyzy3a(#9)fU zJ47UqIQ4lva4t96{5Y`gF#IRHE_QK1A;r6_c5;@*WG-ZCf4)vJeXtkr`^w?<*JXp0 zld7DcL{=5OZ8X=*5ehP$f;R>Cl)WqvNu9K9&2N*T|4X%3YbnPkwh%32eIgru%2)`P>YRcDHCv-8&rY z3Yc9Qd>&`z>72J67aC#@L2oW+9f!`b3^D79@8q8Mu=#$Bg8*w_HOS{t`3O|m)=X8QG zWhjG}z#2#T@8E|f-x^I}TQ!dbbx}dp{(gKHSOxok@A_g;E!EO<+hm3@gz;%0PMwlK2FBv zDOXj~RLuLE9}?+h*w)pZFI1wg0hUDQXr6)FA0&-h)f(~SoxvTHPWhLia;C?2Sqjbw7zZAI+UD`w;? zPO{3qXrb?UT%ub~uGhWT&^$1OiL{I)=hj<_7jIVrIGm>UX~+%CiU@6uB7*{%HB3U`c9-4h1UCNMwVdjfT-bZ7!Qu&0*+h1xps`wHDqqMD zd+c>h>7aHNFkLOxZMCS&a#zWoX3v?UKZk{zeT`Fc= zNwAWc5T^T<8^mix$6XD6R9IIpQY*TjuLj}=cswj*iOLJfh-(ClBU>`u(mO7eK}iBx zADwX&i#KgZOcMc)X~P&Sj!`aLRJKFCdq1vwu8u>h{E?l_#2JKoro`oUVSo254wm zUh?gA2Q8liLFGYprJ7t?X54$YkChW_*!!EL8E9Q{iifR76s(c^GpCqVG45C<)rGc# zsGn3So1xRAtMIZ^`LLY2cT1L@Y)g&{9QxJ2U^wweyWIGa8J+t9l!6|$ZYz<2W({Ur zB)fc1SUqJ}zGtK_3?@_%j~j`l@|F&y&h(C1ro_f)DV~*6Ko?s*&kk4O8Gh6Y5V^%U zMbk@M&y>L8nDVFyVhBEMelFM6ud!|OsZyg4PrMXohz!H2bK0^^FMnw@Q{Hf1mkw-55wPzcdY`m|BaLN(nv{`{^ZG(NNMY0@6Gse*vUQrsS5&6-+IA?RY|%ia zo8Kfw+dV;AgZW+eESGk4UHlTDsr@!Obw6hs5?xFS3Tm%TcLDcar=6ikL6Wy_F4h7u znaqPP=y<-GuRsp5E7qxtaSaOxsko*X@n>HosB&K{j!blGzeZ5x`ipX*X*73eY9*E=x>tvT6qA%{RJ- z`qb-i7te=cLR{ng`gOc7!xgu%2k5_NbDG_Zb-SG2R2trnRcmZ&jqT;l(b>#%8FJeQ zxHLPI)S3dyt%xT){qkJW%+zlRi=M&151HgimC0W=k|B6J-xWzL zoc>x71A}PYx^44AM!2ELY3VlVovG(#Afx`nS5U<3?L6Y_HrkpicpT%*%t~!NseH^A zEUgN?{F^1z(%B)Va(o$}Yc};(#`a@0u9dy7mWuX#x9uB9;$zlQvokr@`hKY&Xfz=J zPI1teGkMjavRAvp1Lu|+ScQKwl2~yas(zMd^a-(JXU*60Ljt$N(7ZpMGe~YXhuGGA z*|^spQ9+yMMeUtzurUT)nC_ zfa^Cc?F&$A)q5fLI5;>gM59c-FMcNa{^&kLjc2Vct+bAFbT{ed(P@$W>@^*LC$SJI z&n@QC%C2=(KkLN}!lzO}<;?OsuSq`Gw^4N*j}mfXYLw1dxT%NKApnGw>-GTuEQ3*>RzU(QjBu=cn{)cFLC*~LR>PH>BK zdM1_aK&R0|Em>-D@`X7yQ$zW`jl(RJ)9zgf&%R6VTx?R*M2=`U`Q#LSfLuBh50E*u zPgb$ z!2W!b`>)P+RkIE4YHBmuYZq7RmC^`IndXxi^=gd@%_;gK4-6IeadFA;n!W7uVAana zU+F)`JeQ4gd-Un&t7Rr8vQpAkjl1ndiF5@g=ju0=al$W2*bGeP^!Kgxv*>!3NlUNd zwGVD5PPHAUi}bseu`+j1g^3j9BGo1X>yKITMnJS#)z*-6G48~8JQK4`krcvb+VKqf z8E#}Wsu|w*UCl`U0_1eIcDDF(rL6SjIBvpH`#fqLj?v%T$FH5kdE1U5r+6{bh~bHM z7L!m4AWUSOwlRt$ySx><)(`v@;2J+FoVMH!Z)^cT{GELx0fiXZhNM{qmxb!Cb-aS# zsQ>+Iti((Jhuo#on*TZM>>6E|gy)$zL~m0w)N$LME0g%>E;m!k6hNjVJxcI%&V4%3 z{2-OPB?xBe@8Lq*yWRXouH*zz^aE-*xxgQDbz7b@6#XUxTcaJR@GcKh3+(ue&(qsH zYSm_=#TnG%v0Ecco+)ur<@vz2$DWjoR9Xmr%D|Be(_MyCo46tuS3y;2@5*Sqv<$g5 z@EM>^q-3FLV!=GTe1b=*2{sR4aSfYN5l<|W6hHxM`X~R;O*6LnSWQ2)T`Sis%J!l% zg{5d17)G55~#HVRD+JQ6o0Ns z1TTrHsZFGbi|h_F;JM~$qs&3A%s0tpqGF{Wa)y3tJHowJBcx2K026a^R}AsdOj%iZ zw)GcdRc0vZZM*XY0^syaOw$4NzkaLz*G8?VRJ1V=TeA=cS!T(tW@{P20N`D(Nfboh0KMK8nalYD~j+NMo<8mJ>?M3XZWkcIJh z?1^*oZA^JWlce0!JEXseW%}MEhpo~I2e!En#Z|0Ff17erVced^y@%MUQJl=}|BxI_ z!?%ArK}-qP2);Lx!Z)?f5do|zCX}Ei9McS@3x!%hb#S50n9K3@AdT;)h2`Vgo99Re zi5nnHhw{CYJ8JLZxHAhsf8s+cP3+5e=ogJ*tV4rwZuCZGLjf>>2G7v*fx%t)q zzDz8+87FHWxC@rZ;mdck8!1c~hi$5uE<_Y>m=5IDzwx#ORr*Y2>E z?=wQor25lLxt^Z0`AzA9m)#P`{0Fb^QwF63y&{=&c5_KI91G~W1maDQ57_IRf$aJI zP^NE+MZv@E=V__8#p7HOsCSgd@lD3Wtz4|keOq(foPtjdXvo$HrIlFoI1|ElAVo%> zI0oZnV|%e*eF&rSwa$MSBbCxa*PSh_KjD9gFP}hyIhViz$(l%hqvi*+Y%cGc%X%Bh z2+D$@nD0B$FN9%zF$(MoQ-kp)vy8#`O||}6K4r96#C^QI*HWVgLS6~X5P|CJm+ZR@=SRK(Vv2by$}6aap?uutoI01DwWmAs<2^Te-j)v~pV1urof-zmm* z{(%Tjoj2f5`8M2*%hp0GlOkSIVX8qH1cXu*nb}tIF4R}&T#Prz(7DNUsul$g+-suS z8@7C_{ZU?@(`uv@KscUkhP@_3zk9c9?}8i8Am!aQyeY?H$Bwhb9MK$uKm->^r4*u@P zqyazA>LelMuq*PnzF6zu?rK)5A z4$oIyDuo!wCJ&o%TBmE_L|5&p(JB?+lH7Wmb-Zsk8K^e!zR&FP_IWFY2{GvU4NPwk zMHW|PN)vi^xTHoCiiU~ANH!yn+w)D+vh6IgX$xt@GZ<8w+{QAy{NaI6_k+=ISe2%qRE zoYHu(?ReOJHQ>4!X2Sk z**&2|$0OGTyoW*qNxhACt)w|vE*^pqOK&^`qAHMbp_EH|{F^*x1JlHm1Ox*2t2dg#Cm`y#;G0#GcKH%4?YmJKnJN8nc_`g_Q;KbABguCZ?aXa3)$LNaNq*ll5Jz}|t6rZn3Yf_wlH64FDa*Qzqe!fH zhpdN3>1V^Mo#PbC63w<(9((rb^W4waMQee+kgTvB~L43Yamn#4`*! z>W4v**K9=LudD1s#P0an69WND8N22xIkcajau&PA*_UDm{UsRew^+ht$FV}cL3I9` zJoMT(|K@I>fbUKDZTD>~#g*alu}#08P+*_ECjVM6QAdS-$G|W9X)=@M2+0RKgPzwQ zhE}Ae>NAq_pE>KO%Vm(DVq)^6Hm+mKe(7M8RENbRdikEuasJ#`bhVtgwsxyY@^^7r zp50^)yYd9K6b{4Y&duqUa?aDdZ;~{$`J&{NxGlcT3i3D9T1|kwQMIzoUAX&TXB-?E z=RU_QD@kLX;@#sz7k@O$VZ4Px_Lq1GQsHF2n?qEn`ysF0qQ#5&UCrHooGV?UPNJmb zJLXO6BglBSuRevEI)Zs4?Mi=QuU)=(muUAs9PpRw{o=7jnGOdc#vY?1SYbpIJuHsj z&Z}~RqF5e^CjZG7efXe&=9d1Ze{-Ob@n}3p>MrI3Y>V%3b^$=%_mE;f&{-<=;=xv+ z%4xI9Wkj{L-E+}z0jE5l7`=zIYhG|aX41OQ@jOk9Pny0uyv9VwBwVLUKC^Mydm=#t{cbq@F$Q+EI9?jqzUY;h%OC^ha zDSl6O(|WFYut4dMQmg!`=C(6Z%2&ws>bwF)R6NHYKyAI;TBlhSg#@Dj8M)^@odUyV zuQ{+vdJNznAT2QPG2cJvAr;v9e8$jM7|`+? zXKb`-QX_ zAX=E2F|h#8-GJS0K8zR2!W$R!och3ZR?Ls6)6wUMJ^YB7@I0`tku!X;Qm?!o-Q=h< zaY>K`<~#%d$<&Gt_#V^=`Rn@&o{1NZKk|olA9OGRF}Zb~Gb40zB)r1us!uWIS{@1ebd&cDu#mRcCkp;iGh;#RVFW^;EHDLgeJ) z%8Fq--ssiQR*_o48)7P*HrMOI=r_Ykz4Z0QV`tXmHPS!zgeLypOEIaM-xUicqJytM58J6mf$flRq;-6~V_zT*7wcRe z8M{8{=P#8q**uB`o_KbBxB=HsAW9`r6g@HHBXK#ETAaBk5E)gnySj*=6Hv>Q{sJJP zLn*J2XDboczph6P^!Zcxx+Q|Z(WQEI^YY&Tl{42+0=2cVoue-$xUs=!Nhk2}Z*kH| zJA8oT=#Yj?fnBRS4Uk4Z<8_^Er*geMg?&FVmP)zWFmLZFe;93?n!EqnJ-adCB7ptM zX=Zd~m{PKDB&Chu{4K_May-Kf$WA#%T-;wM2^SXpXJeWINbU*yY$~rE>cNxT#4huN zdWshOtM_A!iADRzVKjoOgTX6G^?Y_J{h-{&ii-|VKq1qz2>A4g4{`K>YZ3;)o$$f==+?BXgI)n z3)fYYOsOWtsZLu0;ySvnxtz%LyEAq@eUTCClXPdVLx%!1aWS3?uE%7q(UcgK%AskNSc z20aq#3`R$!4NfqRmI^c>uJWayB}V^9>z7mcb2cTQK?@95`D{ZUh9ROQgHIzUf+fpY7Uv{f=jh@83NJ!||ez?=ySe zab4G)Z2Z3L?Y=}B$`{K97ezWk68X%&+gI1Q*wUGqtz2p)FpTce3=->-V;NsuVxk!> z?>hi+V=ANFU?xOS+`|=Nt>sp*vQTm>IvH(85!BP{M z^fP3OxF3=foiaHAMFHMu6h7%N_7;ZDJSbckNa!yJ+(!sbm#bIfM(s;4Mze&2|0#X2 zB#mp_f@||vt()PWhK90S@`uOIuniqgJYPJ1ww*yPvk$*Eus>bht2r!@Pzn~h%46z^ zgmyQVyK5=sl6TRZij+GVIZWdPqk0DX^gB|?v2wZM#&Wo7?x&j{h9emEWH>BlBq+Jv zE{)SrrdJdB7dWdQBjJ};mQ}5aN7;0hx1YNde^P6;9-2kuB<;%^h#QbdX(5YbzD}Uk z&^=hZOST&_E#XAWm&7%*b%@`abF49*kd9f>P&$~e&z4ubgH7Fi_3T^X=M{T#*t@)w z4LTf*m$vC*Mjx_!BjyGvvU|kX%Fg%R%?)acJ**{YB~WW*#^h_H!~-nJ*Zz;KCIeMT zA`!QrVvGhS_W&JyygzEb;351?_0X5c`tCsvcny7aEZw2#)r%w)jTdfH*~)w=Dc^$E zTBwUP?awM|DK8bOjF%0iaA@CEs6TuhRQg1FBb3BwAg*eJP}XRC@a#r7GR;_nfYe}X zY>g9=s2_t^IE?+X-p&(0^LuzDr01*%i;J?+BvD+*RUzRfG8? zIW?*Q6ggij)p>-|Wj^uPLYHPQPH?2d)~x&kLa%1Oc*C&1Mm+a1%u9E9)5(IoU0vHu zhrMJl_A>^no7Rly?~0XZJ{=H9cmvSj)%u(gD}pjg>nr(pst($j+V^hPkVL_y=(Gy- zAWv})uhnRg-7FPRZwR@TkG*UW4yAB5#6aIWnA4}k>iDeO~gDr3&tNLcQMZ}X2=TE$d@^p zASVBn4ea#sCmYyw(gOLq*#2z5*%dK)gHAoxx$^AUXuh(e#A6fN*xH5sp~R9H&*?*1 zkj)zF*S3ja#!k4-5(JpEleNJZQi*lIJ{5g538;8a=gO(qls~;)T=jlh2?Rvm^2v;^ z)6`hbXfH&r_Q#N;l1o{S>$IQBaJ)2+tIJNZ-~{oynCG{-e`Rr^Z~yKc%N1avkP=8`sg(f=twO`2SuPl7LD$n=ChHEBod{K6 z`i^_HeQdt*sH!dNx5JJbqBpvU&>)vie|JAv0p1?7GVsxKq0xSFm(&;1VQ*0l073xV zXctg1g~M^lmISwlWl-i~_6<-N##X03iR*J(E`B#|=;RA%98@*{;e12s47qY`NI0#+ zXC(5MUs788%A*+}vR%reXlqT!tBJW9G7S(aHb;7;)9yPZISdA4kIxV% zUOY35$chn(plvNT{Z>>KBf<)2li~5ma3s|*jYfSx3#hcIO}&X3TP?;|=?McAj|M~B zsi`t8&(@1Tz(z4WHd6v2j_noH3R!3tQg(M17v_Vm<6r_RLV8hNZ*RIszM3shUGPq~ z(_0LtobumWm7%X=KcEg z8PW5P%qEM?u8XDbi-jcOx5Jo->B!j3Ra&*ZZ?C(P=UqUMJYW`*Z-?@$RFfSD`H4Gwj#4>g^8sl&o)Be zeF1mZizkKq1o$k^Fmw_m=&~c&igRYw#^76J(ILyX52Zww-N_5|j8|8;+~C z8s@G#?r#1}r~*tRaQIg=8TZ5w(lht&PzT7f97=GA3?A+-DdYM%0?(_Vu8!I9a!ghpvwEI!-SMLZ{Uz4<=Vp-h^7`sp!`MIMCnmonQSlD@ zTWeXf&Qb^(g@W`2qPug9%WB_eB_SO0H<8cXkM&pBs^4RfFugaQt2oMzl$)K$N$vvS z5`g2KTt>;+bG9K684#6MrujKXA8uu)LCPSt&D&FB^N42f4JKxf&ULLFW<08Ufo~O zNCZL4lrNTaYAXR}lVuu7)T)fG*yefU;;~jk+iMGr4$Pk81I<-di{=;2R5_$B{XbwL z!u6Eu<*tA-&ur{dS%5syioiBFH%0AB zc>J0S`;%Nwm<6I$E{;OyK=21xr;8aRs#9@a1zX>DrMU3Q1P`T zK$wgwzD(L=xq>33wib3reaWgY?p^>OkY~cSVxBzPZuRKwA(c>4uXj=8YfaV8etfnw zRYoi|cg-Z$7CY^*oI|QKS<&Rs<2INr9QQ0>D@-ux z$h1sm8;n}kv)AoXx0tH=NkHF84b7d+?vXa0DDoe=v<75Cpo+0ISuLM3xm2oFt24QK z6`3*HVVRV0-1=ghiGO30 zQ9pd0)S%vKjNSFTtaX2(@!@n!UQ0_0n}pmR$acu*MsNA(H`u3*sn?2`+HdSHm?@Xt z5rZ^3U`&7LfbBzccv`W8_y4_Js*H1NNIv{Y@N04 z;KiGeSc>r+>9sb0kNevzV69p%#j9jSU*Hu-boD^BrPdRZSoINp2qJENJ30Ar=Z*5Ncd#k?k@ z>QndFbj{?aFX>QOK+F)x-?<*s(6mQ0|F|C&0TE^g3p8=tdDs>lKn(-=xAqG^x0{97 z@>4`-+Eq;B-RTxMUr!WKb|s5NpbQewE|1+_hBWc|FH!+NHQ$~o68fAYU%#zSbJ9Gn zseZabOh6uweVvt~bSzxscDx!~*Gb@i&%Dq8{S)E^pCI#wHxytpCd)Jd58;&QO;pL4 zny7BoF@<`awv(b56cfto zNu6u7(Xi@W59cR-#UmVljXHtV#qR{pWq3O0h|sn`I>P1;IT9hKQFShRTF%(5ZuJ#p zBE6iBnwCm0yki#833v&N{>GH}!=7N50mjq`H3b}GBxaPD8Ld_e^)dmr-0tz3Co`%z z&_MCLYfube8t5zVwOt>cs*QbKd&*S)H6J0r+bihndJ^WYq>A>eUv z>-)NVcXReZXJ;2rm~6phs%3n^_1UgLc}~8V#4{pyqMHBc-#;v$1Gwq;@$Ph(RG`aV zaNgo^13MeZJdVq?G;`@ZHwi=LW9doCbRQ(dnpMjb^b)AJNNR`K5;d%s+3PhmER z^hMu1hDN5RdYfz04ZsFF8;d^$&PWPk_&gUue7HOOh4MOfgUi`0U9TsP{q?gucN(=u zyM1G_7tVi$0{-&7XaG3^4}$>m`tQ7feKlFC`W}d<1;F$lS|2lfF-!xJ1Gs?ERUu6d zf{cIvE&M}Ik zLSn;MoDCQZQ_Ct&4y=U&f=r3H_D@l{KWFFPR(D%01SFBXq&~nMoIr8dy0z#mh;N*u zMvv8)tIId3$ev6P{v}}YkN5pCHC`{lL}zM4LPDpK0sYyQgNxm$E00t;U0|NnST2AJ zSiZI#?B6%pDG$7Nq-j5u1&S6^G>vj%a%hLGR7xw+ZZRKR(|QbqA;Xl)})iAU?D@&38P~kb6w~CZ{8HjVA*l|29N_{Mx4D-DkPjWbI_+ z@Kb(LkOUbS*=lcTXR37IL8H;_Y5qd`AMjUE{U>>;`g z|E(E+`L%5U2FN?#py%BG^7a23p?`ex@&@mFM9BKTHhiC!pTBRRjPUGl7uG+g@&C9G zpal0lU<&#Ex0%r<1n+|g8v0)w-iUzw-zD|mC4~&mmj541>Nc{u5+d@)W+!_TG!z_; zPvdLY{e9Z^-g4^VnRRMgfsI_bq7-sXb&Z&gf!c8UaLLdu7mU5-yZain3G-`E2Rs)f zl@FtLd%N@dO~fSpP{01jra{1D7I?s@dY}+O{^kePA3XaOVl)L>)ay4tS)7pYg0gq; z6}P{>?C(D#!-HotA+p%uq9A_r^Tr+u%`fX3UH?k#cP$VlL<7$XLcX#5O|L+=gSMex z!3v#G^&Q9jt_4y2ufVhZP(h1--&jV>b*^$b+MpE@fvC=Mp_S`%6J*L`_TN$kIW z#~WVnO#%=~y_GA6{@Wq@x4&d1Zo?L2eLd*+`D1?wH&p#6CGgV0@{=R3pz7Q}(y>&>`Fu$KIeP51DSmsZiMAPnXJ?+$p#FZ{L-rE#3-mFRK9Ugl{RFcTgJ%tmljwin zGxo>ew2ZLEQ-S~e1earjXaBo&|GRX-W%=Kw`}0ix@2UI8nf%{V_ve}X_owc3Vq0${ z!TZ!lF@Lq%QjouAf08O^ltrPJXq)*&$MZk-Knp(9fiEw&=gIQf-1k}m0$-n*;M+5G zRS_;!qx{X%;n9^kPSPMe;=D?h&d4ka4aA3fH5-7c*?w0|_ZtsVBG>s|ZcN6a!` zyie-X!&5SZ9=Q2AN2xRk{w;Y8IFq)uIjl|2sF#;lFCM&V2`*90;OGK~elho~M4=dT z-#i>HhssJZWQj!X>?gAe08w{hISd~(W|Q7Kiu`nTlE)a^YUE!TB1JZi`**1kWRb5Y zi}6POv@pLHlOOIXmM>LaXx*6{L*pg!5BM>lHgNdA>nN)zedn~F*&*PSKeEK_go2EF z3uzIS9fm&MKhxb$A#5k{!y`opr91NOeLDL{^1qA++zbd|c99`z11+PFTj3$p8ikEC`04dA7uH2If zXdD^XgP2)zIx{8vTABVtgnxbwKRcXu3(UkvD@Og(pqE}nLGUJ&)n$#P$$XCT zlCch75K&Cus@JL<{piWU$?<#rt0To9ONPwja;n0Rwo>0M`Q!PM$VMzEe-SNih`@~; zdbS|bw@wg@rD<><8?we`$>re%&zHZb|HBY!TZAshL{JW?WV2g0iie;iDavK-t9`31 zmDU&^FzMs&TP}yI8Fu7?`?F(oU$X$d;H5u=19}K57a2wALnNvGW7+>4^h3s1C^iQ1B--&_7S-QalBLMRUEaAT zM`pCPw+N_EM3}yfZ91f8{^#KQJk`6QbsHNL#fl{iCgKK!q(!JB;;^@7#&Fa4JIliX4i8N~G8ZFIBB8Aj=j#FE5{4 zcF(iD8c;XHi2Y?a32~vz9n^PKq@5so^yu*eI+MrpZ0S01{K2cNVW%^pxMyM2NOLUI~pXHf;PM$l6|)-)<6D75EhiBZ}}r0K9cW2&axe>1=4V(n1J`Q=xC z2n<9W`wQVW!JzeV+wb@jYw_Uaub)anv65;B!b=MDagCh-gSiBaJlt`7J?bVZY4Fe+D7iWMR94@E2r5I&7la zri8qFzE0WmIJ5rV4fzN>YEfUm$GTGr9*DL7nKYIlL_X-gO=l34d_nnvg0-HMx>D(`V-?OjCR+B0% zaGfP{weD^fU6Gh{YBis%e{@}u4JVO{{mzX#EJ3+kht33whZnmOj%TxHKSCNCdy{w# z({tCitI&ZBGo19NTHI{s4 zct={x1AzaPxbgD#&BcM%<8Rx^qw$z&G&9SS#5PC-pgUdo58P-G8QTw=%O6AyR(1T4 z4=*l&R^LO*qbGN6?gtB=hnu6sBmkXbGeVMHD4$0ypQjM~qnrK1ApAF=c9O_sw0P5Y zF#rgyy%sZBNn^S)wfl&rlwL70G5PsM6`&9ei4gi>7y(}kCB!orZ$86ecqAmHF)M3p zli8dP#l^*AqQBk(f8J=n{ORS@2`AVak%7gk8@4^WI+9?tkQ_&ueQY&d{+!9^F1Jeb zB2l(8=S9OPpG5rN>#gYu`xH6kcb{!0Cil2<%dEOWG0OnZf|B@Ir`UH;D2P}je4);{ zm^Do#G6R04=_>Sl0jM&PvA7UJCRKze7D@pH*b6V{FKzD<+5vk7b!tHae|9|6)i;HX zpVqQ0fbUKPR6_&umC4VpO0JObIptgjW-1Nj#lO!&RQ+6oZMBkZjSr>^<9u9~TpC>A zf3u+uS)N<53-rO)0abYV+{e|XGoNHTGxU?oprCTpwwz8kKOaX~a3QzZm0GWmOQrFS zcQnP*Y6Twz>G&qIyf@cDdwjzQo66yO|78Z!{TdMfV`tm$@1jX13`b5H91mJDGBPN8 zKdDxBfvly$D$zgBbabfxfOLM@gNJmP+O~Cf`|Pix|FKe$NnzhO3v6};$7nR1O&Vy_ z*!ADv-B2`_pDO^q)WM?bN9K++ViDFj|3Fq!WHhvIH5&OtYPEqZ2`zVzo1E^m;XvF(-n$pxz7>gCQ23MO)}>up&RV>bo_Bh#93^!@;}y2-=<03Y2t@84c^1*0a=$QQl7arms;Ehn5mmj{h>=Xkj^vC|RL{qXo{ zk!*8vidyO+Nk^S*LfiCF3{d)7{GLycy-!iT3YO#t!SC*G4`Qff{-V>gJfI+*^a|1XF|X{;70a{aM_5my>MRV}*7 z&)2bZDn`GMEmaZPZ5_vr=MOI*%v5eLa1K%BD@T|oeZID9_qhU@=Y22qXLM3Kla`z= zU59Vd=sfoiTF138+dH)5GYG%qa@wu#)}Qo7rnwxSnk+WepR5immTNBpzHXw}>giTx zZ$uim^YLl!pmL?bP?!n~{OVBJ+?-@=@l+`Rm&1?MLR<2P49PT3gBG_wa-$C~Vf1>! z3SS@?0WGMbN+Y@;bsHChk(gdCnRNBb?Ep4V5>Mx(d|A&R(PmBD2rP);{J@lyIXtbU zVr6$)&8DZSu#liiVXfnXCy?ZpN~HIGYMHq*jMsYi1S!N;@&mW(J(P2ktqb5$c8FDC z1xO;x$08AMIIN%6XZK38b8)SRy~tP15hbFsx%hc`9T1Z7rE$2Q?>FCESqXGwJ(>Ea z7Qpf9mjpJM^IcT~2TBnutHb+8fvo29>$VF3M&+tnX*e8DW40yNZLOg|M8n~BHRcIW z+dtHiTeQ917VDb;sTrFty}zcfVLM+f5iq1aX*OJsA?4a1}g3fek zKOU^IGGWGcD3tsm3y#P0NcTtAR=YquHdCJ2;{5!5OW-|Mg>|P=Y^D7UMja0^hR;Ny z>h!#->`{jT$&P6u9*$V5kjk7Q6S+m8@K}h_LdYw_Vc9MJK~BTn)wT<7dZm(gnJS-O zifb*Wvso^Ki@e&wWb5l^`!SMu-Ul_u&xei9+uvpYWKN^m1uxt=eSXpTWKH;lc2IlZ z^ZU8sX4hxQ$8qNXq6Q{i4u353B?N`&Hvd?$m5XCt!hJN1ClQhWc8Ha#v2mgPQ0SII z$wfOsdNWdk%fnt*^TmVfsS*YScLbxDUfKJM37Yi{#YRSQ+i*L90^7wd9;*B{XP)zC zUzqlEoum(`f?g=XWF~nIYqr=_@55lR>hl9YjeWCmm>pCk0Uw9mW_b-(;s>%NnqQSlRsqaG!Or9-1&n)8TZ+wck=t?q_UrR($>7(m zH9K|Icc$`|Hv```!MPoz0)^?GLBnID(s6n7@!4or5}IG>ygRKAy3~iZ=g^sp2uOGh zH|oJz`VLh2PZr!!2&HKxnx^HDIUR3;=^Gjw-XLTUR;`_;$;&*|>pIT42*W^Hz7cDi zyBT?U?b5`~An%H`$Z+`_x+Trsmp=bV{wF!#PX&*WV`gJRY7E<_=+#F<#xZ5TdiqJH zs#ZQI<&}FbLAvP_zRfgW;#~j~$dc1=JGS^Kd=}FVK&}%KOHEC)gCRojRrTQ9q}yM- zV>2dV92ib>J?viI9DOa0Mn}0P-ur`e5J2rHXaIYs$8mW6Dvk5*THgJxJ4;a`Jb_ND z+wthfnm_zH0fX+xa~u8we&w{p3Svem-1dCc@qo=rq?jT$osKF{SSHwxv&vGw+EhrR z9%iRE9E%sJ{$tTME|23#Y*Z!#Mh+X<^cFk*I@6`hMsA?n`D7_q;(-^X(fvtATKtL@jlFyH? zl6XS+43}NEcX(m!WhvmI?G#TH%+~9@pw1(27PRM|*`6-UN1k}|9q~o&_eSH7E8zIEX#oerU8XNW+L+ahtkl|=_CzmO5TQ090s`q9M_<@5Gzur1_#qBj)7;c|vb>wQcTH%Y9N{>|bH-o>2f zA#2;mOo^m4q@v|@%``1TY>#}c7R58-ZVhJNM#AsQ_o{^ck?YMk;w~xQK^_R%JBO@&Zu3udWsv>^Fd@k;T4+7&i|<6?@M}_`{LTj{gu(`(aJf&H!1-yZN1e2!5&0&#smVrL1*0j3ob3~rNk2JvH&X_0&%oAW zEDpB`u}wO`w=W-*)8xHuB{0YXVq8N7HseoAFZ=)MQB25ryw z+I=7PW*QGB_vV~zqcF3~XBe%enqW*$x+|Qdl9^G|be0WJ(4Te6%79I@eMa>Sz%s|Z zz_llq0FPGgVu(rbI4+n(JQjJ$?do{4 zRKxZ%XcPf$go^Qte`rFj#e!zGFpJ5kJphj%12K-4mX9WX_QV(POz*1C3?{S#HS{*Mr4oXgHJ{=@?F-<5iVU1Uyn=F=UE)!fbH-I3G;k z&M@P%9OqlxgnS^D$|_6wa+{X0j^7w;YaY)g6?t&tzCb=$$@H3^gH05=@u9K)`r{52 z3WFpHW6b!}&e{21Be+u$_MR9eQ7KDv2Xb@=0VMwWAdGVJrIwv*mJG2N;lMNUG2t(V zgbjv60i$|k$udhF+UuyYSGt#&&`(F_U|^ss<$iQUgo|7NaSbB81skgYDb%~9?t$9w|J9KR;9)_iL8l5-*V~NV+a!>2_L3UXX z2A|vM6&iJFP;2W$fvm4$Xoen?z?_4I5Sm?orU>IJde}<;LtY==eGHnpdk$NE^2JK%Z3C*u!-R@!55^jSW4V+|`+g)4{O^TTvC z&gAn57dB1eOp$GRr=1_XAifJhNWL(=vb{kc+*rAi52(#2Hp@HxPz=`}gU9UjZH)AU zn>(xRQQX?k^HK)tbC-?=P4#Qy;Euqb2WHD(4ou_~hL-{c3V2!gAxk1vlz9qr^6m&l zIiKoOkUM)KQlOkQN&J_B%vCG3xAToBj;O+M4Vim7|Z5F<98{e zj8=r}^6OJfjiY6;3~OS)HcXA_=h0ausP!HT`BIG$4fSX=@0|KR-ZyBDfl32f31v8% zG_eGIk2dp^-$~YA>~S61?r6oyW6%$xfKuJ5(QLJjtsd?n=rp>NrR6J9dRHNF^7%u6 zWa(`I=xvB}vu|rSYb=Xh+R&F7$n7rs7>erduFw4lp_7W#E;Kh^DPLPGSYUDbjr1-1 zrZ8I=-(PXvcB48cUAvO!7^&{0a3$1EzM`%+oA?SZSO@L&a!OH2I)j62C6aHdbk3Mk zV46u^bgEcHxq!VP=FXl94m#7zOPR;zOg6X4Y^0_B1S3b3SNFKf8gLcRlkmA5ngF7@ zD4C4*4RFuN!(L=_MTxU%nG5dhrJXD(nsM4~=W!E%PF&plj4F{pec!rtBe*Gd{ccaV z-)QIx;Wexx1#XC8>Xd)Iy3`A{?di;teSD1~m1Vv+w4glkBX3RjFuKkGX5~-n2I9ya zmBZ(FTtst0Tng9{b=DK#A(}xsHbGoD7?pCX5BoO$FR?5%*LYx6r5lBFODsthy@?Nz zQD%2JPL#@6c*zE0(fK`YmK&34)R@O@V!U(pruKQVg(JCa&zq{+K3ktC-JVIN8uy%1 z7&CoN4~x!+1vNxGj|c|-EW4yygP|BJ`TFBf2qH_ zKC60p7ZeVa_Py4_7x9tDYhHta*bWtj_ZS$D$Ay_KA)!a-6dN7FY18J!>jh0;ppr?; z!wG(!$iZQ@?hp+NM^zOSfNDXfidUp%3lty{L=?=J%?ZwKY6_F-NaF<6K<$|G%0CX` z?}P!NQPp?{PgGdCAiWJ*Iewds_$$iRtiLn1!+7j z0(n9{K7GGXQ<o#{`IA;N)6*jl&If~@ z6kM34jI3m==8ziO+k0Fhby685J>0uK&pQa}#AYJXz2aT&c|TTYODD?p6~^&kQMtyP z0=qlxk=~v^jzXPP`)Ky#Q0XzCg?+Kl1hJ5CDCh-w7akoa+8YAAB#6{(zsUNxOYX`V zO{_mky`g;uo<@U`8dd57--bxJg`bT2wLy*}6G>81xj79F3R`!6`_lU$oPi~ls7DEAaWAwDq!#pe_(lw#Y|~yzA%l|%O7Khb`oI!{c)hHJ+7;cu=Xh` zI_cKwO1Rp?BR&Qo?ofEXS6pi^D>@ETTnk-FppZv=WE6_|ELTeb{YZ`7?+bB!@VKIH zEcC~x0vK}d%$M=&dg!+?2|!LXiCe=q*JkhoV@)~Q2%2O2g-OaM#<11$eR=YO4Ou9u z`-Ylz!_^?QN%Z@ zGFO?N9VjG+v#LIQe^afo;ljt-m7O`MJav4$HuyL^IawSVvkK6ro(N9LOg9;rl^l2~ z6bdj(`Msg>(I=(Js7rHqFi3UHQ!w% zDAK9aZAY5Bkhh=Vam^68$hh`(I-T3OXb2~vTDm!-eEK8koG@fFPW6t@Ay6>RVYo%& znipTD%VCB21}SO`k)`OX;QgS{jMSbd_3%hmL35x}wQ_^ibWASyaX&;PKA%tu2Pn2< z0ypv5e(oH1@k%5N$E*l1p5h}Mjb_npmS?;u0^Sn4_tb$ew6~qb=Yq%XD{;#&xZQW* z(1?~Sk<+->&N6xiw8w(w5CtKqU$8ij8N)uZ%BI5A5M)%+=KvQs$v48&OKsJX{e{_` z_^uA^25TwoQB}HA2sYYi|@q@*|r2Vy8J zS!Ylu7#{?Y3k$p)9B72|xOPF)A2ztWZjye_J=rW~$#A2PfBu6@OHKiyBD2Ap64$i> zmX1rcrTt(&sgxe(3eS7hd)wmkZV831i>Vro!yo0F8M(fJVIAtIeq{=U-0Sh}3Ojdq8k9M)6M3J4WCoIv^x1W07bq*(L` z8DV8k5YyKD;js5k$AFt72zk)yDc&)kHC`rRk!b}Z3|E~$nO|7B!#p6uu*|<)^9^a> z%?S_@-^VaC1zc;P?#l9~FB6H`qLr$O^M)6A!*kF}8qj5jGg`l1)OxS<$|%;b&Z277 z+-fltqrYe}anD^FCGLzBar+vLAX4C2Yrf!3=F;xd9d&M?4Gx8hwc;o!LpR;5A_ZUV zqvHXh{AG)2W2{D#?kC6eO3p%Wn9t6(Z6GEwVKW~G4|xkJ`nCjN*myY$z0)f6y?TZb6A1rHj?!*5eW@+%yUuVh?rg#0vjr6*FDk$H$k; zZr7*OZQ%_D&Fu>_$t@S5prfu}d5MIwr!0l|%^t5ufNCyc715}Odgb}E%yT_T;u?!N z>w%jKET>%N?S`Wjze0%yO>uz1`1q_=d4z5~IS7K4CY}2AI`#Fq1W@;=v^x?sXQO;g ziI>=s%l*xMr91DztKIgV@fJ$;^6H@Pv&-2F8m;q4CAG0Uh|eSn_L;U*`wyk+vmh+~ z-Y(9duUuBeQG%=F4f@l-6jsYL4ztq9(h4AOVLE!tfgx=t-`!1QQF@NYnUdfW`ze2eX)!3o*B#z`O2-Q-&H z?CO-yr@IT!LTsvwGDM!Fz)8}%qIg9+ou9AlTmZGpi}{N!vk|A#e$@K76X`fwG4%yq zXwOTh%k8_EDf|V``<`x6;q_IxrZJK)$uD)NG4BK(54@>KYjD52A1uDmf?pX@KDeKD zldgLa*N-zbvG!gYIbNxAoRYWWrCaw>sK>~8>X|Q>wfa;;_v;4+xgNv`JS?=Po7APP z7m)|No+}vRGhAsRst2*@M`6B|l0v=fk~eho%{QkLdJm3A3%YrdSo!+Hu`}`>N3d1K zBL)v_-duExsKK}m_oAuxW6;(ubkPDyHf@dkISxm|Oy!8zhYZecQ@e#c;;#8tk!x8` zfe+?32z?k8tf9saAs1EgNQhB@!1`nzaU_*hGSK~Gy~HMo@%iJyzTNrHm^*pbt*0_6 zv@{O7WeT5D8x0YcrBZ4@34@gn>^j*2XAG-An(h%Mt!Dj(Bb(S5iHcx}cpUs}tO0ga zgo}Oa!`W243dT);%m~lA(vxxFZ`H7HkeZ-=!j#2nBA=(`bA)laH-WrJ3@V5_i*4St zMFVkEK@i7u)bjava2n7$@9ySt2PqKfw6r?!RW8wJlvLPPwY-L6$T8QgaDmPz&hp_= zy?1M$a^qQOY-|KR7xwl%o-xqww&0h03o{VM#0&Qt5k#3%Z01NL{o9q%+7^aNT@%0EEuN2PRE8Jtc;VkjEkm*7wpRPiAqmN%<>9qKW zbcz2 z)Xn%e0&aMCd*~JwT&&?--^*rhzFIlnK3@OrhK zeQD%=()y=yEBYc~SRnXJD`7ZA(f@I7^=l?ExC}c{-XA=A^qD=xad>xaFabsfdv}&4 zBb;bq9HfHjmaqCfr`tuz`ELOx#Gr6WXBtwwAj)L7&? z;9&MMh}DS$Q*GDQ_S^=WSw04efmnRkJFur-b^LK+P`1S59*~%VF9Z5(iSXG~#5)4M z!fifeIJJqXnkFE!wLsz#=TW33!g|J77J#_DoWFe6ctNN2j??g64|;^BatS&gWH`=b zr|pM zlN&UtcO-iApZe8#=G8S@5M2%#t*-Z<*wS&w=v4g-SF^o}s?%S0>R)N(K7YpTdLb3b zQtQ6xrleUd+d>v8UKi~2CG%3DVfboL$J=g9+H4V__7}Mnv z0nv3^XIGPrWNlAE#XR6UBF5m5Wa*`39kdktYxpY^`k#HZsFhPez%acu88=jseL{cA zB2r_X##tDMuUAYX@r_WH^0QmU6$%u!zTSzBox57Kg`@UC1Ss~mbv=ef0sWCbOv~2v ziosE5wwqCLQ6t8%rV^Uq5tL9;g(deO&JS1tI$eKr&ZyP)HD98Sb%|uNXNy?T8yVQ=jH!Kf+nS#kviJ@v~P<>IwG1R?DmF5CrRmR-V>B&G4FGL>OCW z3ef;YqMaXY^ej#o!MFb~o*lRhfmf)oNfhIlvz0*zE*;Ou*K8$1Nz42{3x^lYrrB$I z;}K^+e@v7c@;2LWB1;IN+bZM(VaqV#q!&b|jPNIwo_p929wX^#e9)eUm&}3boj1!z1ra-7C{?py$2i29m>)kpQ~hI>Snvn zNCbJiWQ#m|zFh68#qCKHHlQ3Cm?7MjYMKdUJ=55C-SN#FzQ zc^n$jniiHnp`W%Kaz)lP#dxg63<11>#IR&^i~SxqlM%ZSn+I*N($Ubp`=K_vt0PYvs{p`ks%KL^v9`5N>Bf`NC5a6lRR2jz2Pa; zP1mPe>pzaWWg;mDd~bScQ6!fYowx9HExAoRuTSgk)T}=fYKLx4poJC=Kx=4dbdLm9 z`SnB2*eo`ABEyVG*mLk~N;o9qE3h|nnXl9?-Hr8*5mT+Bt0tc&EF)>2VEQ00_7vxb z-W-IFY=4hfPa4p_x$Rn8-cMx+Hp_mQ9;5ZxgYRS@liX5BJkFLZ=)%M$s=P05vx3yY zpD>n7bvLyztdn5JFq|*Df1|fs|A=>q3&W7SqA!MUGN48kfBM;X$F<+{w6@qBek>ESZBCdTsK-!aPT|K|ze$abUaP&uxJW;k(9iG|EJ}Lw7=@H{TxfukC)zy#Yn(sx)iL`A;X{1uqV;uftY1)`x%~ z2jaJ4l_5FicYu4WTy3ROG^Rk7aRx@(?FtwVR3fu@R9~dAI zW&J#u$uLJGno}FS@!QeaR&`o>Wupz{gbNyD`$%!==cDWJBkTm*HS?nvhj$XM>~WW5 zeHKW8n40L#?t`|>W;td|da*1SVHOCO5?w)G{yCL)JxEv#OD4IKLZv(aERz`raP|?O-TPt91I_`x&`782 z#iJzKm)8kg^lxg}g70Lca5-$7&Loo*Rgii0v~B_{3>j5-4p6F%($ZOTk=)N_8^rLK z^O8Co&@usUNFsOUeJg5!iNqsy(syOppl5)doRh}y`Cu(o$(%1ujgoK?S2z*UJC?#s zecod0&Lx$=dIDa;6nByoPI=5%WkD;ooRA7syR!`kxW-xqj_wL zUW^C=A9=iI)qmOW`tzIr{uvlH0|S3|%&PC!zI=&eu(MU6#?#<72*6=wL6cc3FY;j) z%ooNM@QA>bYIPb7Ok>>9!~Z^w7MiNypLKG+2_?DU^s4?z>T+Ed@WE{E{+Q)wk>C;k z!1>wUj>FrUJ8Oi3HjnEuo9l%W6A0#Bb4*wW0-PY^Ghf1eKgIa;mj^Fk8Gjx(vH9Qq zmnE)pVKhvOI*niZf0y7DjDUXr$REr#IjSgDm@hKMIMsNdF@WadV?1smYY$m%yhJaz zTIb$$_w>~5w3P!uDP2q6zW0#;@ta}q@0LAjbO0Vp9*tgGk(#gAE6%OpHLpUp5Z>SK zZ(8=%w(A}KA-E=gR^NAi`4v2w&JU;(&hbB#4-l7@)w$Gunwex9?{}8=E5IozA!AlC zLK;yKXZ@?VVxCy~U%uTchm47%bXIznO;(1D%vI&bC?P3%xDPlkFOYdwY@3%SYp~>R z9~KIlrW%e+tW!ZieC;~vcO<<3w9cQ|v^OkH?Dyy=n9SIQ|3&&c6|l;HFS~H${rM@w z?^IiIgT4k_zZC?%Ks7Fd^;chv8m;`JrnCJ&?~SH$n3W})Po@*_*v4L{F)6UcPtyFd zDU^jOYYzdK-v|;8YR3YZ9>7!7uJ0%DJ?=kE$gb zz$O;gt=75?xy}u3n~tb6&o@WByMmYxJ9uqR#C+2Q@J3dPCB>~jgL%VkR$UBSqIlz@ zfYsK;5=~*my?|e=7Bh497!k%CCb*ncQR09Nlz^>#5hO5Qs+G^|wP?3w;xnUh7-bWV zNkxc>Tj#P4*{8X0&HCL>=dLU6ay*jxG_6y44$aa?K;>Q-xW8v< zqZyfO>%@_0blL)BB(Tm=xREJK85MAapeUyfCHr{o@_8H`O&!`w2>wL4r2Ls@VJI)) z!}vsieQv&D$KA@4TI{DUoyH-d-0#Xiag-eqHC^n^wz>)^%$RYw9fc%}zWsHfO?BNn zf^#o&+8aM#&lcvnOxLT_>*V)&>Feqi9%ubD5`z1yfEV+kEQN(Zx8-YSp}mtTfTFAl z$Gw129a1e_{LdZ_?GrBRBA?ID+pkHQ08qcAjnY1oiD&I$PfV0cdEV-$n4|Gibl7X% z-6XK|Tpo8F_P94))EiIC9v*#;?R(GGbE(S7_kN61bPo>?5=Uk=>jaO=-9FtUE}7Q^ zZOZ^HU2l410&A;_LXc3H{sH>W8Ltr%KL&0s8y-EBOW_iQ*&KY&(xAurc9nmp#QnD7 zBUmCRfFq&Ku3kb*g|749*>Mmu8Fm}AaT~cvT<7!1Y|Pv{RgPyPWth>Pk~T@lzZ>4` z!KK_#d4MFIo*YDuoaH&GFUdv;q)Ez0fCN~LD5y0O`9NH~EF7GnT2oXu{bN+dKV+r{00m=1eL z$VmnskKgOhT0S1nNXYAncw}Y_haJ5t_mNWf=aR{Pg0FqTv>q=w^ja;vCdW_!jLo3W zPNG}n(jJEPcNyS42UPf1td6A!oYE^zGTy7uo-^k??Z{-=5+0J zPBdKjYm1wIZ9nu?KnDf|1;tRn^8tpiX$0_X)Pl-xh0lS^*{&sZqy{5ua1wnm=@-7Y zI$1L#d2d5vK3B>Q=$#<_Lo$h!+~3A6vB|vws*mxroPS&wvf`>=qserA-4;ak46Zr3{*O{4lF!S+pmNeKQ27vjNAqG zs@yAo!U(=e?1T5bIsb`=PC<$Mmq#srX2Mz-wjo-(7|wJe{eAGmFphIE6zZ{9zW8zZ z^?Fbz;&?2UEbggH5Rv6X1dAF-vsCJ3eEO}@1DHwxyPv}(+gA4($ZrkvndpwEvQZ0H ziKMo=UJfexj`U4u(Ia=3>gsmA8Ln+!`(2nLJ4*YGARGf8@zMBxH?3PULX! zP~TjYX^c=PHA7(Ys?J}ZOb%tn5B;=XlaEg#?cX`=ydyF>byM-e$s;;gbIwEG!Rf;CRc;KIV1nSFE0BsOz%FZ3xkND78|H24+2FN4$>zq> zsXQ5GHW~G+`U$57zAf0F!6BNM4&MQUj>>8bem#xeG)#y|B;)Px8cCjDBA=6(x4u98 zOEba@lC?GN{5i*$pPqU!<8l~F>OO-tid~4X+>PFxCz;VA5^5Bg)-Z=v3JeTy)D>SR zylV{-$`-7wD>-#M*}Db^S_z+mJg2(efDM(u*xOBBPhlfQC%<1)u>b;b0x-4frC)4` zq*`#*?*7c~bG5f5)`}&Mi8wP6P@M~Us`sZY#QS`3XRuA>1=yr|jTb2OR*Q4%<$HkW zmHaDzMxu&IvKRK=bSGq~UV1QrMt%1#Uy&2=;EhASvYO3Ri6KQ^vIF`}e{V&xXm#Qn zOQ(tCE)AuS5W_T5=%&H`y;6b{u~8Go9U|Z-Ga19iKMX=5>nZ#wKO++gMKRkJA%6)D zMkZQ-)dtQeu%Qw>*#9oU+IA7)-3?4Ll!VFcpRuG&>-r6WZH~I(jSfd~i#DIvmIpCm zZ)H9GHirm8rZNMx48Wa`nQkB`b-_45~MPUBvZ;rWh>`G zAq(TK<_jHe74(`)eITgC$Lot*A5<=pWcTr~{mEpJCInMC?nd2|6^sVBbt7;}>n6^) zL5bV7(O`i3+S0&h;%E(e;tTTm@5-SfW$TCC;Y5uQA6iPyWSE-_zfI@m$?RPuEadi< zc`IQsAI)U(UzI0PQT<^ZO)HQt=j}VAIDYtX27MaiB>CpIuY})l(S4NmYudGUET|$%b4l|mNix`_1 zBA3al752GGrBZKyJk3=D2KhB}DRQ7{Z7qpJ0zso(`e9}FTb1&lKGOldZc#{$6}Us8 zG3$xBeMq3k?m8xWzxBMGrbW)q(VCYs z6OyV-VS)Cr^>54Hp8_yHu@zaazMfxHm@HUwSxktWlnRVlZ6>7jaxBg#@eWmOjO0?k zj%)<)|1{-1^HTZoxm)-7$#EM_zlq{iwPFQ*vuszvcH)V`vm(S=d|1pK6rqaxE> zwf@cx$nw;uxua%9oP)HxnSCO2>0tAVE zO}AYKA|zG6$JL7ix-|?Y{lI)cD6;EWO#ym9gDu;QB3)eD1($iiXu@kVw3+`K|3q2Rpqp}k2YjG1d;R*40s@Nf=38Ecd~6NWiv_E;!0nDn z{48cNQzgtL*h*<-b;->duEIXFjNA>*X>wBmCYaklFMy+B|KlG(FM|u;2dP)+eE-U7 zp|gqpC9!ZU#^rm=!2EG#)=c3&BXUxJ(hhimu^7km_O2pT2y^%8bgM0Qas#;<3O+jT zpwzTQwPh;*NPUA^o;w>{U7(5L0Q@YAtHe&3Tylru*Y zBa!!V;{Cf?fB}Kyfm920-2XRI&$pZ8k{2lgx=-yw8gV%bwh$-C+`LKw9X~-F1#ntvlAyK5r?AWSw8G?XtWz>tTR-in9`=>BoYp@)LkpB}6jr|Z!ydt^ z@sF<-x{VkCkArjnOd#q~yx6TRZPh}xBN*uB7|1f(3;}T8bbj}_%ZGaDLwREEDyv$L_3MBIZ3H|R=l`$<{ZLd7**hU56E`S?G)WCQPJPj?r{ z0bJ{sVpzCMAmSW_$EQPpo=B&C|GeY;p|{DWSFC(-k}j2c{wv-;*;BRTS~8SChMV9II`Jd#wi{qu=K%~ei)9G^ECB|4E_c?a6^4*qTsTScij5`;iw#?Wnd}AWxC`H zn|KAPR#Rng;9suYDai3Ikwm3^(}==c*$SN+qq~fA{Ue1OZmtw+>eQdN&Qn-5yaYb+ z8LQf(o;H&5?u;~b1(K;3;1;D6rqh`08O(gvetWl#(0dy9 z*cZCbTq)cP(ED795@{^Fj2GV(+<)1`ewvkHlhD{144u!8xDK^hbSG+`O0E!o<8eB6 zJk-79eu^jZyQtPlO&ZS8KH=_Xjh^sIIcHo8Mpkf z&!(n3(%Ihoqoo8yH68Lf-V}uFJn^s82$B*hW#2u&8?NL;bEj@g(qAieoCf)q2tN6+#)kOUJ29qk|61#QO-pb@j8MXM(geaY z-I6;~XJkt&)y0Iid7H0s%Pl`j>mR$_SPVD06*L}Tn@&BP4vPeQfDv1?^%k|$1vY9J zg{85&VuigWMv}9&=EH7gLNKrD$m`>5*Fikq2kA{zS2!Hf!N`0jV%hx3!!|5C zgB*9P$38n0j2^>XE!|`40_&8F3(s|*2j(nTs+C)Gz9ZjOSLNh7n6z7#QY*u)%=)m^ z5tWd(F`_n02Sfykkaf4D9?TA+hm-!?s15o5(W$*AK zxZfNzavIq&oL8vJdhEAYsryDu{cyfs<2-u8lpCCb{~Z_KvWVIB(#J6egYk<#vy=Axr8z5+?RrQ-H=leJ?Y96dL zWXJet=_lpf{mxiS3eel?FoV(9b}nsfe1tp<-#aJ}XZgCvhxf>?T9gHJ9!S#S{IKJK z0!oUBi!AnI$aOd{=xn7;IVO)2{^nVx;vZ9nwLF}?V#}0ang9Co!~LQEd8soif@3Rw zG4IyO7IuhPTKt)ee+Fp~vRe6)*^YyKCXjar(OMsPU#keYYjHVm_F5K53)WX;x# zXV8~R69SaoktBv%ps<*bbWumlOJ>ZZQ%zh!&6_%{TsVP9z$9gg6FkDy)AHWnrPznB z90%LWu@ok; z<7R%Xmi*3dF`K9OB&688dwjxX<*Z%zY` zvrKVpNqO>DjT~j-CFfj`e@tEag=ie{Bg2vj2()g(Y8^$R@7&N^9QIETG3qaR2dAw3 zWJV%-GaF-5j5Lk{4MkRBG*)FBce=kYoM$Ql$I{xo*mk8tdTNl8;rv4LK7c+)#yKi1?!c;^~ln#yHw3aHK#NUcf& zT1p#<9$6y?sKg@T_@h+{uOQwrRcmfJo18^GJQLgF^5H!R5-AF7_MZcR;#qS_P8fxQ zOwNtx&B^pA2TEo;zxQpmj_T!l;jpTil7c%I58ePQADo*f__%bCVPnl_uk)$SFt6?L zBdoYg=_3{28?*p!$X#ejiE_oSlqJn1k@FucUW5jDkK+7SMU^u%CX=B{U`}PJ72Nga zFaB`J!Y`8T+T@z`{-}nKv#QdI?5~xd`wywTT}R=}GADx_HV<>#wI(XM8O0_E!Q({a zy{HXrk!FYcR8}##K@yfjqwr6dSS(qv$Va)Gu1n zEV=A#_lh5-Ue45`ki%s^6MI?@Ii+$~?VWn!JevhNS-A)A5INh*nSgqi{4 z&IqjPD16n?T`Tw0q{{VVR#WyK_0pVKD?@kgg}}4f($VNa`JEO9&6XUEY9XLF#*#1r zlWDCS=_E%j-Utt!vPhnD?m{OY%~ zkq|02U}SGNO8^C5wJxzK6evk8cDyo_7-SQtc51wZbzrKj3z*5o$E9V9?hpM%>ZPiZ zAa`0&EnR@F6qpt*55F5#$8|-qoXLA%_*s$`?es|F8yIpddr_z)BJF$}(9msnK|^*lY0-NzRn>B4SdQWb3!Cw5G(qxqF0 zKa1TzJC4>V+zCFNZPz~J^8}ac)gq6Uox;xI6R=ryxbJe$C&rE#00i$Qk9+(~(&_tX zLlNAmf>q)22=o%|Mgc80d+{HB!_WASPP8WzQhve5T9Co1Jy^8*nq9epE|C?o+k zQQ?)Be0b{I9hJ8jC6T-;+;udlJva=(E%WktOfRd5iJT3H!!qCBR4PT(j%53MtN;^HA#-0__mTkXj{N%`ZKs5h z1Z-NZoO>m$e-Uq7&kXsZO^V;XQ6uQ$)p+~DJpI>PY*86L)4%v$9w{Mhf<~FhmZAZc z!8GU|UVZGz80>9#xR^`0&A*N?KSM%9gvX}o>2`gXCU{JxW^q~Q_HyKM8CGE&tQL6S zxP#q^<4TE&zt}m8pP)-zqn8N41bthz7H~G7E#`5M<;u6ySjUa>=sBD&*lldk_x`FF z%!U>e?eGyuS6$@Q_Ms~l7MH?_VzEgGb>;BYTdEG?Dnd+*tagu>2M{~#Oc(C(6cgd0(mtUUI^Cja-_6w0c zK6ZH^YVgrsdH*}=5Z~@!f6p*v22{eHE}mh32XjkH%9SX?+ts}5`35}Fs_zJcv|j5J z^FDzepTU9}D~cLZR-s6(H2EG2))$rtsG?hLXT`VDtIDO!HKnP-wbQ2Q^mu*A8;|tuUSR z#2o>mIq#{QLyo7(YY?re|( zU+_PE)8VBhR4;HUmQl0$LtfeL9-Lw^L=}4~FeLy4W$T%-g6w58dCxCDAvk-^kK=T; z+1>1MlLmzNIm6P9O}O;4D7&>iX7k`~!tII~zrW}Wjy_ulDY&W=qszhc@tCIL85NWg0h_8Zw&tCo!>Q8DJez1u3)bXi zX4aKA#3B$w6>n^AFFyM|^lLE?s4;97TF)7Y_*yEgj{G-KT!>1s;^@7kxMOBv0igxm=V_ z(^#@so6S$&E3X(RuJm~OlV0CYv1PLf%g@OXa7c|I&5#9!q9x~qF|f0Xf2QQ7NvhPC zZ?K_Z;^f|%KU8IM&XxXd@}arDkoAOnC&0QInSu9&lSkYa+yqR0%A~W(rjIT$^*ZGv zO!ft_laNFlN&W3%gjKuu)zvVOQ2hgF7_O%q>Su$0+_h}9g85~p1`lD?6fus05tm}1 z=~KcwPB?Qy{#7Sa90a z$85Mb!G!L@x|?IX9^d5m4hYn)w|g@5&7-2<>N_2pZ8N2NYAUvX+SOQMh&B3^8o`j(F2z~6lF1c>X_e3h}V0nHU^1M4$ z_u;M*#zYkXRm^$A^_KefwwiL?MmTk(*YXXn_M835$Z|Dz2`|L!%tHeaFZ4b)xTNZK6s zwGwGlsy2p!Qt-BRv%{zIu`=0Nq3|;4?P53V12R8NB|xb+p9Bg7E~=SLK%*cfrp=!ZP#C|4UD5nmFNQnvP^kPvIKvyQ8^vfzkW%OAerPA91=qmw`O(O`ucj25Ig9^ z{_>NDM-+th*v~Dd5j@@l)91kS)~AiD$B~S+{K@+<*>P?;VVoIjWUC^5ad!uk=$WAW zIL3L&1IQgmVq`k8yqZNSZix!H+u+YthA;nUiL>B#Jq8wDq?F^_;zKnK)u>NOFnMKZ z`y#&40bwVgVY2S|fb4AgLv;t6*ocb=K{yrOY<4GQM8zVQStalHH!mL7lRsobRT1+w z`!w~VWucU}I4`rg+Bh#JBbYxukE;Gc188CBBlUfSUGwrdD}Q7TfX(MEcBYqQXiW{C zV#-;ywi9>r%0jH%goE_14G3Yn1v`*SJpnj@vKGh<9Rhywppvo=g-a0*xYDGZ$Rs@<*q4e2Q0XxX_JhI{j-2dL_+#tv!a-Y*P;K<0+_m89LNvoO*l*X zi_wgyzS#T(_jd-mJNPSRFdn;Ux^mHd<9#tC9+0!GqcAmN@XS#)PVs zXqX{$WVL;t|0*F>?@&OS&SeqScTtSqYzU*A52roem#-dA{*?p1M>C{ZFj0f_AwHix zz$CWHlD0*3%08V!p8nCp1DEISa3aO5qf=>B7W#0`lTA(K=(~E@g7RiW zXdAEKU)4VNPw;ym)lY$+l_@7qeTF-IaDlr!{n9Ol2I_$-1^%L*kUOHU2N;<2I#nR( zMz)+^H#;K{&poD+Y^mC~&m+IJe`>AyBq{vXp{x2AAq@d9v!M^MW?qASH|rLQ3culh!~%dT;0O1;{Ux6OrzB5P7=ktr7tFQJ-^N1 zP{)(ReHHC+s4N4DcOO3EgN_4|)GG2l(k@nl(NXEt zhz4(U-BEL;D2Ym~-LhAt*c(mAuhi&cd~Vu>E(XwKmaB!e%hdxk>MAXnHI?~F=$Qmu z&5-bUtq;nYnZt6q2+Q3xKxJC>)Q_1wt{v{9`c7nB%7t?3MGA5;0BA}rzl5!awYYzp z-naNB8SnNDNLsCHn4OdWGRM9YR@aR1o&L(>hw1QDm3p2fN9yPXfrBpRILkg-V4Mrk)vXi(B8d;n( z1ZM_acg_XKTvtzAq;zrG;*6%QdmUxbhsu%6hI3ptKzK2a3uS(}g{XL^ryCiN$0Q@p zo!V@jK)u8++bDYoTOW!%-s+B~N6{G`5|V5}N_`Ui zitnn{tBo1ffE3GA`;OIuHR?A6>@f<$N2`)|$s(UJr_O=p?|fM#99;>I7RPehN}n2B z>Op`d;qS-a)G|<}*B&;45RC3qtYkSYO|Vpe9jxU4yWmKKn73%N(x$bG&uH&4mCgCc zaQPjpX_HschSadQU+iigRlZZm&!qswS>}bx&4Bwdb{lq9gpf=D5m17C@8uWyegx%< z#Q#YUh5tzqsu}+~L=cVf3gHt(nidDYd={iru+CU zo6ay@{a`FbAwR)4@cD(ySlsJHo`-c;4vof!v@3miRt4geOs@tYc(Uh6iOO2C=M!Tv zA5hWzt3;55hW^X1Zl|%?7#L!ry=gy(w}YzSP&?GDVFK=V7+Z%H`dVzjR;n|zbcu!m zrVo1+_bmO|9^;RrKF^`mw-jP`zl@{!2b>7gu*rFs`4C?WlHo9!@rn$3G~!P3Y0|qx zDl81;;e}QZa7;gbD}%Clul$gCN3B-&YxF?&V1k8rtAzi%SY)|EhqcS9HIY5ILXr>r zIlf4W6qyelFPPu3=$|_qrPaY$a^%H%2H+~rm1{N5%8t7L&N@mb2sDxUog)a#JivKr zwa(V`bp*C##pB z8->#@VivCUwkiD>9`%Y1@8@Iq$Q6x5?K2k|O}#t?;nb23U=rNcn|i9X_QKg6Ljo4X z>nZQ-NSIOo&nR`?+N68yp5)rD;D9&n}&|%Plsyi8kgFKEy3K@Ws3V6(@ywoYy zeU}nTko2)TK6fC$wu0Y9c}Rfcl0d(j`as5ge~Yb8*WpTQ{>8$`hYRT!w7)gUE6ZF0 zpTqd(qXl32rL5f91$DT`)l9o}F~53(=Om2F8vN>jH8T}UR2v?;IKnbI9R4IEm%|cU zsuHmc(s?=}yxozj5UOH1)!MZMWS4&BQqom+raz-p(tso7pZ4370q@H#5c<<1P z%wRZ5aD}nq-+Qz#oBBC;pMR{7hKESa0`swkLwc?nQ24a*Bl7U+)*fQ;Y>6$ffC_b7 z;Kfz1+}PSr5XM4?Bfb(z<;3-Ezqp@J5M3^=M`aox&?vx64Q)jb_G&>{J}?c z=WF@VLkK(o5lwkSrb9s)m>CZ7q5J}n!=8#fiVe{G;CqUk*m`4sVH5~52=2sa3`7tc znTdW@e0Nvod^wGh;lx>{SMC59G-H@!@i^G%;x0?VUvBNH(%O$Q{Vg4C7c!o1p^5{R z&!>}s{9?CWfZ-sr0MxSo2>Sat+QaR$5$2Lk-Ew+EtOGV%oYgb9^<|9xxG5X-12>dA zbSz8@e%oz!NS}Fq*gT#cD3ml-p;7Jb%SPqd7J~!ol3|A?hT`&BOKcRXCn_;DD)#T8 zd&4X}l=I~3i%S5n0ehg{Dp9ImLW7Z6cZ|~StnloJL-o&PXJxg0T=p#JJ~dKH@XKgZ zs0o@3=iVlxssNt!{!)i=^bt(Zo6 z5{5N|B1M?^6Ok|+2HK^ZD2qnw<#zL|AUa{1thI>TNwCMr|}k<*fd z62e}mU(Ue$i{7v#|G^q)2dUTp*QHk4vl1;OE}%Rzd=&5mzb6r$hT5n96hdkb-0-xM zQfxu0{$n60h^a`@4>>Xh%?$>D&XCaFiwas(!Yh@1RrNrlni2Fs$|m!La>(E&wvO)8 zt8>z4xm9wu0)5lxjrLvU&I~-q)|1~5*AdtNYBkEsnF>=PWFl_sw}fem-+^(n5zC-7 zR@5~F21F$}?~*p=Blp&D$)k#e^YXek&1#O$+PI@N_uGv3-#`otfjD){@3W}{-ga)} z%aJW}1^Io-sEQt@#j`BMGYSTSxyB@~SHHBq&a!_B*f`Re*i4Q&Ce8!)Ir!Gn#bP`= zv^~r>7d_P8Uh?liI|7-trLLuSo%;gkYR8buMV?BFcE4tU&iaAGcJaeXfydL8THeI8DIL)BM`jajMxf+6A|T`8u$`EY?@|Q=hGAJT@!umsCfM#s zS}2-SZY-^AJIaxJm~**6^y!To6y{M6D)%5@xAkzJI-L+syK`QAP|z6iZr9AEFq&I9 zHHM=c!fKwCADEd%N)c%{V>{3q_xoVzP-hM8YsQEMgxF3Z7D~dVheQMba>Tw_mha z(O){GILd^!J@Gnea;hp}LrEGMm9S5fx^0Os-`9UJiQyaE1QoJPwZ6nNB>C)O(YdrR zt*4lG`vsn_=pE@8&w^fKWb*|2bYG%4)J)C+ivS4oPf(4VHNYV?|mf(Ue?j!+)|_OL)9Mk*27SjHXhf zk2&1Fn`Df+zxXt4+@xinTW5{>i`e zUhm>RL`UoEaAhmJ!uQJxWZOF~EdO0g7cYzb&An6aaoT}zIs=`aa}t@1k_4qrrflX( zV@g5)rM22Fz6pyX9Lj?(w6#x@XqZ9bS~9;jHhC(3DfT}or9Oind<8ro2m9N9FMN&h z{&=TQ&ZWtAB%jVH3S0rh^A}FDSEBjxO|_KfXpIQ0P8P~-GR?EDdiT`ICr;hWN?%(q zy$w>Oc$}@FYmV|Q26DIp*Ew?M>5*HdYOk*kJeO(KL_BV9;JN%51GG)5m}l_gG~IO`@cDP* z>^h$0XxK)^Pb*QJE`@hv1-Q7Lt_QQ&w)0)i>D}(8KW8jXlhr1Pp3fIfB0;?&pZ4AN z=NnZFF=mu!ALi9{D=rUL8|)VI?Ut$pUxwkZ#G>&FhDJ)}t)hseZKvBLbH$LD&j(DR zeB6_yWq(R2CIX?mB{A+#KQg^exMppOt}m>WbC;#{OJ&yU9#={kJiNZF@3D5SHrRZZ z%)kGWWUJL$tXV5Y{`GDrys}N;5y@O0c^!R4^pzl9vzqDIL}R1P-6<;#bv@==Z?! zW+$AX-BL}@OA+Gsja_~#ly=Qc@%9@PA4ou*&oB5~m>D7K{LS1rsv)_R)iJ=PbkXxm}-beebE z>B~xGv-0Z4s_0&1qS)OTSq2~IHSEt`Nc4zyxuDN@Y#Ix}e@(d%EDtVoqGCJ>XBc00 z2OZXs!56%iXDD!9WFL^}r!*=b>o*du_ z{Qh;W%wiXRzI3(ZwDn%wuI!MyHSow@Wrbr{7u0cpwP&)Pm!|Y?fg96=0v{hIo5{P5#)*6K z@@5RahTE0D#Xz^W%0svO4V6Jz+j>JS&ZleY zHRPzigOwJL!>!G+cy`Ce^G=^%E2vD7;e)O6KDRyhbUShrip7W!xrN&{YJVTy?7D{* zNWw6YB?Tr!vfbNCMyIU|C|x`)H8U(pMVj(OEZPhVV$-J)r(0n)zK?pSM~BB5YB%X6 zHh)W7nO6z=>En^E@4TFM_k87BiL*CF6EE;|+s6lT&!wQCW&eD9zkP{MSZSL=n)X1R z@-_0gdlWOW@xzfb$xE7%LH#K9visIm**p&>o#Uk4!qQZ#-)|hm^d-{l-)X7&&(3mI zJhSOCW-HltYSy~o1$mo$QGVC6uyM~$?RvW084VI5n2s^ry-W)33BFPD?1tnHZ#!oB z9)9o(R5tU)an;3UCKH+8!)ZJfKo81tFu^8(!0WH)uI%+8?KdL`jrSz~TnO1V^|_5* z4&}~)l2m>r4IqfI$RArK5%X0(XjDIwxYcczd#AG7|;%Y8Ph#Zr<#3zTUM)Y0RW0S9J`7#=k1dG@{6800*SD^7(`Hls-lg`)LKZL=ITy2^~fMSeHehGwLtAJ>`HGwC00$A{y(MxjN+_dwPQu)RssTzqIgNG&~? zFE5XoOawLffC1XWZ1Osrc`OU%4ETURwn)r=O1BlPv$1dFeafCRvxcSa)IPR9d>29e z@5Ziuzd)SWTMJHhx(;$#f0&iUezld(bvyP=2KKcbr?P#(9sUQ`a#Nt|Koi-QKtJrb(#kl zT%-s*PK$cp!*$-JNRUKrTa_vna`6Zl3E^NL6Qki1-9tk4srX!e^8%)I+7sh!KpG=P zLEDl7*|i-##$cv)W|iut_g;NV36#I5J$R1K3%YHur=K_I;je%N;n8&3KfuL*q@#30sV+YgA~6R)oc{JyikjT~ zT_w8jcAmz=ewYYlTW&f%st~4fM!!i#yOK${eCb&K@pz8O$pIrYfuB~FhN4x_|;Tvp6TN4cX?X9>4B(TX9t2TwEIV0Y#o|K)AU7YZ(^wViMR+nV#zwAk;89je83ZS1-UKSiW?Mc3zOuKCC%9_PgrB#y`txxX(F7&@$7$0)OX90cAT9hGJTWml+P`uhBzF)&J1N*+i4`MThI z$^js*g$)sAbXv`ezc=}b;i^@-CF5zZp>N|hnYg#X=L@+Gx;cXVw|yN;xthIFg@Z}T znWqe8*_!S$&~KttVq=?IWic*KomSdQwm(<$Cb*%}Qg4@iWKuLxafFGX$^<)|*)f+S zd+dF6$jEJpj7FUz6LnHMeT7zu?mDx4gnaZ`lQoh_wN>~C4RrZ=xaUruj!A2nfIxkz z0bGSwBB$SaKIxq_-}!voY-WFU19CWWz7hAX!jGqeyjr4wsEbw?J^?8>oTOn3xv7r< zS_@KBXMzWmEx*GHvV0u&56H1(%ZARdOgjl)z}nH~eQQF*ni>|L=5{(QcFpQTe?|Ji zvsW0fP+s@kLRB%69V0u+I<5ysfzw;C+KHw?d%AXl+Gl)lcM~S8g5y|{zE5s*YA}+3 zF$&wYRT7I@ppW618+Gy10s{(%>|rX2RCMB^U9Ow@Un?fGz2@Ge%j4lWvNN=qpkYGg}48xRPEA!O}LD43wEoX z4|mZSlVhSf#B*14FgUO2ki_$0 zIVpbp)mXM&JwxxP&FKMUI=Q7fH{nSeM09O zIr`^QPIA52LE%bVuEQMtpu}oACAxo+5&OW~4(oRcnFt#OFNBUKJTzKtzck}#K6OE| zjRz|U+h!__-G|REw>`Yu%r<)ORcR86-zA*rbBV7|C6ff!ZM@i@W`+7jnYxy=6+xiQ z_^30YSM0ynUZHRHGj3q<=?`sABwn0CBrYdDCIX~`-r!e%lzf4JeI>U7dBkJ5f>?@8 z3m0+kp$^U~DDeMpTcbNvpy+ao%(oV-&Xa(cSK3!}TU-c!FA_Cw%usy$#y6I`W|Wg z2EDBctT4q>xX)eV&fP3aR?rqIv@5G-*Pd?q^ef{u=LaVqq^=!8UJDPJ>)m7H;#k6% zTQ;SM#oe-a>@xk(Q=(*yqHuE>WBG`Z`X+Q+A1-9=UYwWrbmoXm1-=3P^wFBhY}j0) zB<1eQ1DEjtZFwDDdZ=6m_fkK-F1<6#7mLyYrP)ns@S3A5AoImV6KS`Z91BC;$C4_v zK4W08iKf$S{s2A?v!_9)z&UJ3r!sD)ckweyg=>Y%%EbM7O=kbkkF1LmgvG%jpiTb<@2IdhOu`t}{4>+TcXVFd}3O#&XzMA;%eT}gb??Tkl0{Jv|k zYNMJe0#?Yg*FmZ#^vu!rM6+|v*`{QXT79mWIoD~eSTpKoFyC9#=}D2Kpu4e==z3P) z_@I(wJu`kg(JTR?uVgnda`#i3ULLCCMoagg5>1(u%ZW3ud9q!aHb7M`*+W#;FZOW0$DZ!)G)q%GnN?6#ZPO8pKnaZ zn|&617xgz$S*y~>CDi3Vt&$93mR^5gomxOz1W!rOUVH{7C04EsFOf;!j)8Jay7s+@ zSJnoH$=rYw)Z6vga1XpGK!iNA`E^m(RrWHiLLCRmoU0?x*mxIaxWU=VBThkAp5jP) zxMNQdj3A1`|G4#Ca5*M+N6h2L)5GfX!SF6vvz2h}l_ygg7KFoQA60PpH2GaVg`d@R z&3$uUm%(bKNf0RWQL9iE4sNOZ%d}o?vY(yF2gzkUiMKYCuLpOH-2E$QAm^r5r#IZm z%YyQ9iKMwG{tyFC>Oxz_+c}g9K0y)$&9lRq4{j^x#BHi`1sb^rei?->Gy+Z}N<{vp$?EhK*8lTZPXX{2zO79TnHI#Em8-cnBnr5FA3VV8PurxD%Y< z?h+gV1Pu~g24`@0hJhrw+u$199R}yy=bU@b$(M7_{p+pu-g@h1v1Scq@9ygA>gww1 zs$cmgw@E)S@JgtqZB198mPGzMX%=*)pgUJCPkJ{GFMQX-T;sY{;@PKW@5- z!EsV;sr__oC<9X@FuJIs99b-5Y`mS@cDzP0h-XN4n*FG75^aZ@rU-1CwmqxG zB=$42;mzMPO!-#zFIP4l_m{%t>X^+f?D$YKlQ;VF-%CFzQ#zv&$^>n0KlYq&0V91J zwe5eDQywL^Ao|H&h4zC`oUkS+V&vHpgD+G^PAqZLW-wbC_=n39JCu`3oqt7l7l!`$c^94jf!skqCd~g)w)OT#s^0@BIPAW`29y*cj z(8(QW9Z5l?5;Sj5dJ&;$*g?!}Py@7{r9K3zXG(ROopz6*?Ei zgQFJJ26GJnF|M-&X~|xK z>U1IJSp$bu$op#P<98mbHPLAXiapmGt(fy3`*XDq^=zKTTtrKxpRcUEYIV`0;J?^t zm5b=GuX>9+!T0p+pk?1<@z!IvnK;t2ZtH2ft1kM@doIUuD~!)(6Fk_eMQUmMr=}1S zpkNC|N~$TYwZW=h*lu{ICf8!xRj2nAbj||1aSZU9+-lZXY*_*x-7u4ZRJO~N#AodO zZ?)aT65tERgdm4*z_DR#2e(Qp9iCZVj{L-Rm28&aI`4JY?&q(4Hg;f4;(g#91OD94 zBk3iZ_F)UJ{i$|kQoC(4vE!{9eQL@{N7F@owJD2^w^O$6Y=g3uc4}G}Ow!E6l5;_d z+h7W9Oxt4hD(l_zfpo+BBwp7A;qydwXS*dWKTa{*D~){~6EKY|lU<%Q9Jb@$nsS(* z)W(-EINeQF;Ca3^6OAVGUtr<_3QWxBOkM1GF*!fGz4_`@qFJMYdD->=`8nOYlkU81 zK5utSuRBn$$Qe#1W1geh5#5X@CvWH2ZpHD}Oui5aOhSG&Qd{kc^VwW9+;Z|W6O|w! zW^PB8yK?z!^hzuYjbbV6c~{eWg}&TuH6ir$#AH9s;e`M^7Z)B>8Y&Xg%M`%C|p+$8py!aOQ=&kJ;lQF0Tm)=)NczPRlP zx?OeD24Y!~SL0>S?=fy`L^XXYf_Ov>8<`p5k5~3DEiMeT;usa0CDUS;sp749SiQD0 z{R_y#Y0jPN&$XFwW4rb0oSHwnIml|I9pL~c#1z$i^S5S#MyMU)YB6Fj6Y^Qo%F)acDjuvG`bC! zdXZl&lx3YO`nfci8L<1vP?9&N%yG(S1a5ZbaV6jv)~=}$F~%wbEqf4 z$6G~rrv7-fecWlEU=uvsg?kgP9Tb4vkI$$3(mps^8Bf`bwzUhY>t%3c<$I@n6@azP zaC+#fNOy@~0e9bt4x*GxT{%?lGSnl1WIt^rOt$W75U;2U2fI0%9P^b}dd=1FEx6eR z_cAo14f4ak^h&{j#V-ZvG@GlcpzKB1;!-ZO^M+o(CNmv)(NCO{u6AImA z)MT~Nw|j$Pfe+sa!*)t*y+40i+1Ey}usIu9+Ib>@kn?!JbvNo(h$5&kn)T-TKie4_* z;xduIbn4j?EyAeh!x}AvMILNXd;*tUHxxUS&w<0i13E(WRZoMC4{-+OtiG!YJcYhI z!|`l5JdZkYxcGiSwwa3`-S8IPl6Jcg8>(v!a3Y0YPpd--6Kj(8{4 zpam1opYhqdzDH=x=ZZkk7d)3$`8t+#g@K!)XXo~jRy28PCa{toDB(K( zXVomAWVVpCspXb4ivm0ILBuWS8@?)jDf!tfr08*Bdz(Ty!0 zvr|B?dt_K6xJB+}ZkZBNsn^mBXz{-3^^O>M-nHfI;xoHfSc3QbHn8domA=^%JPneW zagmrI^lJ;i!B8S&b}QZ0uxtp9pmktKYuBS4;Rd^I49Ur=uN&O7DwsMGa&gs-g09YX zl_x6N+H%Mx9+L>z3q##bCTkE-hXQ}RwnKS15Py&4OH$7kouO;Y}BpMa0Mv%CQ?4xX6z^4;wPNns2vy8JkZk69BIz4qxc)9*=FK zQ=Q6*u*hV=s1le>(e?Q%s^cT_zA;+W$`!!-;k_*DRW&YHR`AJY+chj~WyZF7esigp zR~$jx!J?Qel3c36C@i%dH{ECLkSe{qnjeDz=5cs&XPiu*{Rm&ncBq$;_d3{zDBOMF z1Jp62JRA*k$sJ?Q6+Y+M*wkWm5&HCkc7%RicUH^R9-%sI|G!ij)zp>9@El}43A_a9b)>ktq}-c3gO*a#@1NdTX{brkqt-7LLiK|mqJ;`U3;q~*4vNby_d zC6=o)xW1fGiA=fHDeyyYKKHCfoiwU0!(a7Dd{YXPC)>j#_Sq2t!24bG_O-LW3tX7J z`|;5)V)F;xXs1(RQC{s_H+IXN{=rOgZbv8n>y&#`o&svB&I@95oS&NDweCUnwhpBi zgCg(+Pe-*&K~8j3$3~@gwB-)(Ou5&(5k;uZ&6i76OYP9r!%E1MlVRC5mE5`7lYSY; z*Z%ozU6ay`{0WLy9SOpogW01#i_Q02?#`B>@cG@F;7}{Rqk{+Y(rT-0gE4FEhiUyb zsyQnKRKyiwdm%uqST$|ywOVB-hLmvC&h^n~ThBAEWMaW7?;AIz1cn3?Co_yP`vvF& zeiAe~JH4m&zOxh8HI}Jdw0?TL=QC5Xm-5d49>SEi z;4#vaI!xINAv42iThTOIzh4aJbZyw_Bah3@&}KfBQ5#PTT`p z^w(p`Ro)Y&I6Ra9BPsHubtIZ< zO(PKynNeHZX6F*(+<9WD)v{z7m{)t_he-*naiYxUltxF+E6a|kQHD>C82oj;fJ=QJ zyM@)pw24`dK^@gXl{5~Y=Bx4WakI1>0I00#>@sB`GJPYBih`@X^wFJGH!(Lg>StL2 z>uLFx+sm0Qd5OF0V_V{06|>qwS?Ec`@oHB7M69mmcrmC&|64r$-A3+Pn%+2itz4;9 z05u~SQ$}`t>rilywr0XKTjKU~A{6t}{wY%{%EXjkqxA4gd!xVPw=e8r?096}F8Ou<@ueI8H z#q?lnsu7EbTes2S)FL4}5}!+ke%~c`dQ`ncw}gO^ouO3t;^_VvT4j496)RF>X*&>U z@3K2zqUO<$R8W+e(D@?qYA?EcZSh-q5Zrhds!r98-X+l$SHr)~Lp^FdhO@-jmW$@4gh$123gHN6ZKO&XA6-=eprE=N&fjC~`j;sO&vKZeeX)d~#|7OTft&#fry84m!@hsik zvl0VT6IPcR0&oh>b=lH~QS&x-NL!MfhMG1Um|)s1Z+8Jp~^B zO`ZMnQAsI?nOWRWf%_Z%zNYsvMqPzc;zv#UT&4hrWctMXkQObidU2xDMuxB`1K!S3 ziI;~Z9VbK*;crd-F-F{sAce(GvA6!@K-Fu~)s{^rYT<%GCqx_CN8tEF>$a0`Q5=S8HK~s$hz>Oa^nBo6ao$@Dewa! z$71!<^GU*~uB1ls>%!_vVlfSRynD(G)EWgc4S;mCYV&2Vc11;ZcefZ&TurU|U3=&% zt!g0-UR>_;pNIFSNQhS5yPs*++?YxLj1!9t!R=^e_?_J&WL&ZYe~bUb86%PVYgj#> za6!uAf0u#ZXW^yF;&}-66HS)Fz^_~kfYcJU_^OcnIWSTwL?C$mNenrqlzhaf@L!FP ziul1|m#57E&z`&s$3{6muJoa6gYBVFn{j<+SI+Ry=Ia~Q_z2$mAWyB=w>fX%c zSc(Ym>-|ts#9+_znEznTLkZITZt<1HSTP!uhpJy!*PJvSZDqbJEvHMhng_6shrqA$ zZut5z{~+b}ccz2{iB=;C-wr1wGq!qz99jdKyjQ7M5S~zAeIiKoRS?y&e+}3Tz_WsO z50BRSpQV1JM)cE1ub)k22>ZsbX%v?b7(*Y$K~L&*@&XuXV=N5mPr6B+5IVmoW4eEt{)aEp@8?&!LW+g{qYHXFT682b;20q&OXD61gXQr z?{*JHHF3BSQj-7G2dm#~1sD2yUW~#JFAeoOghqO2M{em}et6+k0}m0i)Os(0`Wt?0 zSXfTXprlFc=hHvf`up3WLB7I5S7#*S4I7r_&5y1;lvJhGpn3N8KJb?U2+^b&TIw8j z`IZhHBrBQxFILI_5K+O&hf=tq7&8@|SP1-RADZa-N>3`jI#O%J%U6j;dp0<%!bm!T zFsaf-)}>XS{H2x-)E5t;SD;ss8%1T!_qHv|TOcXdaA&D5Z0wjCuPJoDDvFF0wK|&@ z5psgmkGcr|P(prHq!|&otD%>3Ew^+ku_7h}_vfM*=KT8#OoKewvK`^8OY6P3>Wv?o zZnI=%xTR#eaG8G6AE}NA_%wS%KMXz2h{h9iy-vq)^}R3#rZw^-+k45%s>o>M!P_y!%Z9 z6wq|WC@TR=BMiwrk@H!BZQT|Djy`Lb+U~J{%iK|aM|QQh)|02vR2k7rFb-;~Vbc3p zSfNc2UwpFP=N`+-&yc3Gjzn_Ghnj5?QJEMa2?b{$UD|Q|10l`8a@w#{*`>!Gv5>Z! zMOVEJzWDOulbf5J$`G+X#ryul0Uf_oCMLw?V~hC=x=5V$!`X>l-lMg_nR(snnPoM# zmv%0Qd*<5O$4G&uIh-EghXHhmsDHelr7bACdj%X`onDyK3AkaxRBFtdqelFbj`DOUWY)kz%? z4IJ85LO&}mz!BV*m(W)R5;#;Iq|wr`+E3jkSz^*nxvcE_cc0*e&U(C@wgle_jx8_a zQ?6L+)C?J)q6cx|7&!qd>q@8N;twwUsmcFXqW@YowYXhLyNLJxnv(zUElbw6ee;(x{_`6tX&c{v?BidegCg1h>>$)FUsH+y6vu!6*H0t~3I==p+2(&B1}oSB z*sm46{kZskn!dm7>b|~M@c+>IUj$;UB0LPpx<+tx|4H@yM906Lyid0G-v%v6+JlIK zB6fkecJen8ejWva@a%*C){kH;Iv~p#R20EUYEs|1?8?{_TH)^Cv6*Hf#SAod2?}{wFy9 zUlp87Q^B}@V*&iCV*a1gK3D`?>vdMA<6Q-h*o1!V=4ZM2PN~o$o)kqKMl4LWnrru~ zqWgK(E$*PV0rjPqb|yaJ|5xRQ5+LIXG?$&L|KFM;Wqt@K{toAi|9o8fR}X?+z*B+Y z@gIM(IR7@azyS@=+ISOwn*Wt9GHl=}W=*tzI!^sQ*q0)}UTvg}Y~lCcG&e9pUxh9+ znioIw@@HoK#`EAuz(yNwPn3`N)6Vd>O$>_}c)=Hk& zft5{uFO@m;bAQqq_VW6LnB5r&GJ+sXAuak=P;%YjS~LQNbL0Awi{f;>^{@YVW3?+qrG`Zd*lOQ;+PgUfvC-jV-p`cPg6~f|)+>CQ zb#v%k>w6ZXTv1i65Ov{Isx$Lw3t~7SWKE;`lHY%Kecr+u#&jqqW~rnUNy7ET^9@ad zN(jO#HX7op(PLt6mxGK;L?U(bi=%d$MVvecxq9r$3v{$6f&WO5C|J;9>u@D@St25r zm_M}`zhkurk0hOk-)FCUjQwd)xK^FHt-;8!f!NX707%-eGCvd{aQA!K=La-qrVR0= znx)!Iq2nvv*pU6N?=g1Na)pQQS;l@im;}IEaU7MX^Yw2zmjv&-SMvPhtZ*X2ic8ez zc`GcIDVag2N)~Rrtx!?Z+fW_i(e<~`%N}XC~h!vTOp4XfA zST_)DP4$DkPBQ|HwwJ#QYrfsLCNZ=%#csdYj^F=}I7iDVo&ut-Of^FG+ zgYqb&$I46H{9SgWUcX3}sCq3n<|*`}Au-w&M@LjgYHl3=o&qk10^ zj^^C?^fTC1E<+;bh66+slJ=thl}KH>KT-RC&)pO13~^gFucF@@&DVX181R^wx3D|* zXzg>ht-=ciPfpBC^umhe2twI@VX91Ei3CODK(Sf#4LG;^Dtc683EhrF|K&pe z#dIe9jtDy`L9%1>FJj__seaDzRT#-!;SBV5=m@w>r4hJB2t{pgUzOtCfy3T)${_(a z!2{23xgACS*$@_{*T?@VYxqGj@|nUHOfs4kx1<~xv`M!%$^>NwQbW%!aIv`UmjbwZHYLMx z*BLo3{?VKsK)pYDFU_Hni8tq2L3Xs9eDdM zpY(qeLYJqcq_Ln<_VwRyjDBh2-@i^N0S0<)(@yGNuG_yiW<&*;-cy?vj-~&|Ruocz zC=?Xq|34E&%1)4W`Vk{U1Z>Sh#cv~$^;TQ8K>t_@F>Y^xo$OL(R$gPhXcR`nQKXWw z+3j=!s);nM*8i~-i2i&~uUhm1m;PPO0#KEEeBb0V0lWEhzIlu|f4m6$KMVa!HPW>< z;O0uHq20%tQISqhTf1~<%ygsLT3+^wYV;`GQj7i3`%EIp<3h?@sWwy1bU|j(0U9c* zyggu7Q3Q>6g9gAQ$gwRl1yR%(1ndrz2hsD}*^5Kgb!U`xD>@-1|2Ux<&nFwn>2(z{ zWisg!7JDP6C`ebr!x9GsxA4eGN4dm_%wp48$js+IiO!f(!`^2qAP2~lk$P}9&tj1A ztxBS!%sCH=fCZwAF6X8tTC9CYPw_^Uf?5TJZD&k_%cEG&|M9qu(g?V3Got4YyDhMB z6{$BOYEhFSqD-%%6mYT6a1r4L zD$44krmSe~kDrkWvLp3`i2BK@ce}x8st7der z2e^sHox)z>J|~;%1qB6u3F4@~&aP;TpcN}9ytlzDhqDCLXtJ*QaH-GEF}?Wl+@w9j z*khw%AWM?_-X>P)_xArJi`%eC-C|)7NqMtocOPA2vUvc$v13wPf4!4yNbrU8bNJJ3o)EixFjcu!yX}F#b{Xl!xJ65PzBLvl4 z?V2M%{uL6ML9xu|WvMJfpby0-eksK$OCDd%QQ)`XAjni7~ z-m=GP16g8d0>>*4ns=U#@Cw{Ad$sqpgyGUoZ#Nb>WfY9wy{mL``*wcb4E2~?c5lKn za9n+@ont4w`K3Pv#;8KQD}=Wm34K5SD;vH2ehf;{9?|pUdw&%HYOJ}O^90T1xc0B4 zgQvt|f}ypx7P9rjiRM z;&7Yp&JWRPc)x4{1dX-q>Q_H0K+pe8&rrgYWa`AHnXRT%&tyb^qTbIeQIChc1ZFE&i)2jZ z0w6B?G>T1$`&XY{=Ivq6-Q#iDV-M_A2;*{08&;mZ>VLC$)eYj&{UDYgH?TFu^Cnvh zW|G!ow;4??v1BlKzSiKq{M=D%+G?Q9cGQH1dF6CS8vOlU9pT9UqMSAyflh|pd1p0uc^AVw`fv{ifve!bkL?ra~>AF9`_`1mlDGBEsvhXW_2LR@mN8!+a!h0HCoo=ZTRK2)~Uns zmv2{;pklWMCo84aOKJakt)q3ceMpdXk^6k&mG%6`-1j_Y&mTMKR()!OR~wEM#tpc$ zb}d}aqzIv!qO9lXdEdQ1D!YwellIn_@_&tD&dOIpIH$M43si&RR@>Ix~Gx`MJ{Yei&* ztk(mex;ZnBXcPtg>F@?{z?roc(mNbTy7PS~k4zL;=w{l>T_=XeHML;mT1;BP`?6+a z!IP&#w%269-R8n{<|Kx^(A>Bsr3}ELs+}r)@;JzgSKQp%daklSI;gO$8I+GwT5BQN z>9gRWwbMP1+4&{r+33xBy7hF%Cp-7PrJ_!|Ryy6L;bF zYdv`iKMD@=pJwzIncK29PE4PsG!t>qa8Xc{tUNK?Be5$wUhXoX{Gpg38U6i1x(Dl_ z{sA?fn#9QPo!A0W?D!75hvY251f(3`lCje(Po_`FxSK6ChtkQRh z3GDH?)FhoiUcz5x9WeErtQN#k5xLlHr?z;*(tSYY&mnqq?c)B`;^rkxDOSW)`NWbY z_3UgJ3s+^$l=wNa4a-Z_W|vdc{*IH}Rfgb}yumcnBb8zWIn;Jv4qN{0TD-V&`_Xv4 zyn!CGA|OQ2w^Tj_U6ak{GUUn{Yoj%iKcQqlFiJUnY+akRYgrY*9of&tt=V?=;;3@| z_K||P3eg@Y#L4vRb*$G;CZw-e%pFO1n5d;ky+v?!g2(Id%c}RTq{**lY1TVZG!K*{ z>WIsehliC@a>8g))I@Dx{8eGs7;nG5?$MBg^}S;CQPkX4^<8e~GFH(SSa&!Wp>kN^ zv?HZ&%KPTXD^3aPna$L({EVN+n=B=S?ZkswnpcQRr`u>XRS1H(SVEJXic|_FE5!`4 zMI6>x%~#VQ`XN%I%9BBlNydeW)Cyo=W95V?Qk5dcmNdJS4aNTbxngsFW1kYuMyJ5D z&|V^Vn-3Cam=45dc}L*6%|eCrG54!iv4v_41|aS+Xy0)r0}icviB5&ZXZ%VwBZUSB zMVqms~@@dMJ|y1i=oAZ6Bv> zd9r0`C+~O44-;ka@-^zk3+P>@>?JIWh%n+h*9%ga9n)rtm0Yh~bxYCCu&L{9 z&2I6PT$sqrxaNkgGH%Z90hVU0p5d&{M0QaE5n#s@rbywj4u{z+2aHfajn2H3zkNJ} z&pY=j-+749AG!A@SC!8pu3ywc829m^xP1p+$>SSY5xDiSyp971EPOK1MmC(j(Q@ao z=Zp(J7Vnxgs@84iYDFMsM>%J^nq2VH)uEpKYa?Yij@TTK)@TA)PnbmfO3hZn{_ZuP zOd->Y=GpYxgTlDi+Cv?uU?mJ(`di2D%4e6wa&Kkn6`RaXEmTj;^~IAMiKUsuSWFh3 zC!EGgN-_IZY47B&>Zw)AJufPWrfXR3D}Jr zuv%PTE!sK|Ct|)eg56X2G{z-vKYVU`qTs!_@3rA=7Fc%cs+pYYm;Dth*uana5lT|g z*zA*9MRl?nE$ZG0B}5BYeK1B;AG$1NCY__$VT5cldk+(DzGsLivt}H`;NSm+0aLnv6QBc+3d4-u*vu;7>4lmaT)k`&5JXaC`=rzdJ zQJ9q^X|v$%b{SL(@3ktmWhIvn6%oJHb4MP^I=vbTkVZklCm7qeBt7$z;mawit0qUkii3MPsr#G>mh&|BcerZQ{12U{|N>=OsY^29e{(B>vcI z^-`62HSxoe!ItX*I$dvbWQu_OCXcvpZC_9D49c1-FFu&9I(b)a#vIHXD);?3(IUUy zTvO>fi|~e8@dEX84{xgjw_|20NS#OzGr(yM-e+68Wp#z$=`kN|s8<+h*1fqpUJq^Q z*U%f;{LZmJ^u9wFrnZ|ksO6=9wmBz4rkbJ`0v906m2*gT*=vT_9KK+1Fgc?w;Y@m5 zs8HGm6}`N9J?gO*x;mO&YdK+KHPbPnpVOnlt7?1SYkrFfaX(0(_HTBI1SwijI7?=< zNgUck_-iES*G09+ktTFH&8YDW!dML-88WcoK63w&+7(vyn$V$_FXgJ|G4x4opknKe z84}{?%i_rqt^Lmmbq`GAU?HX(!A$HeNE1q+2V;e*W2<(z-y3&qaK}o1lzbz%VwHqZNI#!YE5YNoI%)Powi+m=VD0X7 ze6UbCOd4J26V6a1rM$gc9<7&XfZowr1X5wF%GdYTU~Q#Mifdl@P4o7g+|)%<8K7O; ze3u6fp3y(fLj;OMK3xp&PHZ(%x=+=O6wsUB-5n3Anp9jDd@`Zm<6<-R%0@DEQeoyg zohhy3s!{5{yeu(sjkMm=ERbbSdCGs=mlgvc$oWdxhJt1B%_IV4U@U_ks5*?>X6_T4 z>`~$HK5uL5k@~a?JB3(vXaV!w1l;wrf!_qYX$0qdGtqWO43^BK=WRP)6dBBK9V;hE zT`)7&WM57F-Vr`t;M{1Kz8}OMn6eNSe{G&6gw_MVns*FSdOf;*bHQOM*Rm(S9>HD$ zUryNviXT85o43GV@-0yQqsEvyfuh|ATZ~)DVbZFwhMMZP938=tE#-j5VzA{|_5)6DjfTxl*^Y;0_0sHSnrlk;X}TRT&vkzcH16eAJ8la|u#&Azcns${v& zPDguz?e*#S(-B6CnHbqQ>2Wg;lS>K+O^I@>4(SsHzoJInlf9^D?&J7oBLh?BXL6xI+ z$i8;@&`2Wyzzr-7_OKg{dj0(f8Yar6x;}^zPp%{*sVc)~8Y^`b8KmvE)3P8VVz#R8h!`EWZBFro6M4zhzPVPj zy+p*S-U}jw8?Hb?(Ef$G9>q?i9$XxpJ7wS{ zfBxYm_-i$Fdv}4a!}`E(FBy&*E0NdA@=kaq05nbJ~ky-;MERJ9&w3mG(r#YTJlhoMts`X3b{1eZqqx3Xbkw7n%TIAES2PY>M zh|kV__FOLLl!(2A*)2yD$dQwK%)WNiA^Q}EWf55Q430u{>?^obzMYR^woSfhVRtrL zXcUPUr;PM20zmS%P1N1x%}UvvEmVldWDQZ>2MLQyeA2fTl$TYg)DfSon)FWCMSIz9 z0Z>RGKvB&kh-9|ea~h?|hLFEG{HByiO{>#fhDw>YA^%ry9=!EFM%$3%+St*SkOxpT37EOVsL~S5Y`c|g*$GM{NK0VZ9x?3IR zWXq@b)Z{9j-uy}O!FB$j`q*g2Eb_)N0lPmwqjr5?xOFayUo!LVtG5=DM0V@_4qf^J z0&150Ph%i6aS4+h+u98y$x>{ehjMXU^Hrgt^6iLrw&yC|CP~-aPcYiS&9aTHw$KYr zpmNjf;~WiDenO^>;=QR|2h)HK7gFk2A(lF8qdKm!!vP%Q1sfaWzV|81)+TUX221c@ zvh8@aMG|psnNmYm2uA))P-9;GimL|9<6?`Jk&QO!@m*gVsm_s+^{}_p&O-V)V^6RA z^LaKen;o01cHr=E2?8M207aFe9zq7^RjIm|MbZl%Fe3 zNRcn4zwBys<P+R6?(LLq#%1W~-mlP=0e?chw>& zPKtD0)i~`xT>i4)(TShX7hUyXteYkx^;A)hBw>%=q-c{M_TU=9bS-@3HG8(~`qCwE z^MGs&tACRUS!>PLsM?xXkgFC++6*~b01v>V6|n=u0La)4tCt`i0lx9vpiakC2aFRJ z$dLh`L#YLAPu8UG(`ogXTvJv(cc7ruDXby6{B)=>nFh38^x+d;Kxc!)@Rydpr9j-& z{dvyP&9L#}x%@|Qufa9W+&1-st^aKe%H5tB>Mt_oPjFW*9sTl@$_Plv=%1AJs zL$?*K^^3Pjs;UtF?0|WD019Rlum(GBa^I?QgrK#yi^b$;eN1vQ*e>sh{5?2@Vr9db$CA-3Qs-~sEpFntYpS+Mo_q!*^) zf{@2fuT`H=U}3hx2S3$#mz}121>e=H^R5zq$wo%a2hm^NXvTdf%7-F#mgoQ$a+6rhr^=TD6uC3*vaUR7lQge1T*cfV7ozrAPKt8#dKdAeTw~9F&VzwhXDk7H&@|p9F=^Z{^@3kDy zKjpHW=Vj2UF@sD`rn)5KLArZ&*{eK=*OS|O<5OHMv&BzSqjma&j1Yu@DrLQ_q&Wy< z_A5!a^9qU<-zLiS=aG{g)xJt|AFc$v?TK25iFE8NhFWsh*z#Epc#1Wf_9a_NDf_Bb zz2uS}U@MEmt>^z5kExpF(F7msGCG~wgn<%(-$XVG?~ zv^V{81|>vf;AcWY_YVbIe3HDX>CE$e-Xl&PeHBRNI(ep0r}Fnh|D z-Y3t{-1P+oOcnXT=+EWuBn1+kx;l0K$oKpAjW1x72|A&Rz8CDeLL9B;)-@SFY_?^e zo#xeaM`1IcrtUl-Z2c6uGr>4yZZ4xwQ}VU^I{&Q-l<#DOWf~0~aE6q+8R+l@iANAy zQprhjk4>NUq>y|lNWhRzR8Fmp0@Qd2nW@Luu*_4yY!+LhS)C z<(^XY@5`XgiZ27u%6J#l?nGgy;5(5@!v3Q^ShS)@B?Mz8$DdLbvcPg-ez6Ol$)|cB&R=#Y_z)LOXL2YmUjyGc7k~oEY|9X76v~q8$I0` z-A)FEY@`|7jn(GS+DXn`g?K0`Q-PK(cYDYYb33sM<$KJl3b;fAjzdD;CMUORki?9; z$CPsctJrj$kTdE>Dz{5a|Bh~@PPPr6OR(fAGPBOd9krB1E{|_<39hwacoa?z>x`P0 z>qn}MK?0X2w9eFh)OnHHb=C{!4u#U8aGlEQ(&(lTj{;Ax=W%bTcW(suw5mMK;91O? z*o!yj7Vk*;Ti+usFE96JMiR>2Y4_(-W@<5BA8WBztkSxu*4up>p^%0ZX|*n3f#_e2 z27GFvUEW|R#4;KF9%wOMymWYzXl_o~>i1yNR!cT-eVM`N*TfmpM#QW)q(;Kz$Lz1p z2BWds!txOO-)Rnoq1l}DsxgYTPam}=ZMa&JoMNGs#|-)2zf%L*LTX$&E%zLX0ml^M zjbr=A80^o*I(3u3_Mqp|Pp=GaN+=h?NwF^+@tUP)&<2NivGCcWtkwL6gJ{+q!5{OK*M3{;)7 zefVsg=#Q8Cm;$pnzCuU?{2RzCnZgp%LIa);%s)+x4fGeGJYk>K-o zj0+8v+4iX)0nd*h-~_z0*m)SU=X!jK*Dq~*byKWSH*82;!Vx%`s>zz*+$%7nq^vwg z&;#6TTgG&ooSojz3@|M7&FpaTBL=8+$#OV(tX)hv3prEurB;3QsF<&_AnhUI8F5D` zNYDcF1pt$Y$H8y?m`oXau1+r;vjZSSi{r!iuEK0LD(W$Js?9{ zW8z)SF78sLdOR-MM6fPyt&RQpL3CNCEZ`oC4ozmU&1Afvxj0Y2ZL`y@*a90Wqx3%I zwM&Ctp56hX@b#_YiZ$T^p?)_Pm6(_)7EXBLXwsnFTB_qfnQN$P=zJ23$>0Z*L8rBF z6a<8q!7Jq}eJ1mHc`hmQkE=$jSbBH%Yz5{4h3f1)R_E^i>DE?t(7E{pY&rU53><{S zcXM3?o?edRdAXsX_IjvFYjt%G0NR-LNuPt#D>ipmOK%y&_dq_NOUNagTaT0NYBI<$ z%l`FR$xur6`h%oCWqID|$Ccb+G=i08!v-M9(1-B7vDSuejuP{?rfKf8t&sv{C1udt z`HbDGtLI@9$8i%2EbT6Y%;ggvi$eu`$l5~lpLLzpfb@h}6{ zLgwyVE9DZWK+VWvmY5hf6D!FuN3~jgy#uA%=tm@G5sqRDgx(pZa}(JIc}5fmb}E5C z%gAqg?H0NUgd^dy|8qqk<(I=r_3?BQi3_)-A~7O~@KGNrQ5vu;STGb>5~rA(H#743 z?dpd5$syYGRyZnR9BPmHi*8;%>Zwux@iH9&_rAf){eD+|G>g7LY|0c_MA;)51HrqV zB$5S{xmuS!i04JmV9WV{?%~^%HTrjEXgl?-_taS>9f?c^lT2%;F(>TD*JN!Md}w1X z=7ZAR>u!0ykAitfhJ3IoZ@1=>UveeGGvcZBm$w|=O=j#p!c%F`p3&O(-l5M9c{1Nu z&V|3g*i2mFo8>6MhqszYj>*pDlGCY?k#Er;z*EJ({;7^#)v^=CbTG-5r2SRL-IAkJ z+r$&~es?b0TVZT;#mnH<$AqrOC_Yc@D8!p-8 zQwa-GNiIvrWi1@$kVI&A%DZ~AiX^s?LSyuP1Q;E~zE7(wk%h}OcuP@a-d&qZ>vXs3 zc<5V?%0q*lL2Ml@L$?CgfV8hUc}fN4OKy-|tFh-dR1vPSV(lGy=|24`9@iB?>2A~Z zls6}iWpS$gct^xAkLGrJGuxVBM+-OaY5MEMY{n*J{F~8-I)SkZuD$b`DG}+KXvLbU zT$@#1SL`*#q5p@yw+x7KfBMD`C@2;x;Q=HBr9-+y5a}*y1?jG(Sx^ya6_D-}SP+(8 zLQ%SN$z6J3mj%hCmVK^s|L!=y^W6CA|Kk7Rc}HCJooi;UnfcCqKJ)+F1hD^;_@*G! zD`uLsF+tutm}U;zSGI_PkkF@ns}p_}rINy=-}F_Yl-e9OZMBJb?iXvMvArrfy-anz zSL<+}iQYHerTo#te*WyVWys$0v%NfYJ#}sXb^v$p>16KcfN|jG(DOJ1r9UQ$Rj;$ zD=eUg6L3P=ZkpFZfBdJd`7+qFgqwv;Nq_T=>t!uL>7|7qYV;H99CvuhW^oNZd$i|LIrc<<@%Jx+Z7 z^{X~p5|k76yu^#8L}X&F0&Te2X6fJ8`lgcNG>OnG>Seg9E({}jDVaCedNu>g&+?zP zY4D!j4P^8iZNRo||7tn>)0UB$y=ohgG?ICRG0>1-AC@xO%g=`uSSw_$OwrDhSc+O` zJ>Kd9sE`M$YN*L^tm|UT z+GC4TxN^`gD!X~S0eLm0nH1KutrU;Fq_x9`V}e1sn+cwT7kZ{|XCqI*)KrnXQ9p zNp7UrS@>!Aep5QfjLiGeHw_q?uAoqw+5ArZQ)IUHNIrmQ>fUg;$v#>IXNMG$EY)G^ z4bmrh>;_XSYdiY&L$&G0Evtd5!iMkM!Pn0ur@xkm>;}^EuY7XC76Ag%KUXB;;jnX+yzELEHV8X`;*V)0Hg_(hSdh5iro!aG9Nrwi496W-4)4 z_>s*|%SyvN$Fq&G;$na9u>#9t-!c<~Uf)}tv$eU(NQqVgWZ z(vd$IXzBZ?4o2`hC<{OHV-xKPgR(UR(wpx`ug@33>4yMX*s@Q7Ta2|BUP;$l#Y&q# zqjP~(Q4;e0I0aCN;T!pQ$4H;{xxMv;C$p<-Yq#R(-o$OsT`kp!V36=TB?Rv#-Mw}V zA+VH1f5ojW(~fVdav>C39K3uOd8gSsS=k5)fPvDdlcP)eAcM*meD)>zkhWEg5E48#HfB3yesms@ zomT$?5x6D6q;#b zPdk-gAxO#Ms}i`1&3=aYZ0$`l{&M7~JGslmkBxbRrYIN*&3{tV7xjnq(Sod!^g(l; z{E{^#2`{9ZOSpRr>WSN?1@0TR&J;MJ`ucK9pT0Qy?} zJSS`xO*E7Cpdi^2ENMaz@8b#{r0EiM(LKITGEXnL^Z_sIqI?{cner>r+#=dARW6*F z8f3fw_A?1=VJ=}iaNU7w?4}bQ#a$VgW0!e;&rY+%Tg4+XlGK4Our)f#qPoArZe+;@ zB-hQGPxrd8uuyz@8dR0@Q^fRuKb=)0D`5EiM`nlocT!;kDm3q*A}X7c*=xus?1~p9 zi6XBUYQ@gtDBc7kRk2sK7apD-faYFS=hCz#)})2u5QKu=k9-D?C=F{+$thCOFO`WN z6dpXM^^&w8_ko{;?PStDsr?c{LhJ)S-RsVC4Cqe^wk=&Q&JNm47-}_}=I_4O$R=3S4h?-%GVZLU01VI(G?1O+ty74Th3aM?xm28t{zc0iOkRh_H5YHY_ z%+;pipkqb5(irg!d|>wiQQ_*UtyRPl1?YY^pQA>CD zzbb7#)b7Yx)x#Zhbx21TWw(xc_hp|Yu^Lc~ysCpkEg46L$DGL)&|f^amr5HX)IG)d zD}Oz%T|SDG~c@;1jp zL5+FO_bZzYTlCvdxNFtZH#PZ=>obK3cTN1&qc^7wQlD;qeWD?Ju)jHi-3G&+i9K}z^>ml#yJaO5pV`hdp7JUmYkjs364@skFlSLN_Jj1P$kSE`9A>2Cym2vGHBXB#I{tB4EH{ z(PS8T=yLt81@y~s$i7a@0b6Bp5m8~`s#>z!R7kqx$ZOhJ5#LFgNcr2);{4uwng5GW>r#5{bg-}a|bocd*q`ffl=MI?dH&QU2|;AXRKImc4f4IXVulFZ$*+*I-@8)SV7R5ku!2!jpsfmkSSSO4~csBx~Ge z%ZYirdUgMpCvIa!&qe~25QEvd?oTX4+Jw09v%$yXJro_HjJ9Q z^h`wrav5^889&h*C@c%s9+P=`KlxT5lJvu{(l;MbyaL5#pPS7myIyp10ITf3m*eH$ z+@>ShW#bd3e z6RU}GpVMyh=q2+%*dFOoc^B%+gmCZ6Z0adX@2j8l_AmKUog2%+$r*yfYmra+`nt{8 zd~a`;Bpkoz9I1JraVxq|oAm&t+-S8;A_ryuJaE3l#1xjoi5hs^&R@CqAX2k=@x z9t}3UZxt6!XczRg&keLR{EPWxr0k??j2vys>S2q*QcAS)-|K7o32O#crUgEV%n z0xWIIFyjqCv}JJV;JO+))R&l}kPg=F^MN%se40K4X{?Crs? z+KDp>^w$I;D*6CSp~1=NqIdUh-_499>!|KE%M|y@F}ZfOycKbe$E5sgtkXuFiD8*( z0#52^r9IpvZRliVFJnK53F2AQ_(V27yP&W$@eAAgIZ&TLE0?7rXz4#71?2{avxCmD zFakcicVp2%vrKlfVl9&+?7tu8UnTc%wto#`ar=db>({bg+Q6-)@#ZT~+>Wvd#VpXs zR|&DG(saBfCBLt|Y#os|{;eqS?l6nHkPVxpBusJdvaEP{LBT!{17%6Ng}H$xeYgA& z#%!!-IjvpHf5H6Oe}wJFrkcDMm3^Kd9hb+v#m(nbkiEW;_5n3|+=wS~agy?t9X zTqoz|Z;!eQOxQiTlU(}G(!<~75(a#(azlqZYohdT=icn0c=0~LPHo`g%RarMTo|gY zXwuPH6HAw0^I7A-K<-EBcgR(mU4X#FIv^k*7%Paq7z%_*But`#CQF_ux29(Q8kd#a zQ}#M&zD1I*eQ|R$vvZA>TWHJ;E~bKDjDfGig#+4u5c89z&@C8$Okd>3-ge8Symr;b zrZ71vJdWn)tjA%Q6VXjqknQ>&kEo>HO&%T=CVlvF$IgW_t!TM#bAJrQ&E3#KFUlix zv@D#`)=-I`KRa=%?B04Zkgk@KXJzeR>_5gj{gUnjg+DoEQewpX$K8v?RL~mQNaX7J zj;*$qgYvc`vPi{4MX{0UE;DQ5_>)RZuW*jdDiuaF(Z_yFXtT=8Q?S-??%mD8a@u>J z<1W4|2XBrkvWci-cA<$TYqO|GTdpL>!PUam)C+$1RVu7;dwix0+B^qUV|^R1cB zCPWW3?mEs&fG5(J!*9PQoA~~V?esP)ZH=vq$7!90aKjEgFFeg8F(E6fh~iC(cF?=c ze^yEV+ekm?5;x65(h*Gu5W0n?n-*7G`bytezm<4eugTNf%V}82;b{1w%#Ph*Q40UI zG_3s#Qx1yMcqHeOXXfxg+8PKu)hq(xwEqOHVs@FBVdi@N{PTRd3dq*hu|vRVO!EJV ztNz=M*h>)yxPCB<8k=KMlr^DT*&y|s-<`+o2;m1 zjsH@2cIGUd$S%qCrdwOy`OD>hRCxaTSEet-QJ0cF8vuIAMOkpk;aSWY>4dS6vXc5p z=m(QJkonH$aoN+chq7uvIcgobzq3*t{w#EEfJy+y0rSo><<+MD#=G2VuVMw5Eitq$Grp zY;kZpYvfIm>EiOc9fhlpI#$!T3cB@Di&zR*xJB*WTs*`qWJ|;o`Z?)iR%YfGJD@sm zyJidTPh&MJidP?eC(dv~-AMYCJ z0nN*u(fNN5R{q;p|5rze@U@0KrHW+Xt*l?ffMr(a%Yc{{FYEsY!2Ew5^G~~ZX!J z>8H7NO%(=OyZ{LOU%~;tT!YG5+A~7WO*2XE&PER~-YzXEarf!DMK~gj$_Q^E*$mF? zQ2u9;^4|oca@SqagZX9VK6{rZwL7+~ML<9xZ<7vJG;sg6C%_0S)^%)354DyW43ZSw z%7U`|&ar)vBBI#zIG?QAy!t^9IVcpX@=VAatQ>RhJyd-#u z%h~q_!dx6wbQfsTl@S!}W@Y|o{`hx$yJ;XtbSGSK^LFG$5tZbZs2kJtxV5QtEA??5 zxo)BH2{XwtZi?dMYwo}nMCX)u)Nesv4@~4<-T`hImsBG8WG8WEza|aon)mRQl%WcgFUxSO?8rq(JCrI}WuE~Sc0W9#ZmtxZ_@K2z)c4+i=F zV!!sv#MeGf-C+vXRNw!32J``nju~{~Y(_81ua#6BZWJE#n`*F;T|JJwo%)+44Syw3 zfB%z;Lib_Ev=dwnRrGwc=jK&Kw~R=#RDpgVW3TyVx#8ce_omjjtOqMMGB5iG2K;(t zU%5j1HYnav!rE;KSd&+^a%&iNcjP-6Q91jHEgSt=;Ls5m}k0i=nkA3Vi;U*}}9#^DPnSC+X2Otx< z;5*tmPi0x{^F+8Zr#`cBF;R|dAN-sq(&H}q3Vrx{YazORM54Y0cGh?dtT+ zYpPQ%0+BiAm$8~Mzw=VVFD|R+JbgkzAS+7c_2%29rNCsWhhn#t+GlcT>kB&`&|zD@rbp+N@U_w-WIWZQ7&lAY1$QZA>7Dc zccuL*XQjaDLwj35!#6J0SWHtKp)qLnd*4gS{o;!1=5XY^abQ9wg%a})(F3F{$5_&K z0FBbvG|Aun-#@*P{RiTT$5B)^(+wlDdPsFQ{?&&vOe=wZ+P%qeK(@d7?bq|Fm;&dZ z_k97MJ3z2K60)K3bA$+VA!^HiEG{%u)YS@=f@rjOhxP;F@8) zeY5bdO4LQ?F#!hN{Di{oMMpYCw94yC@>Qbki7_of+?lz*Jx#lkq@7gT>PGEDF{YJ= z6;&jI#Dg`^yZ_gG)8B6l)N|cQRRJl-!JmJF8C4U@dkA&Rih2I?4gHTQ{`FHc@ykp6 zfC2fNKD+h1g@k^yy`!uuSJGLMX#P#p`SYNc_V26&D7FFmlX=zAB9u+83N=MmDVL~G z(GHy3cx%Bi3RB3jnZ8jP@!OnD?h^H{o5>9V=6u$0dt!x-pFd$BXLqwTfJakBcr?Xv! z^Kd{E*+y9GDm^=KsP=nTgwmj+Q&_5%lz% zzt`AxJ$Mr@we*2@_V8zk9f0+K9@!37?sj9=!vYK^gUY zlMj9Kk3*&VAB88^@T{dd6Yd*3jWkkJRq*a*ykr9L_WI@ric+IHpcN zKV{4g+AS2x1S5=VZ(PM&7$jM#IXGN?8`Pp;2aviLp9;B+l-tE`<@#21-0JA)7?L_2 zP0*4?m9t246?cXX*CWq={VZ_|{PHfESB&k@Z+NLgt)g*@8g*(9(01;j_|6t1_{pWE z&`nOflIW5jn}$5*)#Dl8K$?j^tGe#5!fJoJvK$?FA{}8B zji6dx9h5-zXI9Qm_c|b3%`t{NndyI#<^<6Mo`AE1LbikBOV0ZEWF}y~LsPy5uUaU? zFd5MkYr#1BbKIT!apPq$?dcvC+-Az3@>Oa4O9hyYi2zN6F?+2mv5R2=3|* z1lYBLPaN2$#cS2aTL)^L|A1YTf%vd4TuW}SD5dEoOB12ANpJwS6U+N_>ZD(q_x@o} zF<<*(22vlZzxL=}CX{e~+EBN9H%y;mc*z05A;T}SyTg`cTxF#g6W-F%+uQ5furbLF z44d|`#LEc#MLfAg>Rgt*K~o#7YRogci6s%gz>egWDecXOay!L4_nRJ&sb`&;2F<5R z*`TBO@NBKY0~U-S`;n8;P^V$*h^?bjo>>>TmRHi&IqFhA_^b!vjg#F5uWcv^3XJ+P z)GcEO{)j=}N4&75lSZ$#=~QzG-|8_|ol_AQ=gLL7+^{`~2w1LLa+!nVN`7A65^Vb! zSoWm&c#k?U@v}E})CPvFn|4FCn8#lYSdR5w>(3PR_guA(%JSQ7yoH@DmHdI5av9Dc z8VsSL=AFbIGM{pW+G+-ZVNl_^|Pyp=fVV8k(0EboSP= zGdBJ4DjYde?^NGG-EvEEKL=RvZ1_Fy=SOHKw;8^!xJG$&!*Y4_YPAbwpakoh`6qbQ6J{?dSYtb zV{}tX#(<}0@7Eh&+{T#NsiQ~7N8fX7jUaD|xL4g5N3`2mu||69!DO(Pr)QH7cFB~G z!oQp`l4BhwUTqF@WYfaVZU&lNR1FQ&r&hKY{z+g6(B=6APkksHxY}!g$^xebLrs;A zH;S{70jDkCb4;#IJaRiG4PZcHqhQsnPT$!mwoLH`nz}YawN+Glg2|;0(^xWI^s?KX z65$ye2)srgdMbE6zsOM6)p23u` zki!ns)LQ!PaIO{j98$_v`yK=STvgOzbY;69+1xj%fIVy6TT3_Q(A_0{+j?>m$Y1&k z7|?UM@-{07Ex!87#%3^08kHNNG;PqbvnJURaNu{+6EO*~1P?YQOJwKd`w%Sru>%o| zXLbO?F?N@A5uMhq+zbAd+chYI8Q0Siw^+OeYtB*EiYrin8?c`3Vu_ zWVY$$d;YaseD)dUYijb{ub1R$*TM69U(;L|+aEFntw-v_%f2ww7ZmSHu537LGWA}& zde-EWADd{N)VbQta%FejTfBN_GT8NIT6<0jg447X#&m6FP#S!Q*`bm%C4|18NqBpXh%110*Dj zyXeU)Hb z3wbl_?SMb7C0;|w9s{Yn-!yg`3VXKrj?N9XzEnn)s=W=G_et5vtaD5t=BdaJI>nNM z;QdoyYK!_Q^0N&1%vJ~bxGI};Mws+0SnLI;b{kJ-2&PaF#DBWl=DJ|@S|P2q1%uzW zR#v4pphdnCB&6ITw)@8^}hQz1R;2PLYC3TZ*znx ze3kMN6eGU6vJCjF-VhpVtHnHdyPiwr?y~MqLyIuU>oLa;8GD6X_~n$U!QlAas4M&_e1U#&-*i~|M!8>{evKG;^X z0TCTkHRZD*Y$1<}YC`*lb+=VICOnym3EqR9uU%w5#a=j=u2p_Ts!DR&^Oh_u! zk~Mwf@4qaHTxTZ)6Ie9pbkE~A41L` zwXn_N%HJi>mdtBjl&f#@BuDam$0!gz3bp_Tu9)LC*2$%g8l-7Te4Myi?L*Q;>ovc! z%U+>xuuOy?G-%U4#%)+)XX_>RV)TFr2E#)mZMWF25vG;2X-;JV#W{}THNNZ52ryg0@HJehiRy(B@D}DU)&0*e4iQWfb32hH1Dm~?e2*%Eo-P&XP0-goS zhG+NK=s=~-2+?hfs+HS+u;A$%a7)`^wF!)n z&hs2&&py^tcz2^|bM*RV`02i1vFZ7?iC)ObcGazcc-c5%ScZE$KVXsKN`zx~9!L=h z=9a9pUW`k2OGLKUp@YQM`&n1rZ=IVdB}m4gqqY&*^H*@tj{_s15qp}?T8rDPq1*Vm zS3w4!Mw4FgEznwZVIQ`JYX?s*%gJqL$9cAf_Q{)ZW_*2dl>;DRM18Z%4t5bi`r!=@ z(XUvQ9(+i5ZRjnKJzF2MuNAASb(vjzyBzPoHQfb7H{?onNzP+UKx_P1Q5UU``{XaI z?_>}qo_%2);&d;e4(z1DE9t^U&BG~_kXsB$F-#lD*U%)4#J9f&v?^kWJ&C{EXZAb6zD7;2UIJR#lm*gJ1X zhR|El^^np7R)lZE5}3`pTg4IB1M*h<(M-I8w-Mg`9`kZmnGG`gn>3)OO&Eq-m`6xmr!| z{*GNy5b&jnl?=Fkw$sI(Fb$p!K|mZ!mzY_fS-EBMTNkO2(@9KG5%V9vxk4Uv9&VJF zC4$9CgOG}m$dGhb5iAv1NlFdgRIo(IvMatH*KhKX?{jv@tgCfY z@cu}#V<_wQO(|!#@JrUyqG2{$Fake`t$KKry#=V}*uy9**~rC0M@1!4x^1As3;*sW z$Rwh#Te;qHhD?JzO~9rUue(=hcKspi*MUPF<-b=`{$2w=Fk(89cdx>gRR9H?dTuIJ z0G_kd);_j+bJH1lxF37@ZH>cfZxVK<_JC)(SASTZYb5w+u^1U5YQj$npKP$?H8*UO zH;QMN58~RGDTHz{)j0dFjszZ{H(+W*4D%YT^jD2dYHvM94blhus_5H-KFj*;pJ3hd zvwB{s%HaE>PxyK*yikMNa5pErFsU}G2{W%x8LPo#nG&D|bX4@#IsDB`so$at%a*P@ z+h|tcW)m_bkSlH-W@II(6o0;fCzq+iG%xL5&y0poAM>+jK*2SA=m}s(zRw2>bM}7( z+YLM{m-5fB5t0LftVBW7Pl|Y-R(0p}OyPu!T5)I_C#93F zuz6>#k%h(T4LZrT5=R-O=u(TRboD&{ye3_54cL~^z6`4<6D5AC3da*5-7{M% zHgI-)9h@n_vwmC9Zje9Sq~4WAzcZE4-ey^s|0JMdC{BU&aBHm0I^r-bte^{Vw(-Fc z`Y1zkGR2kNzdJU{p;v7iA>Fci{W@e?b1?fegmYHPcdMD6)Mb0_)hK8xM}rPSCUN30 zR^&M%*l|h1+uluJ`Mkw*qO<`Q+nPUL>r~n3U7VQ*u|kdN*j0vZ5c?+x8BeYv?RN=e0I(fpIQGJLrLhyV`NjFtvJ;y6$X zZw`@%pD||Xo5`lGjp3PwOX+T4cNtO@@nyENCGO!yJvJaPK2Uz(GneW=8rdao$=W_DLWIMBi$4EpjT=E-QT>4Sm_BQI@f#4S2(Ta#h07 zvKVyZ7{xGK>Q?LXb@9oiv%D-`&{wbVS`_ATIj&K?9NsPtzD z&pzC2WTKbQ-^#NYwgNf{Z43uNy4pVt8VA?NC|DZ>C=Nz%?UkDv0UwX#rv`ME(g5Z4 zTyVYlKGGkRb-rO|iSXXLI+5Qo_lfqls@9%=h*l6*H1H;k)NteJ>~=G_bA!#sFxIU= ziQq*&RfpzK1+Br6L8uG{?_HIyMuyVFUm~*+tQT&{d?0#488#21x2K2`ecu%LM)L!|}8~+-nDRGo}5uxUC z>U5PtSFiC?KoLL_veupbmu2L8436t&4MEs}dISf@7c=!CYYd0n=>SQObF<`hom>A4uKe| zKULBa8mIoasCvb1j1jzKoDjE-1L02{ZY9Wb156V^i^$51fL=0?^tHn|+_(HgHOX8b zbe!1P!ad8Acv>$Egk>9s(?sdH)HEfh4prep&!qzo9|yX$_#k=e)*%~DfD}C7U_x|1 zflg4f+GQK?sBF;;_Q48UHCw(BjNPPcJXGrX6$+?fH>) zQRh4&;Ly0(dwn?93l#^7BQ{AhC`vXqHa=u28kF6>v6sT7r+z2Lp-lsxE{}p*g&nr4 zX83gWXx>~60+uJ?vMErU5oDGwlH@hB*>6%eT@i6%SQly(8u|hLN-vJu0Je>gB-9eL~jx>9*isL3@WzB6yL+4qLOlpmADIc(cO9%n8U3IOIO1r?Ci0gjhL7ix(e7C+KHeQD82uy zL?t0)-l=jP=Di{1G`Y$4Od6HR@QSnT*K268M)uB_mMrEOp)lDz@N5U{imaHQsdWO# z-mL`}6^IEyy$_@&bO&weiwr?;+$*v4C1AdDv}w-zW-kW37}AoBJze;rr7mO-H;-`m zA`OjZR`0s+wc=FS@+H~G(hHiUJ65RHMRNTb)h8V=Rs0v5O6)s-ie$5(!5A7a09$@u zm~5H-*kiYcjbXOdG#TiL2Iixe_V}8udb0z1cPbjf>$BFy1F?;#bZ)Kr7G^+t7Pwuj zl)!q7&IgH~l>FFg#Jzmv+U);x2Q2Og)I3FtToOl58AGf(mvS!Qs(!eosd>Zaab>^Q zvV)EnPb=$P&5wT;tw+SQ3QJ02zABJksBP6F(mJ(vYNTI9Y!K z*O11axCD=XjQG+9s=Y=dVH75Ke2vDDInn$XS;uDv|4k0NL9#AJOpwE9tuwS<{^G4B zXCh*Gk#MlQpoq|z)laPNMiJo>xy%;lJ}Uo~?_dYN>47`FM)=6vKU?%4KWl?l3-l8k z1L@y(1h5p>eArfj(<6S3EuF>v{a(~o%8V63I_SvNE+b@DPfNDayg%lCpe4^@E&SI! zpawRQT@Qs+)(0ieL6g(>hBCxW`5&Op$f>lyt$jaLYGT+Qt+I{?Bpl#?b1g~sneO9J zehnKg1Qrrr9Bk#T!9oh=@qF9>%Go6 z_^UdQpt(<`Ce}BeA_HXF>Y-1c2;+-)uWYu(zgAab@L2an;@P!)&K8xjye9;K8V+DE z&6(o9h#*Px=M7>Hh#tV&kM4plR{_b=AZ0EKo3fTXq?QCszMK@hI~!;X8F zn9ESLEYDp_-Q0Lk;Dupo?30`-Sq0^nmjwHbr>CDRLsF?(Twz~~Dtm3l)cFT88rIvP zl})?M$d;|6E=wQytOezul!Wr5TDWyQ!go0AwDC}a&@AZ2=#juB7?+I73_QWIxEdaH zHCAqo08|4C8tEd!sV0~E8*7c9e1Ahe=d*GL>}ku{a_S0`I$W1NwDK5)%sN9SO1c=` zWptjI3Ma20wVfS*j5yx_M%iupsQKE&RO5|3C*9X*ip@e&sdS_8Y+NuCXs~bp7n%1( zPC(lE*k}=$2bg!qQ?aaPv1QKUCW*@!+w}TI zIh;G;8z#xZoTmTkow`@dD<>l=wRQtAH_Wf^6-wXhIn*}R+%_FjR;%kwFiu#_ZmPHjf_OHkj`=0P@Eb zU_dA0oYMB<<;Xkc12w1CX|1@(>g1v}ZnNhlPmkZH9E6=|vi;z9 zolT^;q{MF|Pm#;0qPM$ybE+zMw$25+I&;^DNrQ=t+bnP0s0`Qz@^Q?$N5wm->w~WD z%*)9U;6`!h*Jx5f#^L40f=1`I{^CG5u&gCDcK_rAD1z_4S7;s>78kJ_ynnMqADE<_ zuXkf4k!O9}^!KEi4m)L1P0f>Zg{0tJ4h9O%ur0Vb2RT^>SLTK9pqAFIMaH zXL)vD^QS!K=iBX>Hp|IJfyF|I#_bH$K5w=2>Qf!)fLN4_JxkCRw?ZVU0 zx=dxf$5P#TwAn)G_Hf`I(=`9H?R}N&+l}0>R*ApeuSKVRv%P-xkHS!;$QEx9T>ieGEn=N4)C-bxtzpA?M4Z2 zIQ6Oa^=GBg>6@9I?ftX_pSnB?NoXd**K@Pmmrl!r`!n{I8!S!goMmzdlj7pyg*G>`tQX*}qYjcO9Xa%(@?D7c-aY8*$mlyxvwfJHx6;5?zhcIJ7l+Smrg?(8djqD!0cwt1xmPzOZBr7EP~c!XE`-O;Q*+VX+^36 zPddioiH5pQ8fL7?r!05~Fxm|6_lQ zsPl6eD0o04_ri$zukzDv3xFx@rtP(fGk&MRM5L{K)6k^pq2p{(t zpl+X6$H-iXSG^i53|+mn)AE8o`vFx<@_!{k?Zr zSE(EvWL6EH!x~C;_&7QBr;3~1@SJWTW(Vtqg0{A9wWSrq433{LU2S;I%3Kv!a5xRr z&cL@t#(^d^)m6i1vUIkxt-bzTUyBm@zzADU+AnMpkoxiChC{0l!mrCHb;IF&xh$X; zvNJ(|-FitB*&R4HjPh#Oxe2!v*4j><8bXzxH%XLjE}WBQ5W=>R!}tT2wobT&g88{) zy()%wvDfG{xRRW+2DVYsn(cd;)NwU1+xL%2SO?Bk&2w*`E zmf&kazjnw%2q!^V=s!O0lA$Ycm&8=TER4z)sBb%v=<}v45^V(ox7cX)~DRW~oJ^zs=*t37cYbiy#B};jF;7#s8aTwhjShD?bh7Vb@`TeD5~2Oa9n!Qavp{R#K_Dv(Z5-Q5sDCJ9i(KCU zo78PDC+GZ^*)%s`Hrt4nCZ}3aH#y~jQB;=OvPcnZ_dqw<9%o=uIgiS9^ZB0IbgFHp zTZ*h;J}FI1fXGc0`KuL$4hBNr6ys8ggPK%Puk^F1K8n6SP%|=BguX@(^?Pi~g8>7Nc5VykdQtE<~%$XKeSkw4r@n>dr)2Hxyv z3{lZRK7ji16UUa$v6TlLmIhS^gvsOkLaiao1{0RJV`>`9%pn9u>jk(^m8v?vw#~7A z0(lpA^sEu#7~~Ujf)i!wGc%c>$Nza76Li?jSZlzhrCD+MI`14kbaVVAThSwWYE1AR=gzFD2d z6NDdm55s@N6sN6lm)B@g2QzH&EOS3zrYAdP-mVBJXI1PC?BZJA(?>x=_6NHB zYmI!Fmsfp*>v(ezhY_2VhSRm0Vp?FI7FAnt2NjKF@VQ}|1xZj=+Aa}(VEABK*dhRI zjDmJ49XyBIh5uQ~d);>7wTxD+uzgTpFQ<1fs9ttASjF15)aP7eo6q-n;k>l@-8bVm zqv)d6_6^#_jY=8I*Qe>9H%@vB&aZWy9_J~ntf6oCWV<=m@v=4*G|W^+=lI}vYJeLI zaCpU6ra^WQLu1PR*|_9q9D3l}2?-EBO-^gVbNEo`&^`0Y^1a4@hLIyQ zdDa=CP3NQxtYhOpNa#jI4{F(ASRBgQ3<&4C?*eF#t6bk79l|BD=~uBQE0q*8#ch+Q zFBnfNY(aa|&uLitTTLtclXMyWjC=krqit8;RMdYQislCV=#*uqR8xCn92a$L67QV~ zu%`*Z!t3mGywOM-%#vLkg6H8IQ%Zr77SiJ(hvyTw*YSCW4ZRo}8?ZSX6}nB%S-EX3 zPO}A$XGgZReTSO{PeVKFPmU|c`f;ZU1tEY`HY(FrPOi9U;0<;hk*3V65KQjfk6x1! zZam(>g#O94NLrkK%cct8gPTn=MnBo{6Y1ubRpTD;_@MEJaM_p4aMSEP%TtqN zyE4DTb3@73y{91-mk;1LWO1nu7H-;K*(QTzR6lmd-)umT9vE%&#TvZ|YQaO^S&Njl z1@twXlToY&&=s~Jw#g;lmh$r65^g<5GL|paZpl60_RV*xn5f2ufVES*k4_GZEE|Pi zOc2PH(UoX;py4|p#0$=>61O@kYgSy}+Y$?bibU+#SgJimO;Y7$b zDtY&M+8Qi+vJAdeX?0M#qvE!?kF+BQ9o{p)jhpvE0bO(_3|jZXU$bf$K4YL<;m#Q= zD=E=8O&1xcZ|yL#4DzCU>3Ke%+A8BRrCl(ljeI~U?!LtkDB;Ob(+YW3K|C>NhPR$O zn2-vnJ;_2f1H2--)vohR0RO3w6T*yeJ1Xd9oW+w>!{FV<*3xH44MOO+*1kZMvjNzg zKpEefJb^?f53aAisWX98o=-@X6!gHaJeNOl@`3N^(5?*qkdPc7kF;t% zZ4G_r|Km!H9F|RYnvc^q1GQ=!JL%uK!SnT zC~#0~9!@6-at=u-0`^4RM)Ja;kI*GPEu}tS2+j@gw}Hw9ZB^u7Tcz(+n%8SGW*_?> zH#yh`+@Yy-M9O8f>=jW=B0psFCE+0le?;J=V)yH3WPO_d4}0$&)C9Bsiz{6aP-)U% z8@)+YdROT!^rF&36+#anA|N0lLO^yU8IE$q4y369YQZR@44T5?|aUg@KqX^ zyZP&PgIw+({ZUyU;T5uJ5 za`koK3d)F%oc(TmqbaAhz<$`qC?@QQpI^y`yXlkBF3acN)-)X(UI;&r>CbkpQ3S&T zw~hlEPiRFG&yJNIwu>FE6_&V!KTCf!N7)Lt&Sj1LOX8&mFmwEZ{vY5?kD^qhX z;|f|BfOX)Cun5GTq^fQbf4kftCz*B=YjQb~{_aT*?rg*(52bV(>Y9KlS08)4z{UHc zCup=@G1=_FaCOuLeG;HH=dl@kvG3!X){^(#Pu!#B;{H{vcEn6RpiN;Er+#9xV5Ac=I4900n z>sF(uP_3^ShwOe3amb_MCSIf-gT79sA*If%8knEwMmOCci)!a;lx}u6=`MU~yuI+$C1D%eN_P zqtruuz4FkMGEy|hq(bH5%CqI-f%m5?AP}xu#8J@1z$aycS{nkU%B7Wlin%(&T?S$# zroVg(k4rBeQSn04(_^SmCg#syZI{|$*Uh6{bn(wHfelq9F0)6({*8wBSkx-~POi`{ znhjwT408pS*fgBVx_Ryc^k|-#>jYH)WUz2ZigAy8oXR#2X)xR9YK2QsMblrY*W(W2s9v5fc2Upv@Z}9uLvy-=@+SX+<(6e))*>j>I%jy|pqEMFBKbjxe&r5xMoQ;ki zvWUuaAOU@|<*Z!xlUAI)F}vTGo{ytJp5FX(0V3)cEs(J||!vDf<~+Vz006JZqFo z=NHYJxgYyO!!|weEpd8(B7IsQlaYuK>u#DeC-?4I-cZ^;G8~-l)j+R)X)eSqlY0g` zGTG{S$bq4;!X07#1n`hPXc`uolh0ghHu59MR20jwuDU zrd-F|jKH2*o~5FWUDh$0ofrklOLBLAGKt2$L$R(Uj9+%e8E4Z5WU@3}z0^Ua(6zRo z4&%nMeQ|pvph|4$G3FjXcdB?x-$l2mDQ^M@_-t`o{!|f>+_Og>*g$>`3B6K&Ugp8) zx1*xS%es9DgMwvPv+Kjr*b^eG7^(fYa|g3>VG?bI`Dq;UVI%Ga*4in3=~Ko2>&cTv zD!=pAW3lD6!p3XG=YFZ**_Z>s3Q-0pSD~jDK$4}Y+OxWi^KUr(LiR^2r9l5o1N1;> z^BDGZ$Ktf(XhmhK3|c)&zj&FpxfAxrg;NpPF@1%*{7xiA6gJK!4zV2!{N!>)GNUh) z_uFga4#gg=9vH1R&Lw2sRvzDr`fO0%Zm{*al6~|*Mn@VxmY#DohA>wuaY0v|7Vb5C z-P}?A)0JTUreuxtStC%V;pD*|)X&t;>c&`RBrs~Ac*90;F56+zoEECi_E@?BA?jkD z(R8ssmA|&kIgBF~Oxx|&Gc&AOilBi7Tw7M>Q8`WI=dV(3Y)w`>Va#Xh)YA5+K881O z^`QzCB#QB#2QFmcs$6lsMK$_6%t6Fc!`Pz!icI_0oR(kgIJUF_^}9*MXGep9efMxk znAD~pu1iBJ!Nkr}F3G&Tc{oR`=f?D#>62Hu1Qs7$X>(p<;q;^Pp0>z@N|!Ou^)FK| zXt`A#CbE2LN>Yt$fQ8?`rZJ*$sJvoEA!{_~a=Qi_FNN@W$MW|z=>MGIS6N)h_f|6s z1ouChR*G!o{6pAg^H=9)TP5$=Ayf5|>}9pVAWl0R4)0*T>N`*Gv-n}RTJ(I9o1NYE zWV@Bx1UOZ#jyEYs^RFNAuOPkm={IgZkb%rgN)fMjDjW@G2O~gbX*5>X!Y=v(R$A9- zGj&B4O_`NB!eaael&nMGKcr0h`Lfp*J<;P=KZ1{qDmlfUDt9v?BBF2}>xl`Y*?e!MJc13l zq8XQ{GY>zvrs`BdKDiI<;lCF{|4ZuM%OadFUeT9pIX1EI+AYf`wy0d-_x~zs&hFYv5eYi#&z5ej7!3h1*)r=RCrszipL* z8}OHr&cBtc{_EO){q`q0nwy~=_3siczdpka7+#UX_S-nd6C7hs?(&ZTj^DO=ha2#o z?W^DO45*Oe$kDpqWNQC)uK$|jE4zr}@p;nsE$J^C_&-A`f64z2ilfF+@qKHR&;D(z zU$|g{O3D+F-|itNC+=`R2@6sFZL4r9+z`+)ql4RL6$-Mb-?qB<=WX&X z9`*5eSI+;x1uLlN7eML%Dhvw*@pQ%9Fphqe{@XPsj=8GbNI_gdA`yF9lXoirwF9yW zw1518`uZZF@!z&YHiC?2>WAl9L|f!osfMyd^2+iNaPZ4}EkVb^KUoxIZv^?`mbYM* zoSyvO0JcG)kA75FdJheqTGIBvQckFLoG4Lpj%U^%{ zZwKekY1~p)bmHLfwfA-r5kh}1!CKEIcjIN#qPZi{>}Rs)Jw2_XHw0!2Asf6Jv!7ic$zDpIY0k2UocTo zFi|5HHeDF(!HbP?BgSX{olY_?dQ<#kb=2hi7Zhb>(yObfxcBZ+gj+HMb_}8nb zXhtL#6J^SczeN(=k$ufbkYf7Ak&z<7%&|$fWsB6ifrU15D!}*X?>W)lE8y1iIl<`> z(Gp)R4lubTCDV8NZ#BB08VlSe)yRB#uJ9ZEYJ3S#Qo$~o{e6SS*#wvm(!ILx{y{V z`#en{2sh|b zz>46@+(^Xy(8Tu-I>rDV6u~2+{+5-9JYDzjk;LyY@HDu*M!qY~+o_DOc$S>;Z3FZ$ zoqV}mwNR0-G0*H{y)>16#G;`n^WllGY|8|rQi;|lTOEgq$~m)LE1d_?-RoRM8>SlJ zD$n0^su2Ntx`aH5R(McnaoI~_-FwS=lOcTTAoKjJ+eoTihORD}yT%{`!r&nd_4++T z@zNNgjt$S?JMyy9dAE5;O*mFCj*KfFC+!q^V)WvK5{72f%5<{&Z;@!EI}M(6`op$g za1KW8Z7U9VJcZ#1=}h_7J^2j<;yDuF16*BjGp%^c=FG!1wHzILUODDhJWK`ld}IX7 zlAGjmoWc8k4RS(8VGaB=9(h^aLVJK2Inm9T7#WB@q=Ti%UNpgP{aG=1+FF>sMzBCn z6!WR;08jg5cn}i4uG2n9gBnf*Jxr{;=LBBRQ#CNlF|GN$#@y-*Is5=N!ELp&Ols=%M_ym1_deIu zeJ&uHT91r-c{;q7TStqx=k#72l5x<~rVFBtAIF{wUKs~3P(ma)2hnKnh4|9?AVH2? z!x8S=Gj+qr8}1Xx*W;#2fHh~tplpJvc=F&Euz6{?zWS4#6_DgSQd!X6T_o~h+=Mc| zwHC6=%sByR9~zNV214|(7LbIRKkwZMVHHouY!Oy9__F{|J zW*9~_2q{QR&P5Q5a{<+uz?^DzP*<-vZgxJRxwre8VO8~c+2uCUcbP5B1j@)pJd%*m zBLfi|Qg~Sv;YcpC%&i%=?#q@6b+gMz-6ai!m#ByFFY`U{1Nw(y>xQq|UKr3Z%McP4 zm>5_Z0bD#u9a zG#K%=_qF4s7s8E8r6KBBkh?$G^9f-IsP($YO>2r(XLcxDwgOE|RA{~8i&uk2=VjI- zYN|7(^#b0wHBT5LiZfNG){ZVRiZw$ziOGi1eIV0UH@T9xU=E|m6z;;D%<3DEVwl3+ zUhIX{VM(~I)_0n#fv(Umb!57hut;>Jrz<~t=DsFBfx*%XZg7L#&RaoIgrLhq1YpXZ z2ew%Z{I06V%BLaWO$vl-)x<-^1EQPQCwAq|uOefkX{ofSY%^O&xr!JvGD6HdMn5kv zqe)yM^tNEm^-a%mk5q^=RpdDN&Vb2NT)@UuhKSr)sA@u^8#>A}Q&Ow=2C{4IElh*3 zPCBJrR<^M6OR7^azaBuQjBKOV9iA|#+X_PV%Cmc!EB30c za_u46Of#)Z&FI#Zd?~XMAk~{d*1So77QVjQJiQFaF2+ZY8Gr|DW4ROgA=6CwV|N{l zQ4qd~ohaMU?16i!$c?m=r-PUqpNm!7k zPkdn*V=iE*{u(Q9ulW4{PL358W{5{VqeMy1=jGd#^W3evZ!)sW^~(f)NFLZ(H&!|j z&lR-gS7cS^mtXB4j(<*+)Y5u^o&p7taV2To@9Zp2YAZYQRItv+PBP?USC(6=Dr1)( z0j|r5T$lHuAFwEq$8H-E?o>chizbWwSqG;h1rJ^ZMqxyCZM>kH43r|I4vGexG(Fqv zENnGr{j%-K@b>)OSY{05^o`|&qq`5lPf1-kmBlzwWN@&+v6|1ctSL`hU94t}Z8SYY zcW2A&qIPM%M(9yR8BOlfe0jc*3Wi87jGe1N{x_IHw|j1XsxOuLud#bDX{ipx*WpWz zr`vj+nAW>`E>#TVNsWn2dJlTFt|taVMLk;j+OlIER58cfC_l4zz19$q{JDsw4U=?gkfAQjrxk2^)unmbA!;-t6M0V?KAS!03u;|=(e^Ak} zP0OMviF0Jp)#cqjWo$47)1j^$2!Oiyfql=A=V5=$$YJXc#xPSFDev)(znz$E5yqxW zQ@DZFGCR-_ED3#Y5~-`1nv2iM)Ga!u`17vCyuqVm;hNT(4>=pq}1YCAl!@cFW>nYDgiCkk4yXqY;T-DJXjSJC5*)I`vdFLBTd;Bnigyp)`*O zqW+v}`%Fu)8&VdricIRNTCs?p9d6wk4czGTi^5*LnQ9!}N4KmbTHKy-d)z}FWG8Fa z1Gy?#YKFiE&m)DN;@f6QU3pz)^eqnVZwW(lIk)wXJ!^?>3sO}@YAC= z&LoPl&3b_)(Q$##pJ&L&tui=|&ttDqYLR_NarO7`I)ObbY8OL%f>WI!9&1zeK;cvH zVoO0{TE(Za(()i>t3W|tOI1jI=mJ(;YvUM0k^eKk5x&oq0Lh>o#dLWG|=a6lQ#T*)^YcdeHnPU!k18ad^V($fUjfUohRj9OVE@0FswaGyUj zQ#tq&fNdDTGNgID1G+Y=9h_~1ii+q%soJ!Nau;?1SM#Sw_zXAp&i8O~BR_cgM%Bx# z0L)i*)MeOIvW@L(jyZ-Jfl))l=H|r3J0(8>r&dv6f z-c7QSSKh>!C2Tl!VMrxUVm#h;Qr9ecQ-@9EF3;3F|<@`Y8x z`*0vgOTdnIW5cbDs%x+;JTjp~v%lxbJx+gW3gR`o1WhKXag?EE`T*J652e2`Rp$YO zf11r22LU!Vs{yCU{cP;{7@z~9PW%wWtG;)-85xPjYSVr3^*{7$X!71@uVSompGc`L zEGc1Pp|A7XS-7~+0Vu(xak27K`8U44M+r?=jzHhMs@%ftVv*!-DW>}uSeK>&^I0js ztjtE|3WWuU-!095O^7eGi-(6#Q%&O-6BK75A<$^@I}Bq@Iq;TL?dDGRKi%pzIc}_Xt;&VJVwNAYb98hAx&aZTE^{4g za}F*}`tww=FRsz0f$z@yfK)lIo_-P%lYMF8qeIhL z`m}?NEC!hwoYEEU2ZIH;{CX+c_3ehB++4`^_LtZflt4!R_2YA2@u`k>_7Uxzk_=al zf<)zLq8C-3({;9AFl)Y@S{$sPn(EEDv0^8iRa)H*kihPxLb#{|&+q1QlfYcL`9P3y z2kzt_VBw&OD{}06{Mte@XMFh42XN!pE*lZ@&aJA$O7rRQWe{J2LqRcL@BZE?IEuWg zH;TN>`>nNy`V^*#jI7%_#?{23LOl3TA>W1@c#)u(x+cH4Q0;E4qQeZg1X{!3#4RtBup?_D@Gf3dYt( za#+=Gb2%AlYnxk`=w5j8#&)sAZdlQ^8%%p|u&k;r;cR47%(HIVHmR<<@shE2<(T=t%X~|NeOO%YDqFsd^!0u+ zNZftd6_+fK{6#A@Dv4SNsmC9!PuJqeaLL}Y;!EybhxDOPdiEo=LpHvQ6vPeY z(P`{)FY{E=o3vd>NB3y=2@N!^MLexY;o}|{(Hb(|qkOaVED_Ip`pxhURdfa|C=Kdr z&&-5E=5^}nwpxK2d2suM$8D3R6xgSqVnHlv?zP_^gz{Y(a&hdH=+BQcdiUo8r%J-Sz`k9szXfNIt z-OkI7;c*-FpBhlrc5DlUGgC*KER=GaB|W3zu1X>~E~eCV?N>A9`XViaH1|BOVc8YY z9IzwGwd7uXK*Udu3CIa7E&Q?357-nltN5YOA|0z9y$orJi{@j(v|l3S92de)KbZIl z7mADv>Hpi;MYYywXI*!MH+|K z%9=Rk#G_k?DEI5unZfM3eQi;NfakpuaG8{rzO$uY+4hUJ!1kkz4?)}}oyYvW7yM%~ zB5zjS!5f_WuMhgKtHPUWc-3$>~=W2T~7sX3`%LiqK4`ceQqpTe_9Hrw294kIgmYT2Gr5~H5 zDhWO+(0iEbGb>tp3U{QYa~Sj%=VpIooB2pBui_PUnnAS;QRIP#h-%1dXOkIonzcJg z-b^Z;eS33-X|+TGzG7NZ8UIQoR?cXFZXZ!;xlsv!rqfu)p!pa?+s?O};y`~ynS zH!w{@f+$3Wu*&8}&OHiZJk2kXCf5qHGMcg*qoP#$Ov2c^&Kti^#l%tpJDJ6Pp@ zcLu0bBi9|-1tCrfzNbBqs&OB-Sg4WnHc+^P;d^0IaP^aj)c+Jmk?6gKQ-uGrIPOvQqymg7?i81bUr4%Wm|s z&*4cMdg}(NgB3?R&9-f~xflVxKMnD}s4N0qKKr2JY|uP$VoJJ&-fXFYp53uk55;LU z>Cx`x#1_g_oK>lLpRGd>iS1OJBl|rg{5tTIZD?YBVXeMUW1i=;uZLd3Bse!OQbttT zXJs-qGjs4ub^HNqii2Z8g+YL>_`utDz9e7sZWL2;!>kvF5*KS8l#Vg(p5g~s2qv1& zv1G*GtdcJ{%b!q6(x|*zbLsP2ArU7_?^qg9@zO+@q)IA}e7az_tv79QvPWcJr-taD+A*VWp)wVgHo3e$ z!c)bU`V>o8J2NUv`_ai%z)SA?Gr?IVHIIcJ@ub~Yq9pK)dSA{4v&oE{cGPfy=%{6a z4G09Q@iEQC5jhKj6@ZEXv;Jj!jwC>b5J;#z%$AcK$Ma{ZU-B`>Px~pK+7k{l3Q~)T z)Sd>lP^ayJbdp4hO!jAKr(x~Kz5G08jh^R&19sNdZIm+L{Okt6(&1*5hlqY$0xutL zN9-#P7c{a=Cc15jn;UjkU0$Tt-9d5noAcoU7j!SH;*iG;Ioo*;2*$Wg|+z?f)u+H(iG zeqglgV`r;uKP!QZm@+)~$DOtWi`=7LJzKKcMa#hLlPz7r_Ji9`r6(WZspzdDJq7hn z+GxpjQxN{>q2bF;6a`9Q-qYbm*c>dYzEE`lX>(~l^X+!3(o@<>GK?qgG5}WSusGw~ zoR5X7C`EM90aoQE-6|Swj5TFv#jbef(MTeFpdb|^6#lBqRFB)&V|SI0SmKlfz2z{c zt1ah*YO!5;+|N}0mWH<|YgdSmv+Ce}UEl2LdnIT>rjTA|1dsc3IK>o{wUE??CwPc2 zZXWMuI+|`ZBd!4dEWON`gc;%HHnZPDbMA4vF{w8ptD$e17}Q5{3Zp2D*=wr{i4lf5 znsxz{@ZH}Pe>Q!WDppGb-V3lYyGvA|xI&-jM*iroY6b~)7@G+*7Xr7b=2(h?t1RQR z2hI|~I^3{wH-$Q_AIJ<)hmb*DRo~AwRXUu^ywGo|^OzHD&$&OqJCZ)=Kc#1C*v7c^ z5GM6~GUP)ww6OgrT~o^~s`iIo3eBrJgQ3h@qcZOB>3t*`f~nb=_A8j)=-J3-k7nh= z5^WU4af*tFaHR6`mh$nJj;|F;=Y+JaY$QI%;sf;Kxr+_-6roTq%d(T{3wbWbR&OS$8;t;T8SVHz3y8kz}yI;tdAHR-*Jr67QK48ni8qx1DGnxf@UV5 z9{`Pqq?!l#a+cf+jdS0D+xz4UqTFm@SmZn(C`>Op7H+ma0FV(gwh;KPL!PVgVde>* zGMTdA4`&*-QfHbSJR)~D=DLxTy&h4c{I}!zuU_V6wrda~q*LBD)j^0ExI4Hhsbjbv zA#Hk#53R8&_WbQgmgs)@HcCrQ{hKCQ`fB&%L zj_TP2TPif11yx4Hf5&VC4UUJRrY>>1{v=o0%f5boX>Wl7W3ZVzmQh;4E|t{fH^xoGC6-2$DWd5aA!uk#vm%PO+fD?$(wQy7fH&b0sT z1}h&=agn}({&e88XU~Lhk5~FblFGBO_*8y_v6fr*L)YifB`HI|hp-juYYy zq`j{ly$q&oI$C~jAv=)ZoR9QrET=+J5~Uuqm0G*&;~#A*+(9kfky*XHe-W=4$ z>2zrQ(JW&XzWcYUg-5)qYxHqfc7Tbwx#y-`Ity5!skR8RQh8*lWRz2rpA9dR6ADvF z-urFA7+3v2N0h``{c$PbTkBF06*0FFZeo_|l*(KT2b*g$k`iIPHFiQRHiC>|T-T=) zsZPPtvAqaVKBww8j90%UXkentQ0RQ6Q!`bZ_Q2wCy-$X*7vKF1ZaeqKjsIHK`7hYC zn;is_UqTdRf9KV>f#;HQgIV6is?t^KckSN0;qTMWo0G zse+Qn-cbH^D!W8Du{tDD#0&c;pi!M^Gv+9#d?N5ZB2{eQ!LmnPH~8w<4u_^Nqp&)W<&TW!^*{7*wV-h@*3doKJloydIeU4bL3 zEU`7}=lA~Va1h{@4f|?jA^%(64o_2@crZufQT%m-{@Tkw0DS-H>d$5P&szOQ82&e& z^*_S!A7S`^CJZ7?O4|R63*bMO^S`aYpZoBi^Z1|h`2XxY{+k5;Hx;Djnxz*%@+tmE z?xi4)?)@_g_o`+J@RxYnaU4E-*zlXG*Kn*MlGBjc)3z4Q|F&AGk<)%wS%jPYZ}=ea5=^AJl)t-Uye}kXmS3lg8VOP z;_IDTxL`=~q9j99l)47)>lnLresbZrRouIwX7hG`-Qp6y%-pk*+uWl^IZ_Vc&B zMgOC>hhQ6ZkWUW3jMf0W*Rb=V$poYG&wiCaeP|oY05)8m#6SX?5|4pKWXzMfBfk96K`(P~X@lIUw_f}- z7AdJzZ6FT|HZOhAPo?r$H@APTK#UOMO?Gs>&lX*zHQl{E8|-ly4;j?e=BbU8DDzxC zR1I2d(#+HdyE5|@4@eCfT(;VQY6-CAzO3&1`TC?fx=ZNC*9b*IcTSbMfp9y16@Bp5DCTXxKZlfb!PRA=|u58*6XpMX)G(yddsC8 zI`}x3N+4B^9>1KA_LR#e_Oe=ZrloAcj3Yd?B!YgH^ z;@M+qr;;k~GKB=Z?zQc1@%++gP`-l2{-7#u@!VakaylCl$g1Ge;w~w!pEmvIV5?8x zu`bnhLSIBRmFwbPcUbE+^JWdjV$9(^jr2(?_-X&`E8-KVYy%^9lmmKT?SATLK9N)y zOfAc2(HYT&07lgl6zSfni5Z9tLeC4q!F(Ac&rhL>EzT-tm7bcu5oiS z^F{2@b1T4etfFY15S`$7vJ1 z`qsqu&01x9R#qG?^f9zDk2G#GGGojWywg?zkxP`g#f`v?CBV)<8y%scBS;A8#h~@2 z9aK~nXe}pSYdEh2iIYjNi@Ezu*=9NpnBszBgt>TM;L{3)ok$yXb6R8nb7c6XVvly-0Fe-H%G za*ccA2c&-L`#HczUF1yVnH^LJt~PvGku`-Id*rhop^yPZWrp50mklc}4A6mCucUKN zsGdnHS{F@7LD{{o$}zHi17t@$qz>2{60IU*ZukbvYDH1#eGsHO^bAqMo#$7?;H&p@ z32JO(wyrA4xMB!K-{y8GL-0yHIh>#^0EZ%i>eps7_(KtMxBiDa)=sgHA?6b+(6%^MgsW9r!i)hrW^%m6Kpe z^@WH$*WB<1z0-%Pd)_>d?UEv0vZ|%JABb+!ZHVIZ+I~_n*KtVIr!3DwZS$o=PD225 zboZ9~slmNlBSYk=A^l70R^^d{-{1Zk-~;s%N(F($aUjTJz^DW{_E|khG`*7@&s=wq z`REj4y7tzgI3_8h!)1|&V1?VeJkc~!%sU4$@rw@$ZhOJ$<=%+ev)`pot?uzp_X2DIaBy$ReRgdbelzTlQI z6Q@W2nWtkB*@gM=Wo@Yg}xY#yHY;h z=*%QA<lu0wnlhpIU9EHrU)kJl22(K*h5I z10KSB#x@cJIn2fqKfCQWw?LKigKK`0dDoZeaV4ok&ed0zxq8`zCO~ZY@=4HHX@?A` z0{;v;;%KPE>PhwxyY=h+jHI>Z9F&0gY z-BeQzXx4I_@9@eI9y3;`R{S~ifzy%12#+3xsVbWXZNy%$sDJJb4*3~rJmJ{9g()tg zLva&UOhkib0L0x(#xL^c?fGHaHjNXbrH84De{AlR=6>5SZBZ0W9vQ%0X*+u`Cc}kD zrUFM2?^KufG;z*UK;d0@!#S7Q$};-NNYvEMQSy78O-^=A>xwR`JZU|n0=MMOF2EXT zZGEB|-=@%rT}B?I83>gN}g;U#tUv>7ezxhX8vZ_^#3A8AD&54G^%# z%pW@?QAlaP!ET|_Zt@U96A%`8dBlebjaR{-50bjOh6x`5m}9SzO)-i_~2U zqgU*=t$Ii0Ag6eUUJ@k2rswtwl^#H#$lXZeiFwOHh>UjUgY+F&z;J5r21wc@MfCV5 ztCI&lxyh?vZvz4|@``@$9JC2?&h%HGEhS9!C1KV)VVRHP)s=)c5>7YtYXB1^qWA4@ z1E$TAbgpBUs_vdY1Ae$m{?)*uyaN7WX@}aIqVl0FxV=B(tyBk7I{_rHf}7oXXNEd2pokt$ceP z{2bm+E=y8W%{7hA0jEBWKvmjWn5^QycLK~R=2tIN4|x)D0s zLW^WQk4IHlakF2slw*cE8^3I${r1#Ws9@+_XuY(@&2~^OBX=zKAhe*+5jd!(QKI&$ zCcIUom(pNW@8{Dvxx$6nwY>tzd2fw0{i#f}g}IBseVy!ZJ}1b9>fPmeMh{+nB6*;F zL!EH3=Mx2`UZ|{LRnAA>ho2!`5c|pmKy*hu75sBJM!vYc_imKY?b}6t^jyG6Y$=Ej zmX%i~2v^M?xL1Qwk%*)E6c6@(vb}ba^<+AR!63y{SR1rwDKD5D$Olc7HN8qH56je z`__vvpcsR2;oxhZc88}%3Sj0y0C6kw7DSGoD;Dz}5VOfu%50iy(3%~dVrt~zX9O8S z4@_od-d2esg0#4DC2QA(g=g955KcN)vzd;X&+NKd>#MLiPe&}`L!t&9b#jfU?!M{p zfb-w!w+4*~p$;<}aLELqwx}Y$r1ejLM(Fg;(ze1E3kM8-N=gdKP$#{Ajkl3{=1iAg zVis#;zcdtlmvjA2#627re7G8+dY>kU$ise1*NQgVaL*#Z zt0{2)unR|PF?_co_5UuOZ+^_E9||EB|krJ;c|&0BWc4T?`y9Vt`{3_xk4M=35~@iCC>IvutHC8 zz_RBZx=6mKy}DRpyp@#|X?%S7nkC`!4i+jyBP0F23`0=?!RKz#@7xgWgm3rk1Y`8D zP38N0f52tFv?@Vcj7Q)2CM-#sPTIsuflhbzGxI`z?9Hjg^o=;L#7w>zQuq zl=G510|!p_!s9eg+vJ?@{2;4bjaX?D6^2Fe%^wrv_mx6x7C`cC!l_a6jB}c1T0w-I!n56rt!C5Fa$z=xKR9U~@a&B8!H(9;$Y@GZz zN#>hUf97X$_KBR;H8f!RuQ#J*uJ;#rJ5Scvb3!Nbgc7~_QYHQNKe63*8h-bK@!wn$ z|JxaIXWS2$;pk+Ml8}(VEHRni!QICXT&#YF5@2acGDf8#Q^5hTU- zr{_VbcJ#xSj|yvjDV=KviH`b|wWLHo>z7BT73_aMfukavDK2pb>q}xNAZsu{(OIGT zo5p$XZC%ntZGW4kzsY>lhGZ+X)^lHNZIzbg_U&j5HHgwrnae?9YwNobhw_;}e$=9_ zU)zDeg0#`Z7eRS>p;Rx<85q$Gvuj7vz?%)>;Txq*aNqrt%#yyN{T+Gt{ZF?XT*#~{ zCicQNB#w#Wq%~P2P&k;gk+yT}dXPDObSQCH`zmdMV4|bC$I4*qd0m~jsAgE1;l*g` zdBuThM>Ny=#`g3S0>>kWhos5Rx5b6Ep9$4`?Xo%~L2UOOJqkMl=*88|Y!6+*F;VW2ydR`c--Wp>=1E#trV!_BfO{U^HnUioDtVO(I| z@P@{rNP3I0?)F_9SmMzx|UvmrFTw#p<06$%DOgei8ADO z23!3nH#b~j3sJo$m+oYd9bcHV7LU=-YwGW~>NTsB;Va-nt$KNLhBnYpB>p)pi1z=^Dx+1A;;!f(gxKs+lx*NsUt`)|;CV~4Y z^WCKD)d?!OtkMj=0s{MXc2;lR6hg}vFNoKW5l+#_==gX89PC<&2BP?Im zg+tgR#=bZ@_MCwC{8~O7KgpTe^502~J-WH<=5x8*UhIeH78Mb7<@TTOeskVSh|(|N zOZU437T|bjBS*(Zs)fZ06kcu^Ny#RZOxL?#FI@cmhBp}8n3rc$dAX0C+*o?CnWo{C zM?EDYFg-XqJu|{WN?4T(6agO6Gq5<=L-Q5v+yfi^jc$5uNrIn&u$4Is zHb0n5Lfc-UeOS5LGKbmmmA@dUM{S(alF~1O(2vw93)kn4C;9 zNyex$%ex;$itQX))CIioKR^b#pQa#7&USG#=2*K;o#3xOG2b1T5FF5ip2|g5dpy8B z6QvC}$Sm4>{C-d`pEyj?YDQfFEEX>e159_Fklk0oeNoAB@AD`W6a-qK1QpBSLa@O zJ=yCQt6QPcjDTpW^>JkKl`3np0Itv4KLn+fgG;Xm#SEN#dU`}eQ4L<(iiHXsseNGo zJry4x#na-(a!My>=e>aIN05k(JHA`B58v+)qMl`#?hQdqfKnu(c)punY{}X|p1!`@ zVXO_qLpg%)E$l^DG^ZP`e_Sv8IOC6netR-ZjH7eQrBNOGK%`N4GKkWenwZVgyS!}l z32Rm*E#QH^Q`Mxov0n%RT8lu{YK!4=)_S=E4r1F}TUbz4O^po8MI{1}r;qn!HI|(M zrm+6xxM$TR{7;C*D@Esi`^Vp20obp0N35}Pb~j4T{DjFlEIOzB#@HDM4tsMk5So>9 zzdAr)q_QPLy*rLX!Ifitc9e<2h+h4j;DCt8eTeu+;kaiB-JIz|sx;rXp3@zb(-DB8 zQK>sesl)~)bLPgzduL!38z8V}tw<4uH-|dx32`Ycd^t8WR1p71)C~suDumBaq9Z`5 zZ7-X+DiM#KCHZ6~-=g8XuP`sqw@#tpEC1tfg?2o76O4Xx-`uA)f~u<4i|Z(bvH2y{ zHrI_MuLTNXAW#?6lU1OBp92nW1ndOnrC1nVTy(1% zCdzni1XrJqVMMqWiFC8BKN~ks_vrc zjEw0zW@i|(1V)Sl6b3^<8y60--2VGLdv<3k#WKheND!>ly_NEmDrk&aYczj01DCMk zU}&x6<0G0dV#oeORAL;&mhH36)e9Y7Utho{_oy25Hr1Vr!*`(8IyxC;Y1$d>V{*_P!fG~y7&@`BB zY4+UiqtnkWgR2@q_Rx(xN8X3A=agZM4d5-@JsL0mG435>EiW;6?cBt z7?>m#1$9GH3r8^R#s7n?w~T7Di@HUNmjb0N#S0WDP@p)0;$!!t2GVZS=%H7E*nPy1!hPwLPpQp~2v1SuNrnKA)4jd3!H)Eby;1ZPq{XpwTT z7T@}`sD=Lin=Puk2v;lbfA&_NKi^Nc6)Lf98>LOZRb5eWJG8OKGD9UWmftbE{2M@2 zP{jn`SVT>~A^d$F7kKic3x|ss2k=Ns{Z1~RH#bsIDK^%&QwQo#=k*aDyK$QGBez{< zaYTjn1`FRP^olGz086Z-<19D`8%~ykME>W(%Hr;I-#?uk#Ha4s3j0{LQZPK7XtlE1 zq9%|hDX$U|5&>Oz_c)+~tajLs`_587|E)y{fE~5aSUzR$3(xQ%*Gh%_F^ZqB)k;;{ z8Y+>c3QEKoambjeA1sRvJG;7#vk#4m*Z!CWN=9yW20Y#rD2usmCK_r17x6yXg=7lu zo4%t~jlk%s71R{lX`f7Bjyg{zji1BegELcnBZ<2Aed*(pp=Ep2%BbvvO0Y14(}nh? zllBH;mqe{t0;_#&w1B-B0p!tYIk@nMuLAhR-q);mrn0>#KuA}c4;AgtEuE42UpfO) z_ChH-A5qhMSy|;>8`U<9)`SI-T|_A&MfO1a5&79dwe*mNy}VNVDY=N7CL}vicwFjc zAKPx_>;T@!Jxc22I?uZn3U{Tn&rW-nzVMlw1^JtU>+84|7)NO$g}^_6C^gSQFaD>6 z)~6@C`G&bgWUgnoTrothtAZrzVOLc@Y;cb0@ z`15e`A{Qp}UeZ>ZJR~mp<(cyVl}37nqu3Y92pO~hgde+hSyY_0%Rgs!Q~=^6lWjlQ zZFKj!NQVpPkf_=z_%)*a7OVZ3nWnOkaI1wh=u>z|)NwZG8uk@QXQBQWszCx~`U;hX z%KAcYr`^TMyOn!PxU4Y^vNG?riqXIa*2f$2?mqmkHotL)NoQ)=9b!1b`+30<;JJNWE&)=eW@FeXreV>gJ8lk`D;`Vz zyU~)t-WZ|+1dgg`C&Zf=6Aoh$6MZsR`eC4Wa{u_vBeabK zQ=|O=1^*iA7Q4Xb8XoZ2;LzQwkXwtm$-Hqn2+Zio(Eq_*=SWJRvSKQJvYMvJ|8joE zRBq9$B;E=6r~Jf2xbQJ|YKk$+O{-y{V|W(xM6%`e-oLwZt!sW;G{cY7p&G>I{&zcxEVHmOn6cWDLBq*7&C_z* zBel>g0;2jQF^84EfS+=3y6Nd@aB+Pn&Q+=XPmY6V{^vGQ;)I4b%gy5;rFWwW7)1?2|mfL%9qMnZSLl=kG z=uamKNvH;LZs9~m?53arX5!m;zv;cMi^=!=c@)&f>|!3#nazmI18mtA>?M zYqJgu@ImVj(0LZMuBxdyHPLHlpD9y6U+4Q&$-%xYK`@~H=VFePjRxZX)b?oSjlqDN zbEo!u7$T1U4YaYe1K+oM=f^LVSRd-OvM$meqyGpAX&_t_DQ0k(cw;`@F;QYp=sJdP zPiR%kK}3i|mwxFzMORzDe2)+#9Mki)ymCMJL_Q`D7#CF+kxL-m>3#bJ^3 z+OCY2{BMy9UC1Cp7tyRTuvSg!o(CeW*in#BPuJWV)8oHT+zlOyaz%>k!Ym7rb%Oiy z2SOCJC3!R=?D9fteF%y!0TFnKA^<;K#P@3>Bm1kFhJaILz{$jvMxl)n6E%bUBr7&{ z$ghXE*XFqtu6e=r69Far8d%SVo@omG2`SmLeF~H@G^m5+>sszahBP!tvRqg?{G$*` zuDBKTq+PBHP|FkyqM!gzJ{41+6EFnES0`zHo6@SD1iH<(vB(EW++DiD^A590=DWB_R3m{u27LXMJdB#_&t2dFH3Z^A!WBZNe4w;oXINqLZLmc1pTBj zucz<|bWfU{nc(m^#`t18w-`;)=@ClD~CTRYh*HP&2lbjjNkPElpl|1Lh|gnr3+9LviQ^CIPPHtG^Ue{*SRS8l@bS z5WamUZGsJJRgw5&UblaXjcS`r5Wixp#G_Vs9a&X`Ju6kbbTHr4G^|mdkW!Oe!Z(>B z4d#{LOI%P;R#tW2mv6Ysswg$4!`PW)3I=Oom!Naf%gINgWUB+f(o<&|^X!e!GI{eB z`x_r(-u@J{?;j{Ob~g8Nn#9?1S<-?IF538Bvur>1wBA+cxoT=^T56Wx22GR}$|X## zt0|QvU{1F3hN~-rSi}l=vnSwvCwmghBIu=`IQjSrrBZzi5UBeKjfg+I0LPD!sTWI? z8q_r&eH#qYX0e;T2-l!`2F$Ff4T%i z(GdRqZH=0__0f@r=&d@4X*;~Zt2-rVns zR3OyY_PyqV^9^ zz7y%n7;K3NQ!Y>H2VW@*kiz-@YMWs8TAI@uBBDNJS`77lh2+(h5D`}mLIJG471Mu0+gV$Tw=9`^9a*DSoN*detalRpd1@T`de~1q3%mMRG|CLN3%w3f6 zg_87D7bK8BH>~%Q8Ry6zt()q9{xW8_egw7RGp0U2F}%1iTk^vuMgDD67iwL80*U;t zr3Lr-E~YgG)GT_l(*7VKcLRRb>~hl}7vyDkyCSLQ`vh%1!~Q|~;$!~gXYL2}YHh;C zl(aN`J-snrc@gu2nbE)$rrZfj4q|vv{^j|@otF{{E}Kz-SNx!`qZXwY9l1c^YHKnt zVF)$FuU_9urSHINq=zX4|3O*6Kmft2=b5VpzDjz1(WfF4ab|~R`y%xxsPYmx^RG^D z+%iD<8$q;J^m%xWuh+MbvHEJ?_6kA3#ED3q5?UYS~6~4?h zqjP=Cao0_y)NmiS=P+z8MC$@6QD;e5vM$@4DWI{Y5`@y(#y|{8Y~xCIM?b;nn7!wh z=76{HDR@=br)|q+UcN8S-G(@XxzLo-PpE9!C}8;}WfikIIE3#+tCa2cF^klGMpWxy zu5M>x^jB5SB%aQ-XK@XkYT#i|ePu9Pw9ywo(7(;6D>&^=tvwoI`(!=5alW56w$hFv zvWuyv0`67oyyfZC7?QWeyQ0P~=vrPc?868!P5&_j96 z12us{3rS-(*PQ-D*bU3}F0DjV)CEYHM!lrqUwvt-3pw788o7^t%*eR9FOPUc#N^?PB zv`&viAV0BAA<^6;?vvE=1(rtj)N{iH0FF#|)h7iR@5;Zk6X#9X`5dJsQY0d_l(caCdq_{2P>y;6;nySq8VlMs4~*F^ra16B@^JXn9v>==ZD*FxIZ?|?C;ao<4`~qFhDrYTrx@3up5;Ad54gBDe zvvk~~SH1S#`nAt>G*wIYy^_)p__b1$wANMwwJ8*{hz7Z5)zratOoVBmE>3Jwjr?e; zM-y$gouwi^&RhMq(a8v4$&w0Whv92tupNM2CDdr8JZ%S7>YRL6Oa=!}H+ca9!QD*> zmRfH5$VmR@pV>3rq(x}t_h{k0FexftPyI#}!3n`MmK@k?b*w;w0SdUay3})#C*b%} zb$P{7dzNa{&#_242G@v+=$_FAJR4b=Ek9a3R8lMqCH)~O2dOziUQEf z3*A%dAH{eduhfmjt6`xrA=L#%-Ro9B+o)X?#Qo-vf>&@_mD|z?8~{KkHA^@?!n65s zs>ZE)0M4_R(mz#|7o@L_BBFz-QYiQcf7`!CWp6KbnQq4TQdo>01F&(mbgn`3#b|)H zd5j`~D`i9x3xZk*d9~sViVFrGyc22DZ$1M1l<8X5wpiE9Ls2}(!C07g4xz5Q3IUqm zvBNcu|ARM>XHmfUtNREkbva4gI7{c{CjwiWQVxCqbYt4Nfo6`7!OQr)O+ecemWISs zRk)Bl4GiZS#?*vD4rLaMp@9^PUWfG6u=EDU*GIMU118`@3y&I7f(woS2|d$Ae!HHf z=S@ukFd~?M|H&l7MUizbLfP;9OYWy^-a@RU^RX~$*Rvfyqaz@&`zGeRH}RFC&rDFij&c1Ai%h z$F$3RL_;=ZiUojHgU``~J zI1a+Cxmzc^c5v zpr8l4^nE6GvgZ74qW>+A$j^<-W}KA9;$T44zgC?^z+bJHwQ-CR;f&Q6oCsX~E2T+s z>e4qkKs?^Zo&(PYsvUvWO;b#R_n8?NhEL;LSGPD583hJ3A|3r1OT|Gjv-}OLi9*kP z2Z+cQMH+Bm3Cbz;wJ?8co#)7Hv1WS>o^`M%X7w1(idCwWUfub)nzO;805-P1nJhe(Be~Sh)sGU3^kpLG z6nNPmU{WR6#qco(6VKm}sQb!khs6^1KZkWenUg}JCPx9jey|VHwv2>xu=|WRpe%$*gZ9-yN zZV9}wc1K8UW!njPI?ws`LF3lvmp!kS^2UmqAKa-3TUfgl`k_(k3!is%z~8?ifTw%V z7T`I`elrw<-v6xj>G}@Av3sI5*~9OxRCYRsM8aC{&%|!dQ6Dm=CUJWnzO+?bY%S{c zuXM)_F-uEBf2@Pfk_qOzkqPVs2LJ;Dxo(~ohg%ZBoo-)IO@d;$Nycaoz2O4>-P$z@&P!P% z$PAnta{vt)jaP&Yuv$}e=a%x}mVK75(>e=^`zzCvk4;UWh#2(0+~DsAD?>hKf1yvk zPbhum0YEE0cH22+6A3J?ZCvYZ_tj;8_T9S@n>Ud{AM&xS1zCO!U-*EcvF##?`JcYK zR!($YmFTsm51A=bi}`GxkB+UzLj!9mM}RLT?oY<9&&O&}Mdcjk1jf0Mk)@4ELv5qJ zGN^pOXUFAsGaUz(&CAdC-Sk7e!7r+>x1|ZgnWdmP6Hv_2H|6XG-=h^&F~S>uFxZ!a zQo5=-9PuIo}~iZNnUtv)b9BYdt<(P`|+hL zWpcXVKG=SeUg02ZeD8#0sV?r4ZwFaeQl!C=hvWink?ewL#29s|Q^NbmSqCsfi+k}>v?HyNz1Sa2$Tpp{T-U%~z zHl*iqKs=%S{8#@*{at>w2;aiIY*0|A%yXMB;u~Y}@zrqt!})r#SI@DB{T*uT4Qmgt zp%9o$=9rDGV)gAZDM{i!BFDO1!%-uaV*J8#;DWVveKQ@NA%ZNg!ZmlaAGdlXkObz!8xeloqB3cZvqQ`h8E z!u95yHTX&uw-j2a3Rv&kAs12mMn6S(aZo99z1u1p15mci`fQd zDFZtfBWrSdxSa1;omKBiP1yzFOr7pgU>1IWZGIytDS~}mnx1>;(ps`SaD~bO^MNE2 zYN2au>M;FUK7M4O7OS>(kT+fOME`Vr{03lh5@Gkj>#+P73!Q^R#d~P^_&VOY*2`Nk zUb0#$HBM z|N4??nHsXURLQ6#YdT*U%hz$ zPz=4z>sFqtu2KBC!HUWETBSu$SXfj*z zc_;*OyhZ(b=9ADIJ!V>-I(omJ-`&o1XU~&cS@vAPa-CHl0IL8$r#tNcGi!aD9EbuZ>h}k9cT3)QxvRgc&8R4vYXx3*rD|}vX ziPAA3q!DOZy40{tvCmSm*7vS`IcmMZ)zOevccxoIVGC5Y6y=XiR6DreQ?z)GEw9HBt(x-Y5)$bt-Y86MLMOM-9&twup+8nb?{aEC z8^DgSN5(uU*TZ#a?dS3J>%DlA75Gp+*5*cATUo;INfQpJV zy=75xtlqWiEr9{c@a28CTlNB7;O%I>#bz7@AYXBytI*r2lW;Pr1jh`vp&GaZc(=R! zcsR}!V>e^b2`K_sp#_N<%89!>05AQ|8pXDU7Z(?^gX@4REWs*T>cuQcEL!=>RII+1 zt@S<^sH!Dga`m2YakR(TS8pN_a39{rh_1Xn%T)HYN4HayBvlVaPxun`=v%NW| zT%ZK7KkguIFn{D@#c9TyTzGi_zC!7$^Y@tKCc%NzsjJf5q?PPg9h8_EBr0?oRN@Q* ztlEB8W6vPa4PwQZk?*~w9C|ge@Ro^g3dQ=;MhU8~6d6+!Do=(_TK=$%i}Dj@pa!q^ zN3!GAr^B5}rWn*94DyH7GnJ)B_F~WCdrjxaT`&v%pQr=LrGu$kf7X+~OC_W$50#j4 zmeYj4HTpFqJUu_0_JIuH%@$@h9l(zti8SSJA@`$%R~IfURN&;FpkOmaiYfHU7YDVi zPim9)L%3s~R#SFiSBnBr%`DJk5aDYS04`L|vLN~(5j9!OJ#B)mdwaS3W3df#_w?9$ zuf&GZH!CcC^1nR9Y>56OHYjvOj9JI=Ui|lR3&#-S?10Oa0^-~S0b@uQ{$ta%^+C00 zW|Sg*Cc4O!X{uZ~Zf#xi57AM0ku5Jzg)mP_^_3l8>RroEyk~!(p&bf+c_Y~pDsMot zCn7A2PRJ@&aIx89UB!Z)K9I z@$$@6o-Dk8kkrf2=K;DQPZCMRlj8q;KC|9!=(Kq5>Rquw-@TLbrbbZmt`NLvfVfv! zDk-C6oj;**CN+g)3SzaqX@t!d9Qr;t_j856iVzdC(;hXa>$T9owHq5ZI15btHVyok*DBX8 z9vh^gu}$k%?-~*Jae7UX;htxkBfb(ZuUNR>B@tJ!%J4HJj*RCko4-tNxARl|tt zIIk0{538zFl9-Xn27wUEQ*sw=9Zfkso|1tajym61@~G?lb{{GqefxzLiNSDxbRLk> zT8NUI1z#7`+mxvJZ2q9V^=Dl}INgim*EX{i=Bxk0cI9EQ8E*lwU38b6MR zV@VcUTtl@@!kS{pc_Ns(JK}MdY+Fntjkl;x7=uj%%#tt}XPolddBe9-IF5hych?WE zv>3MxreSdArbE;p9p9d)JE$WvpDn>B5H^y_)_rMgKDeGNl&X;5PsdCrdPE{IZ0?7r zSQ(tg_Y=&q8?1U#2#6N3dwXtrkMe|LC1d0B z)AV1p;Ta>lq#*i{E z6NV4%4u-iXJISBU=_EHu?3_bZPixraUMcIj6}OaaZzLsGmblW7eI*R`^t#%=c0FmG zUq0g$6eV>{3*F&$yWg#L4crqY3Dt6+bC${Y#olDU0h*-xYS*rmO3oLUU%N&bYNt7R8|W(Tx@9_Wx-C1Uv(6`s7>>DfkiB!&Z?IN3_%0X<}t@ zHL0?s*M$m~gqY%foQQNGWi;uvU~==D%duH0Q665sCXbW*o3pE172dSvH z`sT-xadaQ(jVXs`%b18hPHm}pA{O^nh2T4?e#9nVuVH;)PZot?5nFmO*T*6Vz8`Dx92Uxaq#ktiiO>0i5>Nc$Yo-2P6$ z$Qtdjh^lvOp|}kCf!6fpwaY(KKh*Fs`eFDpZ<)rJH7`LHqZagL4wc^8L>@7_rtOD@ z`W}$Vd;H(~9Y4mQi^0`;Qa>_?mJ?%J@8>|@iJmq%*3__W!^LS0cl^|V@GS8faavH* ztaWmZ_%tT6hsm|MGlKI?{y!=Lr~dPh(Hj->cyYS%NE8iA^|NE-q zkmtwq$jwc>i+oDTVZc(Ir}KG%s&GzAlaHXS;*oIhqm6|6(22T&`(ytAycid0D zlU3+IRrp0!c&%L&g+K(KOKAt0xCiCezQ!A;UsA- z&^$9S94_X3y)DcBt{1}R+TU>lOgm<>?p;&r4DP%+Bd!1Vku_ZfDB!)by1Oog*0>fc z=$3t{Hy%7!Yp-r$Flp1EHfuDWh>L~Y5P+8T;}LhWM9fzZ=Oxvg|2CPvuy9w3%;ZVY z=6F6O1p=Voo#S-bK8`|^vU@<;No?#|s-Bi#XDkmO zyp(Z*EV09|ZD(7yMpjG{*$t&^wtv%tC{nhSbQ-;8PtAXISIOjheAcyn*r95CNnI>} zb}?eyISeptTko&l;}CAmtEvjZZM>0ue(cj^4jMYq(ed)C4x=6IllpD7uxnm*wX$Y3 zfD`?0uJ&m=_*Y_2G?ijSj?<$q2MKc?M$UEk*bD({zRsNw=o zDkZ~MB6Kp{E=jo1rt6eJo@6*((A?=qYQC?)+>Fca#18QQX}RV~%vrtDh0ai4gZI^8 zbD5()hw!H;>8Mdc8vlm9>u}^;?GfiM!D-Wc1fN=zD?EYS!)3PHAt49Ab%eLH#xj#R*Z;c9KR|NJkIi>cili^81>H_3lBT>P zl~aEE^s-X9M^cG;)LC2>k>in`TPGzXkc7DCH@fA(esbBUdpDFsJ~X%;+$J1&$Gj8q zTiYzYEUBz%7zc3}wp92nykLJvCND!3hJ7I9VYc*0ulLDeMVy}sba!6nSYBo_n|-YD zO|uj(bkzOO_yE(jsI6iC4C@w`4diV# zD>KpUq1SD}LJPVGn~``ye(;^q-8sWTldJbxe&a9zkQg7YiCA;DU5&D?4Z}$n@IFLd zr1DrOq-y~MoXkc=eN8?Li`vpo5uqEVFm3DRM9rM5zs(Ud|Key)>M%(0&%=zEk8#603+1NtLQ9a>*oA1rp- zN|TbZ6_tE~c&2Z{9uk$2bonZ~f|hl6b>wK}ezfR| zoVvW^L?~sLs9NYAOzRZ7+AXxiS`pPAC981zeYu!N6-;l4h1~8ZS{_2{D{Hb%NVFV_ zI*2K17uB2==jBqAU_B!wC9@@lt+Kxc%j7!5rb`T$YEUmFRo8BL(jjM8uxbFO?}I)e^63mqvpz?o2*S-_h7*nMSF* z=MlZ1k!YR&(J9jtP1$*mW{gRu4{E%6_rXJ5q_(1=VfS)qjtRV%%opBLSMO}$%q7LN zi1MIDwMK~a?|QE_fSQpMfb8<}wqJPS$^%0CjOKKhfkH{teWg5pPWq`SeP`fF`QAil4S z^1xZ{%Brq#%kLtUJ(m(jjO2V>KSG84zKh(ehK_?MnCqQxR!RAaXl*+E$ldQDEmyH; zq#Tn|=>%xBw@JIZh%xxZ2EUk)KlRl~WOnjw^VPDu|1oR);@HJz1Rq;>rR4m8}-(PAVj`PE_mta10@pKn-XqYYcZyt5}cX zWqe*Nb|Q93yhWmrb11=D2sOp$6nq_L9W(5@YW^YjBqiGM&!Q>yyyJ|g{>j)kXx8N) z$N$#yPrd$gOrXdYn-W4xS_ONHOBrMSJzYAMEjS^aJI69WCi1y0iBR2~Q{s8qN@oF~ zJvsK5aR|7H>`nW=t*tHLXL;>f3oM>lH79xR)Lw#$sx02pcUb0O&$!;NZTW2uVAlPn zwLD+hJisBODi)jjuEuTmRkkmRvX;!UFCd&>^lGesL%x9N?qSXTezH78oj`FY4V`l; zC#yVpl(VX`w7G&yp}qgz>m%PPSDNWRJxXt6S21a+Gjab{3`fKAQVLM2jmGLQevfHfl#I|o(-_i!J7mR@{XwAe&aMqvA%yvq#ZhSr z`83U*grB*nk$yio1@#=wN;c#HQ?iI~Q%H@qK*UM{0GE=L4D zFe>lxkiIM~o_Fq)o)P+0M;Dezoh6!v2xUdz6;H8#)h*F;@LM9$D6f`lfA7(kw*c2S z;KbpZ!%AD9@P%Hh-6SfSlO0JFKY#tuXXvvvUw<}OC?OuEc(C9fN4~g;NIl~*e4-A~0HIleQp32#3L9yHLO}!r0l+ch5QUFKA7H{fcR+u4^8jlwEIA{QKVK z&>a3KJGt0lFu|UI*NQ-Y+1}CPGF6B>Pk{ZJGdzUsm7Je&9!^mkQTjf{<;S9HB6NJg z_XTZ)>}#Odv%%xb$wYos`Nqiuu4_ID~ed{#a&iPD9)6Vt%U zmncj3Oo8WK6&1T5jJ%;08y;lho5h}{|sxfxkx)Pve_0^$Rh3%HXA+K${_mQ`lPa?dSluz_(7GbjvepO%! zU`qa$kmZaSfjpwlsI=I4qcbxzuadW6XJK(R1UdX*@KphHd(J$6*|2g0EVpG)`4>hc z&BFQbhYAVY0Wma?I>n~*JJ~%o_67F1qvHUI;&$Ih_V|j~`#l0FPH>6j{?d?W#aFe$ zwb+?vBAFYEh%J0a`q#8o+T-~Nku=I^ z!)Tks>77&(#-wRcgQXdr4r0=-oC!Y%1au~}dGZqxX_~-fa_{z~IObSJ%u%}Bc;_(ZLgJ1$&ZJ=+j>D0*bK^Sc7Ag5 z-UPXt*7y!Exmu_v|ZFZT`C$(-JkEXQVoEbudYX7pm;=XaYTSQfH+g{nR5id&+ z&9~_45XYM~?W;!#nI&)k0eGp6ji~?5wIgG`)ymGAz0YC1ck(|O;wzd&O5b(PcoxHd8DoOZMwCR|8?jC&RCP=u`aqBX7C?OLwUN5sB z;a8u?SG<)xkDr=%_e-=y>~6|kKuczMz0XTp-~M~+=8Y?B-7Ak(dNRSFJ**7!FRkwq zYbGcwzNQW()XhS{GO*DSP(Ab?=*VPfj@q*8;M(H z`u`NzMcBWiqLF-gy^_jpPS+Z;Qs4jY!}Se2Ybs}2*wgXK{ckSP*@WW8`f#Vy+;D}K zucqQvX^lRMUTeS%xU~A0<#ZLCFQg3xa!d;E^(3!@Ab0L!O@0U6#fpeh+A?1IVVj?_ zaqBXkec3l_-7%&yHfbfkC5)vXxFdbP=N#WjzDlFO@#B z89zgR{Tdsc$A2Kplxcg(sy;Ru8dZlETX4Fj1bU?$m4g?Kv5Awy&ZNU3*pc)-+KunUxU|Ax04x zahiNi0Ohs9e=ey?a9jK}C~~bMbS}g4cR#YRwl}NQYQ1+QN&TP=q1;7t6E1&d zFUfxNo>Uyp3lOU_DN_vfAG9+?a3!5c--+~V1bo*hO8Wn0e~p0GGv`RIpEu2fV(EOg z+=1b^@@7YWoRKkn_H*9L&zTO05?>4WFUMyo~99U;M?T5{cNE3}3 zAQ0>?n48?=H()|eQ1k!SK{nF(^}n~`lUkyxB|6zYxe~iQA6{q_{+5b1KJWccXRt1| zzSOe!Rkw#CL^N5|k@*F7!im`kOkl%hBe>bw{NJ_BVLC->;o{7oTZuu=RurvaB-t<0 zmyy;StgOasL!|6ZR-M5Z#u=gE@)$DHob$NNISmxpc?M!eiygWtCg$ z)L#d2>!EboQV$oQpo`Jo0}U!)cv~A0=X>5`(Ml!jLFErr@8&H#I5+~sa81rCMa|V_ zdHn*J5>MtxYs6z!)YS*X13jI$J{bx_XuKFT1l(39GMYncj^>r!2lvZ)tez#sZEi-T zo^2sErm`bW$tABn$EbK_j)iM?)S0-Tn_~=k+rTWG2;5nNnX&{WIzek>CmZPHJ3%?t zE>1LQnpe33zL)R#@lSr&R{Z^of*W3axAz{AHdPTZKZOzh+Q}1eS^pg4E9#v0hqjHQ zwJh2$^Ok3;SHPR^?415K=Bs#EcSsiI-qahd6hlGd`AKVjYo#e}yPs$Samk{#FL1hs zvM}MApGr5m+^cXv2*A-y{n7ECwJMy_YMh`B{9=Z+ZZ0TwkCYZ^luUoZGyEvJr(hpm zOR4S1oPo%e8W>FB7vA%y(WwfQ1*j&Z&6_V4~)c@L_?x?P!E6?=a+-T#KKsVGUSsV>;upyv zJVW;j`KAd}YO%$c=1+eAY-Iw6ej9)|QDOd9XBVPnG>2TEx5&;oU+;jEp(~Gc+M(;) znx^hjne){nRpZrA5?8P_Urpsx8<(_^L$&n4a2U~7ZYHI43yMQ}Kz^8%BS5}#QFK9% zajep->kYd)xm^bqP`Kdtd!|W7HE1(Vw3B2S%;9}x^ICgZklB&dttv=~^^w-$=jWL|Z%;{y zO>1_}KZ z2qf8JDny<3Kllc^^pEm%KXE1UrYpr)lIyxz57g+--}3m)f2Ve=^65kGmgXtj|5qq@ zJNp?Uzma1i*8Air($1I<9o%svw&3ehH;Pg3;71&DndSd094ARDK;}{9CYdL{BBwHH zNVn#2-6_we!^0wK7_*GJ>h;fTn#jjya&;ym*;RH(E{2uh_;%@9>u=@OcL<`5tR0ua z(F55;`k30~zY+2u1cz2%alLR}`AzFerw$MHa~9vFpW%5ut6rc2_}F%F7a41Vm!J0AI24NvU8kKj1`<6?gx3K>yk&&8iuY8fuvHpnpA zqgveuc|buWRI1tkw-H<{w_8Q4m@T@%o!E?DX$S zy}1BAPJe2iqL44ndaaH}uL+UH6<9Uh2VcA|X|fe{n=(@>(e3J1sNY}8bPkEMD?Csj z(8vN#=TnF&A%^LKX=(OWMCA1yoG@1Cs=x)U<$)Ey-^*bLpY#%!|Y?3inpVUuAMpKB=@stzf6p}Rz zxi|!cnZyP6kZ`8*wi9Q6(kjshp;OCoV+##3{PrCDa>w>r(u6FB1pG~Gaxi&3i9R|* zT&aF1ZY}p#Xz5P&A-VgNih!zjihMXJfAQ91#^AHk8a{TC&jsDiio$MLBJbm7-%NAM zCw}@+_LgsMhqatWu)oG`NuSTS9$ z7cn1X`PB&9?tXYNLe1&(zNmvOnMhuqOs*|T(vjH0ePt0L8_O7?+FT{^AC@fW`X;{B z@qjVi5EH&#zDf!Kk#emm&b+lx_J|?_GLDLhDdZj5?5?9@u(|O3xLKfSk}rKH;)q|D zso$qjXxp2kqBfPr!_|BKid+4)rZE}1bLHb!t6yrW+H|SDY^X+ou@4k~jkK=Oaxc1h zzPH+IV+<8pyuDS)vc~Sq$Lt3V@bdAd-^-j0MTwoL1q~ECbj3F-^%_$j zhveZ^bqPaazR;GFO~=kZ`}et}+j$E#?D7Aw_m)9*Y+KuCAUFgF?iwVxyF(zjyE_DT zhmhbNeBrLa-3jg<+#x`4ce$Ot gJ<=wpZ-~IDdty=HltqX|$Qv;gya7#DX(>rq_E@mwl@f!!{65pO^V0mkhCjvFGm|;7B;z8TghD=^jp#NZzN!E~U&X2(pt> zhhGpW4;$7NP(;XMbjPD1n$Gy6+Rrrf`Rgj3AjhzADUAq&>M_t7KPcMW7Yo>Mu(;| zZo{x1WA+Rk3BA&1SOi-HOHD@%vaq+Soh4;Hhq=Y7HVh{?UOYaJ2W^P_U6x`%zNWjeKRu2(U)?( zi*cGIM`D3n1J!%6ad?`YvJFkivO8p=fF)t%MZ#NDz*WuJ^3x!F%3dA{lIZLYFI{js z@TlG!YS+&aIagR}?TlGxa#<+fn>zMY3sm~l$>W`M*b>QSW!-wb4!@^briHTQY}gi- zPmpHrdzk%2E3`?)W~sS5wMwKU`ayc?6KLK0{!nb{Skk7o=j=SlmrV7IG`7b1(Zexs zmS9-&b%&`g3r;Kv0CfVwB4dzdg4YlEuh$4tL-7&H>xYaN!*R1kBMr_8#}Vm#v2@rC zZxyvd#uBT%G?rmEdMnF%uldezD-1pI*|@rSlR_4jMq+xnsx|EjrVM>&XhSw zUmON%5{$+(IKr@V+9lH*0QiSt>KT(0t2BrMd|5ZIyNBWGD&3ojJxPpV(p3>R+aMWv zu=(?aI?ZU!j9QoZ^y{Q~$WGSUBfjGkiUm;Lx`nQLs$0+8d;512DFpXB2a#A1ot=j4 zJPFvaiBzkazq@b+Kbo&hm+IJ6=fyW|BHs~%uX_D>w6tgCuO(3cz6bEz3 zPzfrf1?K_z8lYEEQ4a=xu$>&5=>CqdZ14j6?8KIzcl%pTnO4gP$aAAEnXpGBz=Z2z zC(NM0ad2tqd~nU?P3Ld`uie&=n26LWtME(NWD&iX`S0Kih`YUZsEln(IS`~J=Uio62E5efa|+fx z1B<0Bp0i`HWE&hW*hYRR*mqyvU>(}4pIoo!dND>y&)@$%T=GD&JvejVf551sF(M?2 zv@=!!BM=?Iy4;>AQL8o5w;u#lu^n(o?NX%k&z{q}qh-`>ZRcR)OTv_&((oHo>XEi? zYN%loEEg)auL~PhkF4GR!TT?h`7&+~HB!y`J7Zl|G{ON4!4lW zAPfKn1Sk7PbT)h4u|=A`FO}#D6~CE%$r|DhDh%j7^lJ2CA0|e6v5oy+3Mep_^QxG8 z>G*-LMRsMS(TSS9M0XhLU^8C&Z$k(X%=-yM^vR9D)c`N^^_I1CZDDm=n2;XI%XJKv z!mz;?(1MT3N3enRdr(6Dm;jXJ!mVAEdrj}o+CBG zDi>$S>>Kt=Fk&bU+pTi_horfxv_$pfJcbd9v^k|bV_5=;S&hFrwuS@nk=X zUB?GR@frZHKi118sn3JH#+jR^YgVPG7Nt^c{2!DbqjS5bA< z@|FE-L7vasY*-YC0 zLwlX%d}k9-qJ{aFBZece>aWk?xJT!mPJ;;ZK?d&Iho4g}%QPxt#WZZO(HrMoX=#mx znqM!D3FlDApo}fE&I_FfrC>Q^MQiD_oIO(TV5EkA{pB_tC(0l=%Hw^<655+?GuIjj zBv|S!mYWer;(JX6f~a;iA))dFZYB8{B0DtriQCI?`K>NYM@rNhqX4V~^^idlTmX6` zE_*;azjq<1(Go?rk{WyTh}AH>L7nxU4+sM3Pl;IcmUj`!1)k*!Dp8?#E0vL^Vguz|#ubV;whodjp;7OmND1 zp?3l_YnV{gvR0^UyFZLAi4NCUE_A|vYy3{VQ(@qO#2=*A_m`R5uJ<~T*FjW!3DlEk z5&-{IyM?B@3J))w=8SkMjZc#KTh*;=?$4ZyOxkR#aIsN{5(EO^pvIGqA()q^ou05) zu(d|>x5N;(W~kU_E{Awm;M!}^(F|!flft4pUgSzArLoNfHl3Ld-1!A(>MRRYLnMCjT z`V!$_U7mMMDv{Y|#Pw}A>8GABW4&_*nfae{h8#G>RZ(fxbcFD}pq?I+QVyXRf+|Sc zR_P-=Uf+Y%C@ZOAhjpcgoXSebvu#^qROhMLS&=}37-S=pcJFmdUfp-~2$>@Y2aTQ= zAC#3LDb4_J+}ampef-16ex7xMdk%NVQ5F_ETI5FdhS@dw{8+FzT1IyMT}q;B#8N}S zy$-z~O?r=IB5Qjt+hZ)$0XzEd)bxC9Ms`l;qpFe#Zy7Qm5MW*vL>8A1Ow>(yt}%_O zZHy3*pbp`Pb+(u5dcPWFV;N_NWgg!SdM!oPdv7k4Vt*|63fIJvp8v;oQqmP+5s1@D zf?SP-4plshKX^G_(J7xomM&X1M3Z}zEscB9HbPu`T`CX6IW8KJvt3a7NF(n)O{S#C zXF-lc!J*&~G7iSG_E9v*&E{G>S1^ke?m@*LU#=1DB~s$$f!grf4`T3Q+>Tk72*MOw zs-ybRit`O_%IH#qJ)}OaT;n_eY?1iF8(oHHFfJ#H%^>D9teKQ$_jTSDJ*k;0tC>~+ zGNEWCiaJ@V-QpZh!eBpzNAUX#tYS-RN zW8-d{5YCSY2YyJDh#*gfhUt#?|AHZsi7`?}@}c7b2`Mud-?S~|g)OVNa1YNCphxn0 z-QsN{#OgEPC!_+Xu?-Z9^Jw`l8@PLhdgR>j$DNqe6eruO(Pqvnb1>oLzI}%wg+V-= z>Lr9=4v$Mb3M#S4RFMGD^uWneDbgYlGV@RBp_)O6guJb8gNS)S1v(9AbTVwED}73S zCS1%ScAGGt)U>7!_-*~pvYZa;ZkVcncuK+-g_Y45+lqgfGVl%5{|6xj2H8j~AdAD? z%K(1odDfk`6$tnjJW_fmEF4!?I`9K__vM?0L} zd{?HB{eDt_JH5`yzUhZEoWkeNIIx{WH|D`+G3}U_Y#8u@fT+>ph&U}tI6;@4Dh(7F z0Ux7S1JEc<_Ck5)$>QVZUYN6?q;DHRJr40BlaT-p#j&zBO>m;Cr2zNA{+!(&sx`wM z5lMi`_DJM246D_nBj(K8p<@+gc^MnBQFv1)6R7nL-;yF}0|r2>_RLgdL_!7xeq=9goCj!#n9}4a8$kkZu!QCr%wKR2k!>W_j8i!npOc z4u&;dFjQ2Rtj*_IwqLZ+TBy+K))sKZ5^o8%r!aQ#1A3|S_%6C+J)_yT=7A*-3Z}Od zb$G+c+<_i0I~rU7km=KnL(FK+;VRLoF*7S(TicQ6wfI@LXe+K^|kQGL$i64(fOI7mz`=r=&w6(q;Etw?4coim$o zn2~iz2W&j4HjM0QVf_G2Mlb=l8^Mu#H$*wZNl5FOwW0KH3LvrhuiCGVA~U(I*X}uw zTKQ8vbY0!$e(ZznT%14qP}Up`=RS{Qw8DScz>&U9o-Zu+Au;iz!)aj*`8a*AIVZ)z z5PQ_D9EG?E%ql`Uw4WlZXq(-j(tZLiuf5T`ZmCk0SqMzAMPd=9{j%1(m^kYAn z6KX8c6TVdL%{oJr>YZnYjtY0K3HDOx;WGQDdp8z`z{j=x*3%m#cAM>Z{B;(;VbGMn z8QZr^AU2(85iH-iuXj+CyU`Qoe%B&=6Lv1ar-r#w%S7x0R4$GPWW@s@))d^w7 z+ABN3RdLwJN)332D!uBh^U(NrL`LRb3kSo_%O*1gCkt;YjXe54trxF6^+U7pJ2Egr zQnfHtze;zrd$@N~*5Bx#xlEsuV(xqj^pJ^>Tu6U^T>d&M`dokf&f$1WzOmCxA6x7m z0C#A#8i5JFoJD*v;D7kezWiji2Oz|_oe#5h!&rYhZuCrC?5XfI%y}MRoeGR%Rxpa{ zGt+%uL#kkb0gyTHV8mR}iF*N1TY)w{?-LXkKG&|1284?9m6FE)8t0` zeQ15mo#B6Uq^L@+t=sP`c=4HmgRG!{(x$DD!_5dk&s+yYd9?g6?J;9xi)1|i2d?7VuF)} z@~RzqURTcFLM5q|Dm5r4aaS0Cjo1PyHY%lRmI9PXiT`90?6khf|B-T8mFi0Goo2;^ zeL6^A$`1sbTq*($QnDNlAL8g+FXewijI8m`H>XC>k7x&<*six&&SkkG$}$=VrSzco z>-n*~%-V=ZEC~N%s=@S@QZfZkW7(H#kSTUkqZvH#B;`3oITbuwAfw1Z;A zyvTMw(Ni-RPv_ozF`|&NJ2R7Rf5@CT%Xu#nC12aB%eG0#~<72q%f5kUD zbb(maH*S2@pvvwq!so_eQoxZJ`I94GGXOdcOElXTBf@ZxSbx$dXH+KBWP zdv@w7W{gZO_GErQV9|-ioz2ruvY!F~1XEN|>G1k$>DJ+A2l9{`+?g2QQ3&E^f^AN3 zvwiD0pfsA=IrYIPK$9Dr)pk#1@H6xkMfuN@jUCl>vG`nCm!kqak_=cdZW!fdt*Y1Rn z+HhPUx9S(2DL+q$Rk~vK))mWc;JlhFTc^d?G8k3MbCXJ8;@FSmey=%g$gGvK{z0F2LR~d2UFkchms_CoyExp81{Uco=x69%2 zz{hgiE!iY7l~uyOvNeFQnZB?HYLJD8>;L1Sfb9{ zV2g!aO3y*LI~oW1;HULzv1w+Y`<=;r+S`~}RkeY3i!@1z41dI?h=K-Ny`yFmmpr>< zv=$=-eWbk!d@(|z1R;c40#17l2RXxTX-Q&%ZvU6jLx~9vVu?b%^0uH(GuJG!x$b(S zf}#|BkDE&P#B2bU4x?c&KGLT6sDIkaPrZDK`RMfp^$MNY5HVPerkVWAaQ>rQ4ps`R zyXKBY)+;?Bsa6quFZ65LJow-vxuQFA2tSkI#76+dIQZG^nl;}@jNgYQ>tr?Vh)j1J zMgkE%gPg~J$OMDzTj$O-sm_YLs!Rb&peRCHwjsTQ^t!0oMsNiQc2Y{BjnFS;P{3CP z(u^9^;)}t8Ft}5|Q-aI*CTac>ioF+x6^L8ejl7>sUxW!Kr=EzIlp#BdF`xdSqddZ5 zuF3s@i}@la3rV9vV!uGjK6yztuqxJ;YVo0@0rEE&G?bq}o-Xxdl}q}!F1L}jGeSv^ zZFOqx0lOU4$5VfL<9m#RmzK5JjWxQ7#~i13ewuJAmI;!T+@&swZ;2=AZ_FlA>1>A4 z(RZkQ(-2`ejkR>WDqE^`y@71YlLQ~1dkJTa03EEyQ_H|`rdG~&vw6DHqT-2Gx34j`X`$W!QEG?O~uqpHGJw}is^baiw zlRN+Zpe*RD)BT8X8+=+;T`5a$1R<@=3j zY*MkuEpSZlI^GrGw~h8s-~MwYKmh1rZnj!E|7fp&ULimMH+^1HJjeQ%6uiHwg9nHh zovzlu|Ld=R`NBf@6;|rZ-(mctE5Env2Dn{*e6#!VTO|9BQ7~Zr^34RujvM|X&Hsn1 zQy47dfzKNxzY*FWqtIgjZo)xG&+2`4@;6^I5XD0GzWbvqzdhBihYY~Au=w6Z3jWI! z{ME-k(y=SB%uM0Ht-|!sKl=0Ag8G_@WNd#T_aa1g7v&Q|Qhe^E0O5PTM&503Rn@I% z)O~KitA!BmELs!v;6k$9`ufk^Dd3xr!a#Jcq=ljKTd)4;1ytIv#Jekyy5Vy#1Dd_1 zA)3lYUE@Xf^+*37R_ni0;pr+o>u z=okk@6RO|Vph>9GooHdID^1h-Fb*&zlwb|9_jiFjTG(wchKYCNOSbl3*zXM z%oy8!J9!sMcUGcUZTSddf}R$St6%*3k7j=BGlI1*7Ku0@tUda?Fpxv+h$1L*G&M9r zJS?rH|Cr4GP6F@`Kp`L&iN@!8YcT8qw8s;@$r#0NIa>}SK2k9M@4ZC(sr5Gy_n!+3Rq^86YoRwMFBHdP5?6*rBBA}FiPP0)qOf&f z-M$b`%#`Uy8cY4#JpDb#Iz$j+m7mFpDV(l3nH7!gTWReD3fkS}XyV@pN(J$wl$4Yt z(Cdz<%QHVq2!iASYJRKlnN&~^qwpT#IA_5_(K(4?+f1f{+hr@Iw#??A`Vbh2t-~7a ze@Ik@nLkH=ddINH$iy^4DQ`q%2?C_j!e09Ch+joM1RqOXu_rjd;|Vx>^RQv~lOhC) z-1dayV$$mj>2%{g`$}6FWH@4?Xt*!7X2eA(9h8NnuR;|-kgfRgdJTtY+1@~oj$3WJ zynip5d^C$cY*0;gb!=Q*I3YjZXb7FcpHu(O;zPx^1G&XzIxPcIc3mRZq#P)Z@3;Ap zLw?XlnVM5%Ch=I1W0Gy~a!wL2cT(w_yAE1N+0N#u|EL{6XWTN|TsSGZMi)-eO#sUuhBv?vpmZk`zu-Ws7S`D1S(~(T`Jt1nAdWfO6Yf z0W?JqVgKHbrEKke&|+6t&}-5lSo!E&OJ9~UVrvYx_iHI&nNx=y8j$frIy2AFj%yF3 zP(c>5AJ%D*e?RQ_D-=d)7C-*w9*7?c3H;5l!H$bUSEwzR$XUybZ%`wMo5Rgf?(Jqb z&oEKe;x^t~3VTx0th3^A{t)k~^LKF6kLzH!7Jr6Ru^_;S5l)n#QB;DdqhWk3{i2}D zBAJ+;BxO8tG5weP@1qby4H_+iTVY|y_6CUkNr~TgehEzWhKcpRS?_~ohxH#*S4)E1 z?y6(_vgl3xldepyuZQ+IuJ=-isEeji?t8s~lwbI9d>b+xNuXm24DB*AT6`_$Q1j-Z zhu94#{Pxg(%SSnm5iIx2UE+Jx)6OsDEO>0NM6N&Rx1u6IYkGa+WF4Bi&vFSJj3E7F zBa$39Y4Q$D9S70ReF*--4>3RK2<0Oo{0h`zzITa?;8d|-5WSA{-9V^={?bn?*lcW( z`2zNl5?g13>R=A(voPc2?-18NHVjb30fI@0hV+oG*=p1q3j+2hGDMad!o5*KFfQ@y zT2zPig~XuH(>LyKh+<8Bl<3e0VL2-%Xvl_B1@xWkkzc_T`@L&EO_+aoX(H^K;;*=O ztMVLaQp$adg7BI1uVP++=cB=k55Suy`w{}x4PHnac&}uFxt!O@tUU`+Y$Rr8U~-v- z{1cWt1T5L;)4Nz$O_*W|)nH8-3?lsH0KdOeoc?pS4w59WMh!1XoJUDBklf7x=z-kpI+nGhy2H=j+MY6=!I?)`*c#@73LCC zfUqZs`D^^^DdSdtdOO5ZRB?b27hNc2Cdl#OAyAX6Mux6K^{>&(kR*5&R2cERABaKJ zi~y1U!-oI7^38(rdoOaCXW%U*N1n4GO|M@P1=0>n0i&3O#R2>ZiK_^F1Fq2?F@d?7^AP%AK{{A5#9 zNJa~7d8^+@eo?Qo{8{1n!Z$@QP{^nwWUkmHmXK7SKh;^OJ_>G=W^%&?reek@j6#V7 z%20^p0w+O%BQC8#)Nn4&oz%50#SRtu| zHCs(kU5i~HGV2bdQj8WFl|+Byd*uYrM@r&5C)~&unEHrW8VQBiKrDPd66o1%G); z|5afV7=_It!R)W=cPtR-3oa`JFRXj_^$hh}qO~=%T<~DvKWY`R08LRq7KhSaJkh*E>eRej~0MwoR96mVFXaP{gHm>$8h!0Z!~4 z6SBVPiOXzAqQrE=mS;$ECvZyRUjI#Lk<0^CHZI20!cN|qWS?ZKx2_QHw93I?EvnD^ zz$|V*`Zt64f0*(c$WuQZE{$Kjg{msMj**|dvN*w1oZ$3On?3WTKdQ8;82mBl3a! z2PDv_wdrCe$jAUJ3!nn#oX=qIUB4-y3le2uN+};)FiWjzZ|7 z_!(lfa3%|9k#6kdE8RJn4Snw=2{EbN@p30$ZP6ezxk-~5yfY*LXx4!o?rn_2yXWxe0u z0}gsqhAL}o>n9^7Dn9<6*!JfJMuLpCOHxYu>oJL*6eIFb1)HkKf=O_@I09IhiVLGz z@5ajyCrw)bFjjY6o;7tsJn?z8)8qM>}j56zmJjh6o93*p?+cG6*Z$J`<=)X}S zgl|P*T{Q__VPqo4cpE)*;N3Vm8~{EyPUMWww1Htjfg!W#v;b!0^mhWcy#7#b?I{ZO(G-k*{N2U8JwFOMDH^Fp>jj&juE9{z@rPsDp< zIN)BcK6^$9G_?>h%>;O<{+N{inlNeVzDiwW7i<)g&Y-AHi}!Cxg^8Ir183@`Lvroc zv!eRiSd%o+(TQM$ zRzJ4^wM7DxkZ*}z8xS@Jw3P=rs-d9}GvCb1dsj+PEkT22VqL>3!`c{{cn(g;XN$gm zCGmas*^S=bj!s1Gcy*|~OZZ8k|5&y!I4~YyB9TAAQF(EZvrr&hqm_ew(-XxJV>LYx<9MRd4{|ZM0{-x0i&0MREiL@gC~bG-l&fvE=KEI zNsM>DP{JkOw!qFFe)A1;r+KdnakA&kKL$!jm>^^fVilpFHw1bf$D6@(GitG6 z`CZYnaXaB3<(kDQm6wj=RU=~fQ5IoYO@F{Ng*71$2O?+nBDH+TlV7_$0$c3eKVM!pA*)}ttnMbw&ugMgu@XnlA(=#yP=v(Uy zdSEuL`& zw|~SS5<$rlB(_EoqQH|!D0~x1M<;FKoOC$%QEp@@Fr>$Dl@_|+VyM3%9`u})XwN_c zUermp_Ck2MR0vz{Fbk*`t48z{MG5T2wbE~-DF z9unXORwbE^6S*GLUCw>Bbv<-fG+J|b=)Q$@0&`hNKdvG(Pa*{*d|5lE#lLD^{aedp z$>4=Bl2qj=7SU7~XWSC!N&*Gh58d~2@;ZhjbWFeURQ{)l|LZp%MQ}zf6x43sdw^;C zHwJ`kNd*o~Ppb?>A=-p`=soX|!x8{zG(dStnR(jJAR+cs2B}I6TqyN0ZZ|+PMW`jF z=EzYS{$E@E^^ec8MA$6EVG4^o;zy8v1ug~duHos59+#c({ulG}cpqjHA;B+7LTySq zWEmdDKcuI~rE0mf^trJj82GLSC;`4ow4$_o%Z@I)O(S{<4Ca#m;LI4;ay$8< zpF&yJ0BL?FVUA08U+^z#3VCK`DFIfZpdTw0n_EJA_uj$81d}xX*V9enDwLoR^;xNZ z7axFJ@ilr+20HvCWdq@-pd4mXg{sZ*LiMk>=)WnxP`(1ri*L64vL#!*ii8gVUPX+) zJHm)o={5N58a$|Ems@!F-&qF2A9k{-mgLYF{j_;NXa&8FSyw5MC5y zi9;gp2c?Taou%iPwcM&YGNr-$T!3(R;zC0WNW3-XIDgeleP){VY~hWdB@ASwjNmub zW2v<6KgxZ8E-cDf4(I@!&kHBN=S2R&7#M;e?E@qgK!tVw7HG^wQ#BHfRwW&gW6!GB zfXj48V=O1CCIlP#6Vnsj89hF7x?kKgg(`tMNs2^1u4I7nJxT)Yx9%+cERDjQqxu57 z933ljmx4}3__=l2p#Wb(syx>bpiKUHS2Mbt$N9$?e=~Lg*|8J+;#X|NZ8yR6HKF)p z?#o-|s?+D55g-P?=_GTD-%>}r(gXr6i)O^ZNM1 z0{6?DmZ_zD97AQj2!D=QX9)QGnuv71S9{M&`16kfHqd^jD`itJp?Aoi^~3s7$$f2? z0Pcn=s=IieRecp0h4O<#(nQy>Z&%Q?du~ufbpmU?(H)ZHS5ttRw3${psaNLde}R5wV!@VIhh9Gyi{H?Ti9Z>D#k>!=-1}jRc4iQ-NnC|C==W>*3ofAQJj` z|5J_qxe;Z+04;`m+Oz|NE-HnCkzXt6v27|2HvwR?8?YJ#={- z=hvxr{NZy)?PIfWiU0Zf{oU>u-%{g2+oO#)&JATWBM5z*OOx1r#Tz1J^H2wR@J`{N?3T{Y)zjx9L_2KW;Z*KzL`Ksd}&2`_WfmE zpWE@O;G(yM1@+G;aXwi4>n5KkKAXY8K|}HXI_LpI4}b|g%KBX3ld$LS$ptxHXev7J93Ia29JG}cB;v1Z$=bQ0s;OQ?p~Ht35kKr1pb?-;Kfz?Wp-m-*BTry~-qdjxfW0 z9X^U@dEap%hBT#e)QeuLKI*=-RKtxDioU9DdXkgS`})L#&=c+IbUIm=hKJ~!!sj%+ zo+P;K+T=B0B=3@4nKiOQ-hRJg+xB(Y9-K^da!|?JX1WtsZc+>vnwEZi|LG>V?W8z2 zHAdlIQUR zf7~#$lEiB&cz^U6i7-&}Ha=^|!{?+syx$7rhwgM$c0vxbHk$9#jn7TX^-)CE)9u|; z*6}c62EC38VwG)_jHGiu&XRiFWQcmkD5QJa+`*Y}?SJ|Hm@y!wwDTO^{VmF%YF~_J zurJ?g2pcLA2Y%D$<9~wp**jh%^+(&n*jjm5@?o&r-ITko^Vyq$YXi%QI?&AfFp{!z z8?O5bk>hEZ|AAsrX4yyW_8#8$VgBMVTYfR=eqiP1hp{APpjGQl&$iEPeyhsjK~;_5 zS5-%9_C%C=02f1*e_Z!+Cv+yYlLjwmGJ2^{)Mfgh+5lt6%a_l_+2bi{Df>Sic2v(G zyuf$7!P1idkDipKvI-!Ee72AH!YFg5$=Vq*tIs$4=au*vGoKER9&Z=;Z}v80YYLf8 z4w7{}H_p<19{Scu9kxek-(nMl>WfrrF@uksix*b(w>Qu2R%VhrVw-cLSv zD^XK1b=Xv0;(~+v7<|N8U$w{V6==S!mQMH1rHO zfP;5wdU~2ibI<=BkAd$8Gz+mSP0gc~wv`_x=n65gWMnW`W-LI-LvC$8zx-QpzZRph z+jWbvnuprz>KuZ>apU665KFcjHq)eXIpT4mBGtZW`@^isAv&98O65lH4N(G54D?g_ zf^5UhI?7T0Wov7mhDqy33CA^$h2ep1Q&|Fy(OgcyEKh%fS50TsnC#Kaj4;(3c1{Os z*Dgw3>F0EwYlaWvJg %Pk)LDMAz750&VZy(z|U_w$&``_5;*6sBau|Iwg)eMwgF zgf2}_pjJoLErC=@NZoSl4 z=5;`=dvmHO%L&;FkXfK3BHB=f? zsg@S7wt7S^_sXWk1`j8*1|;$Lz1X`9i7U3#)NXT=3?r#`ilLB(ThVW6tocrS@Pc=d z-s9>(x8AHDRJCoiCXPZuxB8__<2zL_3Yn5-)&N8I;cSJ)^gd_cBL@jrBCW;rKpgdI z+$B&n?UC=pSEZiP_rg%GkOMVL17G0-n`}tGQ}nBPoz4&zcdd;Ch@?U8@~Gu2#-sM} zs$#xWmuqsH-gpWp{HBszh0qOoIBtmD_3cG+w`BbKG>6M0$%ihd(G*VM{D=cucUtaT zxI}Nel7uofr<(zE#$#LG30GMTGI{M-$}h^sigRrn)7VUAA8Gefouj z8vFn%xf6KscE6P}12LI=Rjbef2tn8%E|===ZFY6;po-;u^$(yNG`scEC%)3DNdCNz zeD@lv9#g;DonQjm-9=7j-4=IVo5xSUi$dw%h(}Wz-U6bEttZy3_;NCTbSRB^)FZyh z8^80Vi&?xBNFi6^3%hKZkU!k)KyF@}>q(YI`1}Wnz4&3tII7G%fy1l8GN8_PeDLmm zpvWDCgZ!s?mmDk~mzzC`5KDAO6e6&{KE4@Z9}zP%T%_kn|MS!F=a2c@GSV*>?hBTQ z+}I2Q&aE`r33)H8w2#_-gd6vFe!*{-GYyhg=*80?ezZpf&&ReXLH<)%lvIf!PKD;2maPJ8ST*t|k5uL0g!;(Rm5tgBgTIa}YL9VpY$PAl1& ziS^!Lo1RLsu`5xY)cbl3I^}|%_xb>b-70fBLI~o+8v|Dsi-~fv$kLuDRwanGrN&pu z#xY~xUM1JAE>zojVL5+iA{Bw5|6V=9cXEoubzTRYXZ9Wv;uL1i*F&8eFK@zbgQ6py z7`~T>!MejJEReN0-skGUrN+CILQ7CcP|IbJCWbtWPBX81$e4D2!6m~xo4g0!5hzrA zEtACK^w>N%(QT{|>(g6uW@M?~o55t2S)T-)03_zQiH*4nRZ=;c5=Knmy2ASf3wTcBUE_u z2U5JNyLhX#>ke#Y zUvs(4SA!$z54Ct!D#(&mNYkQeHEX&Ti}SL=X z@nY=1hK+jh>*GlZFk!ck1knbVsX}>xZvA>Up!o^!el1=A}c}s_8E3H{`@M0scLTYNEKs*#kulkVBU>3ei zq-+Yvscwl_=T)YI1s{P6s6yiozmV_v-_hXRo*rMCHJI>xKiBWKTFT>v`W%0_O-!@o z9}+)?5TQ{ju9!Dds;%3k%b=0OVwLIsc}k0+oa9kJx*}?OM6&?LIX6%8@P~5oG{8mF zITnQ;eDEQPt9M^Tn-Z_0r6hd_p~aRLR4#h5wDXly1=*ut?a!GOLp()jCPY>EFR74f zCm$ZSGh6js?6D817JUH5Il!UW;*JkZ;2`+1b^z@38aBpisUf>3Y^7X3CNJ`J1Vvsq zOmEd!+lq+~Vc9C5-0MGF%$v~8Ys3a9*6gv~T6IyfCXidu8C}q%9VIem1J zGpItiC?F9|x!m?7*<=(^x=JEW;=@2hYEyNCeAh%Fm$5_wS|DBeQ0h}~R&5N^e+VE- zK#xKoP)@JylO_Lue!5O>2hLmh&XX$<+rIGiLkN|jdfdaEbHNISok20&V_ZcVItlvy z5aghI&2G&@wbs=hyFk@zQmIUt0}b!^l@c*}c*&Tdh@b-FLDd0aMKIBxpUm54`Ku z#H7}v=U*icjSrN)YO+`@*ww-?^gt};MMXALfJiHGT8PNYpAv~xDKWv<+%oyk3TsC53UdP7BVoP3~&dw%Qs8GxIbTktvj5vP$rA?#k#TJ3k}#F=EcDh{)v%4+-6L$&_|>f7W*)B9A*`RG~JEO8aPtub&r-G(I@|-)>4nY=689G*9)s$W_6q#TXC)6*7CNDodGTp;!!a3cjgi zdPLFGvm~l86+Q658#^O+14FaIGIM+Sl{RV^e?#<_U*8TT$Er#%i zOkXo{YhR_J)GhDE4Nf^KJCC+2TEw0L3VAL_+nSwsnPKx$#ZjN}N7iJb@MI z;o*1NWnm@lsoky(cd^!4ZZ-B==HdLV7=#*)1jDKwXV?=~DBaw2wXcj`Yk6^TmS=CA zuG#O~uSGje*>p@1Qem6-w{QZ!AwhCs~c&xb8Dg^X)|F zU?lh;v>LOzH-bREFe?(@=)B-HP)%AzdK4Oofa!3H-T9|2Oce&$`rnW*_v zp;&x89pxnNLXfFdq$Y);VA=+cNCQJJF#$!J+u8CfQ$Cf=!j^iKC@X6>!5o2Hxp&b! z{d^GYhS%~(nM9&*iQ}Z{Ew03$-`GM{+)7tuy_=#z9JEFHf7pA=pt#nqTQm>|7Tlf2 z9fAi9?(XjH?he5vL4yW&cXto&?(PKFv-bP#?ERfOb^qTVZxuxqT}{{ON5>pv%sGFh zd}b92MWW2Q9cR_7wSY5?q=h%U0WJ&uo}(%i0kEey3faVu)eC5%d*P^D^B48id zn`%r$BcZ8|Cu?Hr4HkMrVhjeNgCn_IP86W%3~UnV)sc9$IMTvV$Q()%M+LrqoUC{w zQtum1D5)fg=dKm?a}}a@P^%JX(sG9@ZYtO5C?`l6RxLlssr9&_HUK&ecWw53XfR&} zS>4;oGeVFEi6zof!B%Ci1qe&dNH80Vu{-voRek2(f5 zHMbiG<1@T-X@E=Z^x1w(Xw~Cd{b^n$fdXYxz^~v_<;(UM5GgQT;f;%t?TdO+^CGDb;u}0Evgn*t0?plPn=TuHfp?E zwI1nNu&R%T)1W?%ZdF?CpbLX6t!g9tUwL`MJ~{%{T>)fKxatpqSuye<>9-l&UA$g8 zWg2WrvS~m_Ii^`D=ba}A=b@q*N`JCg$72$SCDuF5Y}kLj>Upb-ZnM&w093We)tj98 zdUKr3ITMB>7=plRbWs7MQT7+j6e-r(EP`K_TJ(#?5Wp~5WRt5F%3<)wF(Fq3I-P91 zzvv2tTB456<1545?=+$>VMN!uLG7!xBme#%Z1+Fg#|av;zoefn?tfnL+lGj&!q0kL z)?d3sd5Lq}&L77eAt79=tB`xGp~9YP7{gy?wS92UN zaeMA534JUKtKX5rX5O&$z>r*AY4TL%*}a*OwC}f8dAx42ruxXQifQ=Y-|Ox`Z=|I-Yx#HIF`v6_6Et} zpcCr+nx2YJ*R9W zRfUVYcZFv9A;a9zPW`f1o*n6EvE}^b32``{3TA}2e>Q%oU4@Hrp;7s>7n8GEM7>lPe96M15f>B}wd-RRGPz<_a^ENRd?faCB zHs>d{H1?yS`3i6R;(})9L(*1$;wqIgocB@Acb1Ws8aq+pJFts56-c?dzB|doj7r0`Uj(zww8E`a669 z{}N^hFiubFDU_GpgMTRJ1x!FSo+>0#Ju~jhvwAWI&TzR-e)$ zG4gq&VNvEt(q;HtLMpqhPMe2dor}7Wk}RlDj3?-0($@LVXXM1n^RRH>4g>j?rmMysL^O!0~pI@=rTPfQ}))@F6jPlyDC zA!CD7UR<6iWLG}wnlH~!<9tV1B}S#1c^G6~d=|s&nMbo9tlxB@q*JymjX|uKJ1uwK zpV8`S`g@d$yy_re#p6g-X4iZz!cq!{7|RTxi*WV6V6-cjGA7bVCY~(TV9*|9Es4~j zSmERBL&fJ%kwnTmLu)^wO$A{-D@#L+Z)$t8LaMk)fzN3sh`j_ras8zL6WW-}Ye8BjdX}Yw3hHgn;ZxD;0n)9+KrELx`%^P-OK) z>8mzTP^6tCLF`ETIU8XIPfMTsxnJmX>1Xg*i7GoS&Id@W;M4QaM}&6Dxz|<;W~9dH zMs*ri;lakmOZ1iky@p(5lCNQ^Gf^q|RB9h3q@l1Tmq z+2qy4R4iyVU%qMwt`Cp*$NF1bqk`w)wCfM%#u|iMs&WNms}?iG`vSH|7PM*;?|pYoxA*8m#W{VRb04q3 zKIHD@x;_}4Jp(5yzn>r1D=P{FV-?)r!;TaWy)%-ex_W?hykxt4rk-mDn&vIn z?8wp%8IRZy+>Z(LtV9Ygs?H2^W7X02-tF?%?Sk?#X^{KEAQFSUUX;`R5M`bSgIZ7+ zVF`m@x*en(SlPw3wr0IPshT7WH;Hn&WLuv0x!z{=Yo6XMA$MVlXD+!)@egKKose7J zWr-0dXdPLvK7~-lg>`}1FaS!KT2b(c$W3M+;eK{HTey8X_lA@*OR%s^F*gld&|g`w zpEb@eRw+tm39B#;t$j6Mzq;7$u?#!=ER{rmnmBsQ?ds-fcLx-g96x!z(jf-~d1ac! zrNvyVPpz)4v4lpVq(Svg%Q+$K#Cks?U8gSDMVxdi_H_YeAdw^(=m;&o2(~G?GJ?R; z!zuYIx&3UV6*}@VuhmTsoj!Z^=C#7 z?>$8`3*f^kqX|-BC+@5mH3e;Pz+8iMTR2&>mo62VkB@VmAsEy#RHkj*JXu$adgrkYO zo_9IKGiD7P>CB-+&emLR^{JHg11+73wHA>_etO;q!C|VL4MZb5-=2KFcbZKvocQ>$ zet$eu6u5{o$ooP!M}GLz0v)8sGw4cEFvlov+u1_u1;qGR= z@5XFS!Z!;O#;_hB65?z1x}o-Jv}1znrcY(HeL089WbCrj?~zXBlwa1Bre3CkfMvq) zwl~>OM~hHgKsYMMysFd2TlrH9U}L!<=59_A=zl46aeVUm_e=rI3<3eSQlT8!arVw) zr;Mgc?2tQ?ep4#B<9zHbEp%VR zY}r3kYwn8{+;M}ya#Dd)Ws&9t4cZ0HZwFF5a9OIKO{s1uZ%zX0Cv&PhaLw10q z-36$e$6*GfRMEeQ+;R#e2AvhHCI>tYJ24D+PuHR;^a2^|3LD}mIy_FNlj29)pSn37 ztUpG;vc9}}6~`H#w+AxPn~tT4V?f#>q3mXrjj~;UUv2omM4(eCmB!`1BZJW#^HBkGN{R2TF77M!Ua zXgTtn_trTSt_bf!Z|E0XXwd&_(IN=wRjgTCXIVMf=4=>gdI|>F!d#!&WnjSc)cO$N zaeF|G2-4H;0)!%BCfX_AH;@py?b=FlwKI9a;EVNup} zxSZO>1CSDx!rZ}2GI?En%hWY?jZz5GicHNuee5C#jsCZs~_rHhWUh0<6#>DM11(S88o*@(=8 zD$t3QxeUjru_xrM6aH#Hli`xxVun(?#i_do{2XaR6QCHdnfB$FyMI`WfO4Ig8K>r& zf4Z!Isiz~w;&UZBA1}$@pllYgI~~||BJeo@g%~cds8nhh^ChO6&mN+2dY`BBoh6+K z8Cp3EQYL@&0+(m;;&QD8sEuEY?{t|z&*G74e>7DzU7%n*x#$&~O0hX8v><*L*ao6M zWL|}uJZ^Bdeq8N8QJE{0G^#DS{d{9Ez^aoz5vVxoESxOV=V9&Za47oT=Lz(H*(=s58JihGz1kV_z8gyi#KPh= zqQWkj0%}R1|E5`203?lEXO77Y^$`;TBRwJx_s30Mg=xydd@uXkt2~+oO@TpRf#P#t zvm4TDQdKUGrFO_Ur>1k;drbGw@;zS!4gzX1IxB-z+meIk6)kaErMXYp}8!JvLT zo@j^vK&`@Bx_(h(D0r|Dq zvSN-QXCUabS-wQMvYd7&;kxC|^7uSA>b~(GQPCo4l$VaHwRu0)d%!xZxY-+rJF~xsv_7UE z%-|&75HDLjlum8HVfM&%%iDf=x(f{XIE~@X<#-iZ)|}g;M!7M$y}OGJSWfI4^)?M= zJuOO*-tsMF!$*eG!r-%;olXze!Si_YCnV5^B`cba-~(iWuZ;8Zk`-J_$3>! z)Als3XxZrd3fW?tJ7e^$~7oCx@CIxFXDFg#J`5UZV8JSGthmnb{ zohVgH)?>saa@MHs%5{-VODRzafW%C97oNva0yucqK<5Sm@BT>qOitxtpk++q2k*)H zW@n33Hm08_zR#aVCk-i#P8%BuAR{*Imf~T^B;DY~yteuxN*?g5z?X+-EtyQjV&vXC z6NPEa3?iBy-KefHK(OFzaG1 zcONh|zd7Rc^lgfg3PU_ z@T#}^!Jyr4g%@W5o&NV?!Lom#f%FN8#$T?tS(e`eA5UxIsWuwJx(Xqju`|k=04Q%b zUwz>6HvTM7s8%FWWe{9dhKAu(cORC$do>Rd$gf25ukDyr(`7C%K6-@wSVFcl~%~FlfI=eRiKBEO{H!63NnC zUvtpKv&S&}Fli-XEBBgth32{hX>8?}Nrla9LaAF{o9}XQf&9^Y6c-}h|NUdpCwQMJ z!N!G!Ns`)bX+(WH08mywVtn>$UQk?BQYYQ&bBw6*$#6JrJ27=epy}M#$k8zNtTt>x z+g9+rHJWi+5&U2yU#4U4c73p){8;-7a%|hI4Ly*?)Vq|;=nDTI_P)UQ%h28#iewuU!y&YI>>b1)bx zvy>qPF>fg&y0rs0V3yiP=W7ib!VtIFclL=I&Hv8bq~RmoGvEcBzWO2dH*_III)I)4 zp&ig;<4XNOGa$cUp=Q_P03=wxh(M6x>k76s4*Rv@Gy&v2!Cbk$?*NXij&?8B-6L=r`wSr;Y zt=5~xS5^3DsQ@*r=h1lvOMfTwq#tmM zN}Cm%bHzy~kjbnDf4FpiYI4{$fLKw(43Ojo*l$fqaG;~w6|EOzj_AwRMwVlTji!}q z`zVvg+7N=$HlH<2bA^JHc4NcqgUMR9NW4#_hEHr7*&KMR4uv72KGTXW!s{lSbp z!67rT{3_$F(^@{{dqZ(0%5bR_gBz#V5$hj)Fc6@;W~s?v^`^1ROvxRm6FF{C$&AC% zG|Yjpz>JEU^q<2z_pie`7c+YF&tW}})ES_GIi88f>qHdU)Q?hy3row;;%Y;qXHuK6 zyb~I!-yOu3NTk3bolF6A=nhMMuLvjEcV%2}rB%>2R+{j07IHjsFGjuDYt}z7#HtR8 z=J{79SBvMoOv(_9Cgo^4Ynj+LfqJGTiI7y&{pe9ck(WfKruI4bV!u1fgAFi86PXBr z(JVuWjV_DvA^fD|I7HNJa2HL7L9+qMS%NeDqMuiho}uaCbX?knX5HWNi;IW7!PeAf zvEcwy#=PwNu*HaRHu=JEN%4y*Kkj6Mt7};&P;ac*LSb%3$ir;i*5VC`DR(9WiCH8P z=n~uMug_^_AGTTBL&nyAR)#@rR3^Fva$@A2)zTMuAwpy|zCq$rmda!^Kg@OyhCQ%E z0&&gR1V}rM^w%B99A>L=9fH2ty%CJ(N8w@}>Ms~(tF?H1HV89P%zI~OHh^F)i^mme zOl>(|jL?8B!pa>1b?ebB_ISB1T2usMac(EUg*J?^KB8g1ltoB)$)m(#tQm5Fc6&1E z{4fP+JdzxwVIVE`5p+UrM8h=|we!u)a-})sBaU3d*!aaytb%qZ#9!yUi(SBaG7>JH z$aYu!Rp@LnuY?*LNv~9*03$Q{oh$-(TmukB3Ze+qUAq>Hx22JZgDQ%|6+74X+`{S9 zIU1x6QTnGgqWYhkdK}{x)CLQG=J!V7nhw;Dx*ZgTVZAlF0*ztgS;SFTR|V!Y%x09( zk=nWKpD9l-Lv;DQJ)C=NKN{+M%TDw|I~@r7W&E*H#MNPUj0#<;YZH(Hg{+g`^T}8C z%yoi!_oW4Pbim^VaTwNl{V#SY=?i0oZ{XrOjeKYoWvG`el<@>@Muo zA&GbxQiVVW0y?19C07}I z5Zj3G^$f{OifLCbY?3b@*7yM8zjx$#?FC9Uleg6#o1AP*G~HQN*p7Q!ccldgJmAD50#`aOQQVeSt=$ zaNlH8mL9wv!VgdvO1t?{$9JdGlG2|N@Kb+DN1%kcyb2)?1Ab;c=Od@b>%)!H8p^nW z|51a1-&&II-j=!p=qqJ52<`7TD3A~?kvoE8iA&>h>YVJ3MLSn-s{xQ6~gJ}%& z3l`bKjrqkHQ4N4gh3^Zo$dC}X|@t}rXd$1x;dRz zq?Y^3ZRk(*MQ;!&2H!8Oz*TK?Q~m1)a}ia%_kfwVQ?K@TZkuDcbnKe4H2F{mrM|o4`zfu19q|T+;qvqW?TcI}uo^{Y0*PkIxI# z5NEk|%Ve=MlzSn}LT{d3R)7XE;$M$T#E8=9{yTpU>U-P4OjUY3)jyPbtY0b&gsY=> zY4rc~sbU+rpoyP8t5?R7%hT#sYrKyAM$W=ko(}RMf4#3=1{~-Yz-FzsA8q}6|7qwN z4fWqq>4XRF42SndD*XS~psW*vSp{>N{2Ht;OVxC3_g+>hQKgfNr_8Fu8UG8^ebEC| zdbbqJ%>aD#N9>sn?-n)<&i_39f4-+!XF5cH_w)Va!=n(WKRfnnvjeM1 z)8g_nce?zISXd&F*8B)CoaBmqBX=GSf;ohRHNZ?;1^L^icdoYFy>d8Q1NAX%*IL5> zEcfhoS#30gMlO|Xn-2FR`{%1}VEO~qQXmlt@G9o?A0WH}AmP3WdJz%PC>Vh;$>)DT zve>Ffp*Q9XB8B}oB>y`Q|6kAj_bW(@5bd>sp_2WOznqQB{y*RL&p&Rk0Rl=BJSz?H zp9}nN)9nBIr@tQvFoSj4nf~`<|2qi(T?zl)4u9Qu|2-4_I|%>58~n&yE zDnfto1#s1Gn1HKRtO8MjHUL%vARQe?OXW;dDL%Hd9cXuy@_!`t!~Fj~Yxxa#@^D z25!?LYweEbGmDa{3bpErI6d%zb#HcRR&FCk{e1^%Y^a?Dk&BIk%HHFL04o zAeYT%)f=hj0Y*d>mCx(>T}W)1rub~G6(X4HcPCTr`bT;S&C>?|=P>0gt4X50vWDP* z!+%C*3{Z3j-M`ZM|BbQ(X#Ig`Gn3PCtpn(k_1fkHozCm{y620KrM1XB1=^t)0=)h( z8*VKt;vqXKJj6yb3I0|KP`~ye+Mz;yqoL>cKejtXo4BF$8EU7{ZbB*ZQ zZlL^S3Y4pJ_hla`!2hOUQnBt^9Em15U7vLbzsa-JdY$Z-z=G4ks%dve)4I&fOH|Vg z9$&DRY{=gq8U+Wp!cUgZPt7nh(_0V$(;d)n+H#G^Y;Wirwy*W71g|mV*qgeaL$x3V zSxZ_j*RjL92+qag4)~c&H7DrL?-JGj3S@wvjb+j=ArlSmtBaO@{2=~BGDJXHXc$U= zPq*}e=|ZJGv1m9}FBjg#>hYv2mddaI4QIW1JhgGPpG`E)v1~FC!Bd;iapc;S>_fet;+IkHBPv+e+tfcX^I)GDDPV_V%nzfQO3|Xl5zum3(K$ zowxxPsr@CjtYR?6{Cmav2~~6Al3fiUr-MM+<7P-~Fwa%Kbn4b+PQl?+zJNh&YeM_P zjHx$_mgH2rb68bZ$3N3Yisbhf5BBB0H0AFJYW8u7Ez0Nke1P5Z0M(;bH=u&Kh{?J=imZ4p1u?$-KV-siD zG+x9vv)j_c*{erQ&PWf(npYyf&3^l167@<2 zzQ!Y41(&Dv-v^2dawj=br5Coc;8*C&$Br3}s_Y-sST&4&FA&5c(7N?b$anK2IDrIU zL1Ri0s+^QJaFUE+XGUYmY?L=NolgM;BCnYa5N^!vPVc7*B%>;-Flgf`3=Zw612?T< zNI$e`4ncSEQ2o!72*%X?b2NC3K-`xfG3bdAe2C$Znpd*vto}VhpYUrgxy3iJ0G>IJaL}}jkf9DX??(}8a!MD~^ zVyoo_&&O;%yFc=wz5X&RI$L=6bQj?~QC*cO%h}&mrIl& zn^czHbVNTr?0VWGNu$N(WKw7*yy$p<)7`Jb2k z6e08|7h9e0#(1Fm>NnlKahpUQJX{&w4JOg3F{YCBsC5`WW%P*3aQnVed<-R4T_RLW zq?f-4i3M4k)NtDaJwlyvc^I^ssk0&eqL|oSO1Ybu_D4@GKht7;fBc9=C6%boR8XQK z9uw==eIc*d+S=+G%^!C(Q%YH!&SVHufrrK5Rx7BF$`Oq?YI1y=L^Um6Z-m^&NwkR| zppyW_a0ADKpe}8yxx>}mX-mnxb&L0Yh8{FL?Qs&jstT(B4 zkDT|0dhJB#7jYLRmrBPx3L%UQ0AqCe!mgf=w4t-)yK!)v{sbh$B5#8LjV=t8tWd39 zEuJ#EwC?`m8|GP2$-K>Klcy|NC}fMn{x4XGECF|RK_5mpAiF29ClcGIRK1QCr_$ub z<)c#74RX2IFq-&CJf&GPa}(Co;BvP4sSwQ85EC85idIhlxZA@NS2CkP?*$KMgHqGy zez19i<6EAjiq%&4<7l-y6cRS+;+@?Qv@i_TaACupA~G5_p!x+$NdIwg@7QVT#@B>l zq_K>aM*R``6?@;88;pA09ojvDjjjF1?D2oZyo{xJNSFYQ{N ztBrfF6pI~zMwb&s4d-iNyn3{O%Z5&T`h`+ft3mD5Z31AOMi z^Fst8VOzrz3ZXldyl_XxsZe%i!}s@s2<<^_Pj4KauTyo$4Ldi|NPISce2WjgS@)a% z_xVi7i2i=h$e5&_^wo1PO-OWFuOX)4hn-LUhJNS_X?&u$kw@Ug^hI#Hma6a(WCr1b zv24oZ%V42yg=MRaFVDdvI4=0pxKIMT!9LT1y=}IFv#oEtj1m5_TTj^WNJBnj}ts$eCv;Dn7qDa&^ z1E&dUUv@bOu_v`jQ`@3FnFl=f0MSf?(BOVHnoh!O)n(BST+rPWL<$ZjPbYDH%YtgV z8QkvePJR8`6yt+hl~0`kF*+4G9d)KjiMI=1gmqdc`RtdT;V>%(vxEG?^^`O^+(qxk z=vX9Qe)H*uo2)cD>W)GJjH*2>`O~XlKXgs0+?Qbh5MGw)G)ZNFyU%DLj8qQ5KY3Sc zz=d~%ZZG@UH4{GqrVK?or|N9fg0ZN~lhe*v!io1_UNi|bm-8*I*{-hVeBWW`0#5GJ zx$b;%d6XA6BGnNHct4qTG3m1=n%cXaJ(GD=?MnUb=aWpD7)i1fV$LQ18fQl^h(@*I zdtr7kC{7JqyE(Z{aZm8L?bf6qT=^DG1*;xF-g(Jr{s>-25<5BSj9YKL){Ht9sP-vm zgtqc`cz!o|wEfdl<%YR zSn;zbg)e<@=eVSnd)IZvNr;$ikscUVWy^QuGU*gvR##~Bu=%A;aH^%tjrh@Ev+w;S zD|C2`zK!<0&`2T)VuqZ*y)MsyNYQz{?(uvIbS?p;l>=7&MfqYL*jp^X-U2W_3w5bl zjr;Z0ovR|7z4X(y`7&rvqWbX=z!?(&1HK; z^5LjX&2YBGCqi?m3Us$u(a|rP;dyw)TIXs8qh-@Wuif{AQCFOxD62klyKa0d>;3BO zw&)IH^{rPIEI{Lf&7#r##qL4wn-yF5HyHgh z7=X}mbo`hf;0X~^8>`X)l$7TYXeWGO(ySEN=5y(g=}(9HLe}c>V$wM=zV?&;G?iRD z?MvbY7SzXFpFok4H6kIVqIwyQe&EKZv#cWPOf^3C0BP$W(3;P>Zkz+7P%vW;N7#S= z)?GFe{>lt58<(h}g&c{;k!)PmxNbjP6fp=0Ubr{IlfhF$zc1LoJHka5!3&b69l;BD z&fvUo(G-(CN%l7?wDDs(J1lkC^(6}l{VW4dHz)nIMX41Z8BsX)Q0NMv_E6Qh8{iW7 zP9aTOo=z*FBk_xfX)+POSAvD26}looCbkrp8_VEvi{qU?-LhBPJN*(cvAcO~led}u z^^l~Vq%ThJ1nRT6K{U}wQlI;}SZTn?f~(`4u`5z;fAZNKn7wrw?$FXvuQq#E01pTE zDOJBVwB|lSH1fHP6!jEMfmD{7tL1It)3lc7Eg|yZ{VEEtmYO2||H`Y<2XB7`!wY&E zD*p#YL(qb?M#H0`&+YTCgoUDaZn15Xk9WbnnqjTY(5rA{TC4@{I*kSFW{+0d%#^8r zaz5G#B@Wo%_|*g#SHOUjcosIj2ai2*>e+MLke?nL19l!5p~#p{GEAyoEi@Prtf=?X zKL)Ho?xZ!iB!#6AG&8Z64{y;e86=4HJ(fqbUTO<%E(68pJ(gePyCkuh*KqWqi%0jk z$JxH`Hk7`rUr$r(-8)(%PwbeSt)|6BjJbQW9Ydv&4}tP1R$3h?PHbtso?v@)3#oEA zbAc9W4aJ{Y%FtT7KQ2>pQtHHtf-L84bsNlECNdk$l=oevt#<1u@FBNQBsHtcf0$77fMgLZZYVSRTE))9%~mP`asvm^X1`n^+@r7CB9E%tMc2X1`8Xb zHbv*UU~5933a9dzXmq&wzjzpV#h zfb~ne5@n4j{+$670>MZEb4{t)RV3uprs@QVY%r5>U$M8@XO$7HDic%|BOz3}0fA)iW0U9WH#K&Sy%4EX2J)M-%$gxu^m-^=A?id=mpxr-?Qi@(Fk-(DJ_3}aY zXQRa+I;+J_J>AieYj#rkiXZRrl-@5CHm%%FnmFc`26kw|=e|AI_a3ft>z7GQCzyq)1xkb-pyguWKCoHKk;s-?Rd-?eFzS!6SB$5%>G?WO2sNf&>(!Y(JAMOq zH?o3w{`unR8oM^3{yT9|@hYxhJQoaK2GgpK^t|-?P$7v*86x;6tUf*)9g^iogLAT` zMC4z)_{%JbDG^DJ$+X7dJm6AM??a+cqd)!ZQJcM8vQO@rwPY81k26=4!fS1@2`>QK z*p&?nmP9Udf+a98)Dc=6I4+B(K;&z~v0SN=iv_~^uz(2_wso>1OtYix7eVG!C}+^A zw=+|yAR+@N7SsWfK0+g&zl?irkxf5|9z^g3*|F4M*tEHTN5HT1#U#j|X@ga-2^kzQa-TTm;$M>*U_|%4D7r1r+Y}7`d65@`FTH3l^ zMXMh{UU%8pwcEdEx>dDnD%#$weH%=mQ~wySI@3$VO?LdErLJROSE$tvArNebfvf~r zC%RN%ZVR@HPuD!f4h+rPUFeQSpiu9DItlQTd0VtD-En>GZkH4p+Z;l1&8`-p%nq?G ztGRr4o~*ESw&b1Qll6{;6nPBrx46U?fTbgbgzvo7SW+kW$N1<42Z05;rqeRM{S$|P zXS^#VVBEGi^;3skEvL%q_4jdAc#=$x#TH*fqFpYaZQ$&87pVfNBZ>Xyu)@nn*bwTkn<>j zUGi}V0gsnH{xY1!z^OLUt)$uEK|yUnTC(A-(qp%}KbnNAG{ml4?+uqWsbJ|)Xox5V z+2Ja_f%R>uhVQfjA*JOGALDT$YoPHGT|}(MV-`v6JwBHze>?)S(Zlaunp36(DtV*| zpVV7-FqrSD?K3?*2qthEOc-pB>kjmml~W1+Eas% zbu^Y_fg(S?3-_{IT}&FDmZl=&<2sn-ra@)!&6|>Pw0*rk5C741|E_wrg~2|_J1Zoq zjK0p?+9(`i}6*T_)?xgT_~-&Ub;ov5x1%&=!-O%oR5y zV&xiRgH6Ru{QcNb1ZD%8kt8(Wmn-wPy_xnXf-7fE|0OrVe(}9ZXZ1@uh1SB9k`ET({at zhGwdYAfhNB(QT)3T(hcjc8SSxe=tRUr`hq`KL!6o$_MA-@c6Q2*NWvGs<{Bc-$&Rd zkrpB|!E#tYf+gj|wj$A3m?CdELrzKx_%TZ28WZc~$b55Fh0WJ26ZV9vr`k_E20`Pv ztV64EkrqDrow;O`{HPTsxKWd01C~!0(Baw9czh%frF*2ubQ%Z0IUTl2?^Ag!Js6b~ zpUEg>QzirmZ5LA!=3UR%4P)THA(t~npwuc3Qo800{TMZkH0NXtjkq9*^n#!^H;oEm z%7!key!e?2IVq4YD4eKxH4U!LBn+*lA(2059BdRG>^BmXfF2BkVgU^%ZoZ&Af{jq! zvA_UWPFgf1wGQ9~hJ5iZ?V)#BI7o!susqEb9)g}$THY4pqH63MiBZHvEQegSs&$@f z`zCdV>5UaOBVdz@B5j;!4t|v$RD38g6vsET0M+;BO5%iJG1Sq62BNmNlbAddBZqZa z`Zhrngg@0rrw(L#l=9t$Nz3Cw(Rx_Y>SN32T&e{cvBv@*!e@9?_8u}ut( zf6nv?Dun&l8PyI69*OjbQO@-A#|sQ5OXMQ;l3+KPANpq93$A`+G)VNm^tjq;_QNz# zEb&4Ef~*`tZTIQ=A==~^&{I53QbO$NBwrM6_y!_JHSm6X$j5LX#YE!c0gC) z9(wa-WqEo&N{8oLR?@s;FVY}r$5cmp^T$+98&q`4V}GnL2R{hl50Gp=mm!@Z zMTY?CBjKw|8`eiN-bD4iUp`6{D~Y4_$5=XvnJwnwt4oTC(AJUSIml-Cvn-x zfnYvhB0S9`jk>GWeNfHHVI3vDkBiOg#W5{G5_H!z0)8Q_Cms+T> zG_vv!Hs`B&s_(bCBC%IN7MaX-^jmHXyfVpbs3_+ot*E*C@45x<|N80 z{k&>k@xh{oPTD;3tMu?Vle8*Qv2KgRK0#paA=0g@GoSmk2au0qkP_YNmWd~zmIq~Q zQGtl-2qHCJ9(!rIBXCOSf>ypi6lP}Yc||*kCyGZ-_v?$WGM2gs>#32IBxt*zrXV3U zpePF5$ivyOyojSVU_Z>2cCe$dQ(%)|$z%ELxJ#k1w=n*_9>ncV4a z=gUvC=d)|}&Oey*X>>>l!7HWUz|<6<8s+*2(GaoXV)0&XFgXSVeos! ztZ!B#8m^2%81C<%#=kDdy}}L53_lsy|+iQULAFV$`&ZjXPZ+Hii)L^>Za zlEhx{zK;p+59#w|f~b>h`~QOKV#u*B7+jvgdI)^106%7nuO50BJ#8n`IYaLZsD(tv zngQ1Y*yu{8k-;g0&=hhV{yB5y>p-csO&;CtJ*obql}us=gTYu8%a*P~lBN8z(?Fr* zTiO)()RaE;5ZNw$W`kcWIqc9$y!ru+7zor6IO}gOYg?t4@jTnuO?q?Bd8$tmyAndt zX!3LrJBTm#c&W_z9Bxw54T_0#ju2~$KZF%EYpv+k#OG1$4?aQ#DeDVHo4{LcQJazV z__O<5;q{8#yAzsYOC!GEq8I3tj;NO3z1+B3b&)}Jl!B8RHZtyRsuFYX(JU<@e@@&v zU>Y?$YPQoPkxt$DDrEWcJe?Ixkkhxbn1@Y zS*vE4ExL9>e0lM0d&@pdI_%6%l*Pl>XE8Fxcb^j?4zU&CReFhd|4n9PCHXu!gAboqK_ z81X{Ttyl#Dj=oLdb$cfw5#wd$?k4go)y z^CZ)W&9j9r^+pj9Nr0t=$B z|A#na11pfiYSIN<-^*da?8q2_xPdgi8Z+Ley~I0xZv~-?_VO z0%@KaO*qQKD~;|?&w0o1900c0UeWNjCnauSeqg-N0H#-|6IEIUP3>HXw?isnwl~4D zVGt9+?$B{}@H>eYYY-(_va`Ewo8G|i7vqbVUXG{ z70;;7j$p;ie|XyeCs#dy++XaQmlurN)0z{r9aM8!3LhTj@BT8bg{UtxG?BEi6f&uN zUV4c7y`QX6*aAOEi*BWJ@h+q3n`3Hn65}J~qSuLKWl|?GfN{mA^v#49Q$vK}iNk1i zA;8opueW-uvM@O8i17w|zXVG9sHKcA__!s@<$qcoidQsc2uHcdcew+yMh2pb&=0VV z29fzhFFHf^_tEF6>-LfQrM-}8-sSAS1`c4*X_Bl60Aa!>&LBA=44FujKBz{O_LZ)Y zaqmbY5eS)^!!-8XPn+;n9d0=i zWFs=&!0R-mjZulnAO-2>wV_#@3}urxx_oD~utVkHeZ6p~KnAOUdhy%p{z6~)*ICsfp4d)@0^b4bY_hW{y22i<#1ck;05=f+L# zoj32#jyMpA$@4MB7)+_=6y{0x(MqWIg|f7ELB8tbq7}9z*4Oy^Cp%1GgRiQ8uI5== zbFz#9<8y3N?Jn)ArMINU&?^)#jXpN+k6~O=AmTwZ4W%}*5I`wz+bfzn*^i{%4N^(u zeN?^FG%A)S&*uD|>h1^XvUgRT+zUYdIUM4cWPQ&3)PY`{vLA<}o%leBtRU57y2NApTbse88vEM(JJ*(vqHl|a+OnDt*;0Gv3KKYcW; z*%%izJ;Gca5{2DgB-yc2dC9Zn1&w1X5FBt+nRGI-EaaIxN8eR!{D$)u+dqZLY*Y)j z9wJ#i<6J1n8k!!&7;`Z|AQPEhksH=4^YxkF3cCTG_}5bhz#9W1#Dm?qwh+Y}8#8$& z0iSIj-95RquT;;Itg}QaxvH{6mK2@~#1Fp-<47vS0-|~(X(6w4Uv23(jgP?qERLty zF2u%r^;YjIW3_v>?tH1_c_G{92CH*3`bG76FP`6q6=>I+?uGS43#1l`{)g!geR}6-Ym`qV_}@I4FW+vN5G^{gshhKK zgU(Vgn1!4#YHW6>C)h}m_!ROE#RF?FcuAAkFcQb_KO%t_NdQO{Aq(g8wyu(<+|Cj? zzvNFYjUG#!;E8u>b^JUHOMNtHhD0Yxd6?5UHo~T%6 zb?#33pgtg3cDyZCJTXrk1Q3{dyL3TW^e;0nABNq55DrNoQn`$v;^zisQc0$&u=E6nFi&4n?cY=i& zcN;TIV&-{Q)ZHfELrXO&IBL2gAg$dksdH>)ti3-|;j><)4w&Md3kaQWNqjWl6RhT& z{v)%|ai!-aR=5Ah!zsp^7t})r)sEwhtdL3j*;*%~9$b{?8pf0B)JKe6LU>&)dbMCQ zhP0CB+h?@j=qDf@Dp3#BmqS>9AeiU+dwD+h`oB?wdnCWLpOO@MBmVx^>+dgAD{MJN z(#iOC!jkwEkc6Hq+kR~`ewu;r@vHJzrU)5~4Abk(ChcY(dp4f4y;>}+A`CsTs90-5 z)}?2&{le0%>FU1v{A~AJtVrTsu(OU*il7Rsyv+c>e4MaH71FhJ0Ma4SQD2FZo!8z% zEW#a|>nl1#QRT)!I$2%wGoDRHq7|S0S#e`t+Bxas3yg!lPkBK8K+OGI5k$cD;?edC zjHaUkg#m!osGV5x(RFT=XCZ$epaG|ejk@;zcrxqVpa?k3-MT@!heXUE)CDZegB}7> z>b{hG?OB^Sa?gURnvN;DLg$k6B)`Pp2s+OIX>v^rTgQmGAbfvCYD`Aw0?M(fJjdM| z47>>1SCUAL)Pyp_p_Dp}oLkvz+e*Y0SN9{tKSvFG>rACnF=DuK$_*ik&A+7mQHf~O zF(4riY=P(Y-&^AEqSmi3Z=(stNRBVtU&8j6a7GMBRR-+Md!W;leE=b^2-YY`>efgw zn@pkXmyP*4HT7G#l$!%j*B_*Z#<7(Qg@^TLVlWvm-f&u0cV@)(yJsrG$XJ<_VqZaV zKN2Y>a;iLfb$HcL=)^G1U8=UKcjNL&tD0@%u$Wwp*p%3c*#0ff0&ezG?*zu8UxU(p z9#_pT-ok0Wno6*}&B1ir7RAL$6!!jdA0RK@-LLWMc(`yrtsJz&8Cp1$6qI0^@T;u# z`Wg9d-?w)|O0JjZ;Yhu@ou@$$@j7DGaLFOeE=7y`7C&;3Vn-96BqB+k6f_#S!{_p-78o)aNgN=z;+!yWI#o{jk>NYU+T>&|G`tOBjV!@U@b zfJ{oyhnoneS5lQPfyT{H*DJ!>wD>%dsbSx~7^Qdtv%ts(62qh-0)=4bM3-dVg0uc# zBmDmA)?3m;j=5Oi_t!pEBPw2;EJHUsZUL}e=@HuZBvrVYHb*XQ{#0&f z_p2F%H?x!yp3{*=4(Rr^xGu!o)|NEiPK=PAC{?3iyIp-76>8TKWFp70^C{v9>fd>uR6?$-#&OBL#yQP-DVb|;17WNKX3fAUdiJ6 z67ngtu&h2<5V{kGJ7;VlwfxBHG5J0(X4`h)yLd}A8q=t(Gy~mW{VBl$>A1=RqOvw> zFEV0*sn>S~rSN^O=gr1H>XevRxuBox#hEl^xPWUztFq|_Iz*YLgzja!0G)0w7vR?Z z{Cd#pNK;K#nMVqTm|rk{U?Num$&+8l-|GlS16@|eSgxauf9_1>sR8-ijwLbyb3}$u zsrefDgK~=Q8tAnI6gKa^PUqaMEJ`2KaY7G=>`&NDeg~lhv0k&gKx>L~c$MTdMRX zKb9Vgn7x>@lM(#7CFo4{dE-dp8?M{7*u57cJc=0m)BJhbA`+K zVLL^qgN|eOib?~s&S@QA4v2OEF?bz;m%B5!t;LXQy9VYWM*^3-j+@W$*;AfCNt_93 ziqs>&B(}qI<$@pd^L{;NUyCu;e=DcJrad-stzstzq4l zFrh3g{h7;jL+Lm2UCve=yyErP9khPPf&PuPCCFs1m>~!p~`?-)-{XV59Lzqx`+7H4oR*RfYT-SJjd(fxpaJfkw zFSj;ZQlpQF&4!hzrABwG^K@A@_7<02S!sz{CBxQ_pQesP{vKl5gi(U?8bEE{Q~H;S z0I{dg+$8E->qn|!)rV7+#tmKltwnqVZ?=j6ebBf*!aFlequXKIltMnF3gej!Bb)jH zURw2)4AdFQOR&_I_57uy;rsfc)iX{fx5wX2H|deR8?Gj7o4K(;M>uj(AF(LvwlvmO z-ZVnoOU%N;5j>(zdAQ*fz;EmG&*8Kc;F8sX3GWa|W%-NRr!F*R_`Sj`g0%k(P_Hqu zN+QZu#%F__^JDCom!>4;Mg-jQeGMi&%DJOkZ-Jfz^3VmS3_%{|q;r?@W#e2&+V4bL z{!#et&up4{kyv(Szk1hi#v~;zVEZ{&;lfX=gS6>$Hk&kJ^-odiJo zyOdO&nE0l5P2UbW>PoxuzSRPGOXVa(?sW(11ALxeMfjjw(m(utBC|`p zvUKVuDw+m7)}5B;mVVFz@uBx#7DXjEv7HZu#6ULyxQx#lsxV-$cmB0O0fu&odK29< z_Hr6mlFM8^OtD)&YvZDqzS|#1mA*i)YF#z>1Msw!U# z3rH46bD44e`&RPbO7>pk_rwDa4f)V%Dm}R8+x(cRRwIimfi4iR?!$w{KEZM$`sOiP zmASVMx}LtX=u2Q@3h&>?PZ0r12iDL{cjt8_=KqBC~Ff?!Fv#z|8iY)lK&%w%)4! zWfM@K!#zEidf%2uFIFq(bs8Ys((7&Zf#6jt5#u4=DKW@N`~h3K(S@rx>MMnNISD`8 zZGSo(>qjKRJU+rQTKB8+7tZ$0Wt>AlF7)P!zuqb!n$V20eCfCSWANQ8Beu0?pO?3U zPN%>0`X}6l>OHYHRc=Hdbu}(1yKkJ`y+300ot7R&C()AaFXD^=`<8%aP_Y|25}RQG}BV3^YC zOEu>z^`Hq}`fRqkIt<=scvk2^ScFY3B92gX~(DtS!_vUx%)^S(SY* z@IDBd?K{!O@|^*5+X0o&PU?PX)&)ck(}=8(!-}E?V301)5rrfyQqA^gd80{&v#PK5 zCtc-Aj~#r_e{gE$LUgS1OaLWf-J#{VIetJlNikHcVF;dz>6pk{oz3?4K=7GPds$?? zxk3mgAFH|Onsvu2Rk(tZ*A^WJRiVpDqIp6nluX}6I0il zN2hb023+RXP>?FMl@A4iagm|qf$tw{&!5U2&5014P?`R0&zJp2i`PLoGd+Jo7(t;*C4TT+gagGB-&;ho? z6dPK_y!|-U2%p1KPu6%wJlM@tH|mr1>sz<);l950C5%0z47riS1k`NzrV8a#bZKTu za)_|f$D40BeS;pg0`l4-p2q|%i7G~bToE#xV!^3q@yr*R`}CvPdho|^vT<#3mHTjr zA0Py%nj@RZHOOFWs$7brZlF=cGxvUc{RoguQB{@9#22Zd8!zFMz1@N|?~ex|-8KhP z0b=g^!nd?9-1Q9$x;B>PJp4i@44vQPhYs!F7QGugOPAuYlM7(BwiHL%aXTw>y%3NYFWm+Mg#qc~V8p=){l7ll67u@z{=p&K|{k+M!M*ba_ z^1RD*;QH6&dRnW5rbCZt6RFVEq#%!7fapkP1O^&G`COgDq(TWtT}aotcS{y`qi8&~ z(_ci;D&U_yCb7ZOgjyXCc4m!56WjZh-hX*mx;m3^y<-nwE@{l&@M1QCDkg6Stxd=x ze`!R1VMI$hM(;xLEm=OS*{LcsSkaCbe|vSNYku(OWTqmKcvihe+chq)vJ+LL zbehWK~wZ72~8w_8?a7jY>KYsE1{QxF#n|kmcyZ>waw69zckEHy@=tSIi zM)D0C*AV@H2I&XXMwNH>V5V5)#Kx*p=#fVtpk`)PJOL;DGlFvJj~+F=qp99pW-X-) zP_2~|asmd3*1N3hcBK8CHr3sSxVU|I`_?7Wj=xLs19KBucLV+@kxF_lDD?tWy)uJg^=EWk{_uO1Y0{wF z!aqCl`=j6B4h#M8L^~-YM1WFK$2|vAM>3LmidqggvkCeV9O9|}?Az<_7|SrD`Ar`{ z?BM!%SLAGe$;CWc`mZaX!hR*e&?A!$rTMd1uf^{nYOQO{XYXrzcahNIRr=l1NTyYY z-%fDd8ZJGX+G}OgYw!RJ8W27lkIleZ>em`=4KV}cYA9|6esZn&&^zy8{oR^Hzg|^% zBbV*>?7uvsQO%X_RA66kw%CD+W9(}es|L2lku3KNGGPj8TU*i=6HmdOE&i^qZ+@6#>_xw3m9CEe) zdz62@pH!be6HrloV3hqIll=P*{EzREr2hG{>auX@A=dvjUO6xv3&z9$eT{%u*9i+S z_mu89L+bw?t`h&{|GI0y555dA zzJAT%M4{~w@ZY2SXI0(-!^MBS_dgcpKhypD^j!d>(qhnVi8kT{#il%o1oT{=3IIT8{kvz?Vo5a{)e z>iFp8j5P2$ku`#~Ly~uZkThM$*I~~@sxOW;HLA&_v6_p9Y_#?i>!WhlWX!*ODqw2* z!1n1=vHWp?-yJZ3LuRi7e#5!tS#a`v9HJ?z2} zX2Nb5p#=l`GsR?FzVk@PpfiJ7p8(xH_ddT_*Zy+n%pMB$TzoF7 z7h`>CUWSxnfMVRlPA{h_Os6Z&nzFlj0M&eK-IF!;zgFP*l0gdXL$-SSu=Qnh+*6i_FDWV5U`me2XMy_=X~cTE{kP?h8-KxsP9j%RVlsDE=>W%_lnh5ia~mA z6D8^rNkEI{5{-(Kw6=U_sF!;vKHCR*^C@)e&TO62iXD#%TqcB&HN_Yy*FI{LVG`gd znC`+nTsl7jVsBvJR2DM83H4SRnQ;>(&hR+wf##>ziydQ` zmQi7i98Di+Z(5Lz63=vMyd2ctBbTMA_BdWJABhUl)DR&? zJaDZ2Fuv|$PW3LS#dB6S>l4Qc0(h$|AfxoG@qkAFdmFe<2bAd1iI@YoYk4}ER?nkm ztC`b6nFtCHyfU~84)WA)OJPjQ$8!O!}L~U&vE`^YuLsUJb3*w4paF8s$GaiCpC^$>!gkrNpjuj?+`& z%S;Ts)ogIgEn{*s?%IK^jShyf%V96j{tzHxms@}H?{jaLpl8)c^a#YA^vA`1(7N6E zX#Ob2r{$(SkaDyy7bt7om(i_rjMM(q9v3qqWtHQC7pL8wJ;fA{lRae+#_zFrI+8u| z>y%e>B{`7%IZ00Bfj0gQyROsPJ5jksAhpKC+dE3E=i92A|J?)$a4Fi-6d zpAM%gRPX4L&C=$v70_fBg}*SOud0SO8jopv=(>IAgG?H~YM&(OtPSSBYU3L%4xb-Y zSU0$|lZoPfYnF8oJpX#?xTCV9q=T=*9_=IYg=@Wvxe+o|N9)iVw#`PgP>Sc^>@2AP z3d0Hga8R(bTj4c;4KLSF>FMZA$-#tkYyCYUUwhq4q{gR|vHr6zRMxk{J0r&@r&k(p#&o+1NBwfyk*a;O<%0&LL1vwvs1J!NRvssxvIOSNNMN0@7z*d9KSRF*;Oylbj@SY{^pg? zTbxNF?_jy0ov-&v=~R+9tT%Ij+gyQ=hokP9V=hFabS%rN9S8=KNt;{8({6CC%x2HS zn_PD|Y>pnM#luK995e$&*cV8+?D~dix{9Wj5?n!}^*>_^xqL}E%r|PEKZ9=%GH7P$ z#00Lm*e-clBJ*H+MxKyX-sw8u);ye)3&3r3rTrV~v{nW{_w{H;! zUP)>_;&nj;x~z@mc_WwU;Afr-d8`t?6fK|Du$(>vs?-Lxha{}YJhs!qYimwcS0lGc z_YYQS6|@tpl!Kb=wn!6PHa3OI`Zdo0-Ezf8g^Fu$8=O`+ZP1@i7I4UTnP;=C7VL=5 zR9ti`9AOt%t=voL?v-vRVRu`YU_judu=U8i8F0Dfv?vptDt|M33`!1Mso`OWD#~OX z&N>sAWm{dHnaEiPwO!XQ|JbWS)3tU9w8Z`nsK|B}X);-vk5A*Qe&_m6< ztNwJ7%BNAJI=G0u2yDP+HEKA&pr+9-)io6?SYCs=b>^;YWR)M)KZ`P2OZU1)1KmZ= z4V~M7R>d}oFzA-^w)6E@TCvE>gQ=t@la+`PQr?0XKqS*bE{6A{?heMj$kCLyNAJXm zgv?-y$dEouW5q^*wYH(_n>8+Z4?b=IK!N+l3XkV?xe=Z1 zbR%r$^_cK14x+}+bz1-@MX&SIf%Dd^i#s8cMuuZ<$T%c*y4D45J6+j;h3s_Z|7InK z9-y27+FN^zoXWIp^(La7XU&$C)7AwFeXL?K+q(*k&Zjb}2V>sSDmbr==}tmVgexXf zuRK9!ifx1pnnnJGCs_jw5y=~D`4Z|-{UmI`I{4Bu!l0m&!8Lh;hRk}B*XSe*P=!`b z;?-ks05tCT(8#drn?o* zW9n4Pi*xSFW%=#C^pFj@?{cUi&}d7SmV3r_-)$RlutwxZKv8bPLz?B#TZg)+o||^@ zJgy%UI4#sPXAa*1@5@9!uemv}w<#AOov%wWZp_%r@P(eIRbi8^>sGn?U58T$tu;c} zMhenPx?esf=RZyNF=8>SoQW$lU~b%9*yV^6^QwCu$!q3%1D)iyZOWLHvyWk(>;5yJ&mySmxI{01OD`b zLb89JiWk>uw~@5U$7P5zPT>Zc-INaP(?4$3pE9RUCMt3oGzSc^z>;mKm@eQp*c|ZW zaD8szL}{ps9k3 zwWZvR*OL}Vxy~cgRi<(qZO6^w2|TwC<6f)7bK23YYQ((4=Uz*8@@=yavU#R~II zp%0RRdgD5Sp)Iw}5MHn54c?Krj7cy&i#*`wC9_5X?MP9M?MtP{Q)Kt zY{v2&QNfceq4tj6)-`B8mue>a3R5oJBiBZF($FlAsi~lLy3ZSFHE~WM=I2UUBg1idUX&=8MX#ZLzA4c=-$$RZ4y z>=t}QFK3$BPwpF7`-h+VO+y1t=rsTe)#?raeF7pC(~`Lj%y)Jm7upLnR_&1^=mu~UV4r)ETWCPW(7_Q7&(t^5TvnZ^BX(ulLx(@-_Vif z+?-6jZ-Eln^be)*sATuLj__r!-8p~T;JSWk&Q#g4bbF^Teb5_J-L=my?qqtn+&sdpv2%!E%us8{?bk-M@n*Jj zfX;2Jrb@@txd@~ql2;$SU)^03|7g82Je0^YG!c^_=@m6DD>AgQMr7zD?dM#?f029p z#NuWz?_G+>C}?hn9co-=<|Kkp*QNCZbF3JZd1vf7peZ|tSn`g|%4DQy480*}X8S{~ z5vtT5f~&42Mdy}3>PV-KO4L~|Psk_{Pen90Y=_3IxX>F3!W;c=PWE}r#B1DKXGMMP zoEwk4R{U`ePfT=&>fBJ2?{5x;p2Tn2CraL^Kx;>+CYQ3AHs@g?1}d5_Ex%qygf)3Et>` zK`k8$zlJK(J^>r}7iPiD{E@K}lvME^2XEu4G!I0Z>xRCVAQLx0YZxUMA3mvJuK~zrF2G~n_%=w_>yk0=Eb7{c9{XH-oY-v$S;`f8If~o-!uLw-sw+*l6lW_-<0$bB>$?94*Ed^e ztn)CBV@XPIOulxR)^sUna6o8u+I#a+7?_9iA&mFbd{;GQ;{C9Q+su25pv3Yo0^~;C z7ZTZ38_6cYr_YT(z}xJvFS4zg2?2c9r~fDc+!I9Cz>nL?P zfkbjbY55pj#;XERXcY80mwFPSfg``s-~@C(c9}4T)9pLJ2#D%zeIi=k9oAFh8IE>x zdTzJfKeC?QpTo0`!&>cVx|)E55;7JaLa!b;*Qu@QTFstIUvvJPj%Fxz7P+T#lLcMH z_pCK?v>(|d7x^}%=%5;KbFr5YmE8qN4M{k>I0QfNm@TS4k*U*vzAa?mGLbSQm?z;w z&f`4Ap#Ih^I>-}kTsNvoBT+S#rLzFo1YEY7uqKY~AnA3~;}&zRHED~weI?_ zD{mAx&hp|R0SSg<4N4Fv7qq(9iT^@URxLL4p_6&Y$vQI|XZ{k(`=a%H`9VO4reTo% zu$!2XnP>nO7EEf4+?TE0mn1zNmEiEVg%ea^2xXSeq3-7M*%|=Tea_c zMtbE}Q0izaI2*KHAItEnTSVpACzF*4j^4!BFAo~!)SPel8c!YvU=vi+!jp#`BF`UF zUUWCVD#39Pm!{56$}_KATktmGjWShoEmLbLve^mY77{x$a6gj@U!UYfD~+UI*P$=Q zysWR#-=6|#DBp>MHqKwr^7HGlI|H~O$q_hzvMb*--*@(n=Y>%48S0cND_yk6Dm@!5 zuh&}Jm@|_P@A^`r_E1_8SHWXcKTJv%aBcdIb?-gWon_>}|~(-4NxQ6v%X_q; zdi&b0MxBBNenlBRHZB>s@8S1NZXl6oGS)$h+iLw$RRQ(>S4O<2$D3ycK`LiO>wtd* z-1^e$FxqVrW{wx`xK8q(F7+FFPf81$N5}ZG!$?UTXxB1vk*24}Ei2%WtQ83^9i1G4 zA?8|NN)ZhVod&}i#y6i`0LZb9_9R~$CnxOz^W?{C}$Acpyj=nsIz ze6rz~V9>)$ulqKsEEfLOQC99b>*{uL)&*1YM3x2}2{ zBWJ5+QWN}m2Ci~gyHZ7XWKuH0I>ghdC_8RfX|kjnGoiG(yun`g7$JY+q(m^P3-caR z*xsUZP-H00PDLbqS(6+O{jjM)-BLZUt?*`5xWNhR^wxn>>dmHBpT;Ag*sp5Yzj*_J zc%jJfZhvpZPtiD)cj#!#^!G+79|a26po_<2g@gp?uAZ3q&sKCE@+m~NzXjIsyvjyn z3$gpqMQ13yIzN{Vj`Hc}@sNm{w%$BtG+r(ZC=*b!aY^7pe;?KYF08G4h<<0w0U1nh z8Oa?Yjl9B-KYsi?$B)YElOTxbk8;t3uAH=-Z`gAl?JA}sk3SaBoFn{GA$-0+O(tut zbi;u6sVvgnSa-uyoKCsxtZ-)=SvDD9Yr(Xka#N)uQh?5@Nzc*0HYOcn`kOeBjR7)O z+zx7gk;+e4Q+rQa?AtWU0-qYWul4fXTn#8qUY&VcXp=PYo9XT!KE+wIlI&Ur`y2X^ z_a+1k6=_XJEKQSgf3yw4sC&stm80DcP$X<}Jm#7~pXDs&hhdWjr6aemkPDxrW29Tq zr;}WfM-2))7ZrEmu1F7;nD+O_YTB-Ga+Y}BEwgbt^&hEQvO7Q6&7}MwPPA#wBqZ?W zKzC1`#u`4JLn=KNsyd6#EtD)jtf%+ZLE=x?zS`;E;-Tqt71M}W9#o)sYV+%pVG83+ zjss`v;1&jUf}qVXO%69f*J3p&PMD>%6X?7od~+yqo`3dXus(pX@QolDX*Cyb%6J#; z?*lBSx0TK)&bl>R2{Ba01K4Q(R4mV(@MmR59cA;!;yw;;0Y#&19l_tMk(KMM(?v#Sy)x<~7QOAPu zfTbpruKO#dgrP3X5bzo&p^N7jNb%HO5j$ufOQ6R|9IN8La-5?~08CM05-al$JWOSG zhx7-hi#OkgQ-q5zlnU_y!H8eDZI8NKynSBF3P$Yg2-S_Aux*T$ZV&9`4HeD%gf=mn zw(>TCF4%Uo9C}B%y$-6(ngOaTggfr#&lk1zxS|Ca{Hxewt0^wx25c* zT3+Mw1#UCY#~{gIN>0IiFZMDmZGSrjfRLxz7n*b(?H2CSSzPr#*l3s#BqCxpG$%SL zcmZ~$J5&{2$>I|cGV9VzMQme!(Y4IaR!S6}ZP)^^xB=O^`yK%HwVw~svJY_DH0^yc~2RqtZw>B}wA zX4nt6pnWiv(#fR7VDTUT8ZNo&9#^WzN=nLeYt|;ryp@;3{gq* z8JF${3H1|!I@K}4DQ11~a%s2?o^_sMJn_u44WY85T*{&=^0Y$LHfx^ty>VPC0R{+g zk!>Pe(~F%9Uz+O%v@V!gzAF!@t&BM|h|;9S0_9f)@tU z$xSMnhC%9R3e}8}(<62QWs^fX>CzL z+KY$FXNOqVqbo^r5U7L-!P3Rj?FTgBgNO5!Rl!^l8+vky1MjwX9nKPo@<4McJ@x(H z#(dUoJe2nz5NjVC9^rFwDDV*~X*iacJ^h>GHhGG9M)&z0lbPOMNBK=MLjp;77fMYnk+sPv9#Gb4=3ZbMK!xL-4P(;wX6K%uNt=+Fam{OKessiqYt*|>?UXU~<+>)bbZp97!Y{HsHgWjl0F ziWgS(q#m+PM7+E8^+23KueREr#LQZ8M!z3fM=xeJqB9yun3BYsD&qMVT>FqLt6Tsj zndlj+Ox%*I2)2zpP4Y=LT<|<6U{U?Ci4aog;$;kBp0y)0Zlm}XvLsFsu+Io_KAGr$ z)jZ4SzW?SMN`%SBoML6Exy7>bo1!8V6`LpHWA)W^R(ITHqTnr%?6RkI7!b(TaKs(d zwD|e;Oi8)GG}B9oQK9iYpWQ@rN(r*I3|%guVXVDmrK*mLxJ#o-81!zk@5OP_c*xd*iH->`^Y-K%KQf`KQlM%QH zG-T$H9o4~sKkNP*;8?~M}IPar`W4F1EKLOeD(%fTco!q``cj` z?MI8%k3nFW{b<)ttIZp(1Xl1Ru9v-DC=vT6%z634(DHR-ofAkL?hzVRXe5yv6{aLa zmR+`S&FQ*-8mylEjocqgfqz46$x6sB%VGCvL;~!Tci`+JJ^GH2I-Oyx0?FVpA$+(N z8c${|IQUhn_sLhdUUD;%31|vdh0pw!TRDGevjH1+x3AiAAqu3|WI<;oY*1!P!sWA$ zaOp+29hV3=Bmse;(74;hYgr5r8ry~zT<(RR(B~aZpnzD@I_4!ykNyskeAP_x%yo_8 zo_qeT`T9MX@(8bkXDm&`axdbUMWW9^Br6rnM1rDQVc=`1Te@5MTNUjpm%QZR7TKYT za{xg}gww4dlB!t2kmpeUqG^aP}y}iIeRDOFeiSd3-OCr`w`7%La+V7)7n^ zlT5ha^1<7!@l)?UP?wd&&V5Swje~1l$g5d&S!(vWzJDrISBX@>+N%f$e#q&~q+COc z@xSh+LX^iFsfDVIOJT#Bzz$vf;BGt#=)YMjkVn4W$KA zYi#Mi$sjWHL7t3rdJOt>?k_##tHjGM%{PQm`d&tPWX3)#ggT*=53s~uP%g)UWA*{C zi~5du2>n|4O!88O^je_<9Tm6Ju`pa($!{1b`W68`G~!vCeIj}y@-{?a?Y3njZpso~ zR0MmaZh@Kta`2UQF01LYWAUCOu6&y~Ck~Zuee;o{_Z${U_4yLsetJTc&xJ|z6S_Rf z($lmX52ls|3HD#}r%w|k+*Lapz+x9UnfjhC&B$*(bWhC^k#b*=UO6pK8+sx73f3Pt zoMP6meRUE3BvszkEySBb%%|;)LAZ%2-oHh-$|Ca6YGrUacjZl3F4$^{_t40R4CREC zlet`t@1pDw`auZB9-Q;;loMEolb&^^3&69J>j$jxY`uLmtg%8KWZy7>*bs~tYHmS$ zxFuvnx(9y;^1S;o?^{}SVZr^q3wm6CGs5?NGm~CL3bp*hPV0GnC!BNwE++EiL+>a- zXngUz@{fh#AH&j5AyA^73oR$)?eNEzr>L-KTV!oEK&NqyIV!S=A(o!@!tMefbTHz7fy| zmLFoCb>HN*Lu8#)^6Qzv2c1TRM0yAn)WsiYpl{VLhlFaC>C{=SF$IY89QDm0VWv_? z$>bNy4cz18Wo;e@-9Wm*-bM)E>r`!w7wP7j0Hi?Jw2=MJc|P=22jMq`Hp4XJi)&_A ztS2V=jpWd07l*IxIYgjC9}s+=?){&fymmrRCZ*)F>01WdgL-8TkH&PG;=BnVu;3R_ z88i?Z7zvK`C)e3z3(Z1}!W5Gf_k%?>q1JQPZ)fom_@G*_q<4^50Oi56mkYuq=b}F8 zv{-S&&*{dP_Wwnp!~*=RT1LggKdhWRqT%l*F?S9|?01ylb?L+hLBXvF_~SF}CKffuu;3uFH;OQKttj*yckytg}f|1*;n`qf6Ox zSMN8ZH1%LwVKmxu^#%ESj$_3WHC_nt5H&7{Ue@0?fbdBtPNu99Ta`uvN9MYfE~yMx zQ=+Jop`Qm2jHa_%zT(BC*0I5K+)(i+v;m)cH^&Jj|0?3;K$ggZ<1O@#-oT0YH}=YD zdw{^C_}OV8544_aZ>pa(i2bHa4a=o|vKaZEm*wrtEauLdgjK>LyV5(FLx;1jSAmNU zt_U7J4L_b`+8;P<9o?#cgBNYa51)9I>ZJ?sm#QoKjYYZ9k4G1&(uZ9e3^$ZOabJ0j z`KJel^XkD81$MrcZmE}0J78!PzXLJ1t_+g3JmHybz4^|HTL!$wN6HC38^SdYIQCto z)g0k@pv+p`g#9sCTZDzMd2jNi@Du=;?f@8k367@msn={N%*g+yKbm&zipdK{tyrle zDz%B~Ec9`5{Q0N!Ciw)mCF^(kqRJhPL1LP}w^O~t!DpRJ7}a{g=1cgmy@cMGlTMg# zqPPCTsJeB#>~q&eGx``PUy(0M<4bA_xzFkr_S4-)RoTy@M(H}TT?T0p&9A`pF>B?L z--%O07adwRf*~R@R0s0tJs3`xUPA+9ETu1+kQ?&$Mt}}x`|^h!^y3^SIKp$jU?J(f zL)nauF>E~!mX$X$^#Ce>&EO5B-!Rk7)k}0~t4anTs*xsep(OnyWak-nv=P-II+J>XM}L!-_?h!?UNy}zFU_X_pE!L_EBxfQ10HIt^ zWRRWgq$v*19K>qbKq_wvL6Utt7`g&GH{|)$K`*SrL|oN|Z^(xoSv2jkUw{FPIIR3t$!Ys^tQulA(FwiVz1aM&0|eH0NYN|B-K*C{Gq2fL1CE|=ZWI! z0jIgxiT6o1C4@3zSkuJz#!FKV`d6jsu-~THS;$-exZ1dRd^F1h?J*~U4JnD{@~B&P z4K$#x9uuF=0z8S;*lV-RoD>1a*#vS8*2e`4#AU#Z;`Ltn8mbSUbJMswZUp%x6u~tu-j^ z(_ZOC`WOk+W6NW*RDxBy9?ox=2GG^H!YfoXU22txJd>dbzh)-lBF-P%7sAg>4OuvK z)bsMrP@b%v3Fu3AlwgCix#(p_=(+8|PZ^^v>?>lu6}p^%xugF-gy+Xz97-R0RK9+3 zbaUmCSmlaSb$szD1IDOb8>VzYcWAcNg%cy=YYt1gIUzDk=XXCxxR7a;>Oyvu#84;c zd(ZI>K@wp}sY2DY>R#MTMO{d&n6AACI5lcn%3FHLnoE80ygM$Fr#-t-rXY7(d>Z#9 zn2*iGwN9`Th-Hl_jyV~2RHK9DhoAYH`9Yx`*>dyhMf&hBF*=cgy!tm3qPHPp@bIc2~x%G&$bfNyKY80Po z|I};on64wx?U>;Lm+GN!JlIf{^-eHZi-QgY0gt2S0CJ2n(i)?Rf1b8TKtT zxz9w^B>aX!CR>^(Z~EmJ?bSGOhU?F&(a|fnTx`*tW{1}|&K^kYxsnsnajx?eoQXqz zoaSWmmZi3{TQ4js?&Z4J@jr-gDF@O!Eh6>6!t|OnJ)I=%aLirlOM*k|Bz{VzwntrB zM&yaOqH#!|mV1sXTBMWLoBcbA5qZ36@E&h1A#9mM(NDV>0%w|4sSakf1~neDK;4C6 zBS7Ml_{^*`mSgMlO4s$TE<)}7AL>YXAB=eey(9_qqLLj> zrxW~A`LI&IqCUO!L+ecSfp3Ri*e0DJ{gdn)sGAkVLo%sHFGtT~n+ z$YmSQ$aeHdrK-SbE#KI5;9ho)Tu6I2^kzi6Hiz%&b-{R%4s7BQfxOz9?H$W5Bf7je zdg5GuSY^3aIn&_izHtJ3*b0{G#ArqE<}@RX60-Sb1or%|xXMtC8dL{-q0kzB7Gy z%Azss54lGgcerlt=mp^cH2(j!chz4}ZEqiu)Qcb~jYvxgNS6qLbaz}ux|Hq^1Zj|- zAq9~RDTfxNhX!eekVZzj;XPd73VtvC1F!zzV$C{d$FrZ>Pkatg-V)0?-#=86rADV` z-=8BP9 z(_#$q=Pk(w4=Eq@bkw8|a(a*)q{64R_S!A|``z;w+$VB)u0!df#%S0q>w1f_RF88E zi0;limESY}(sCN>oU(Y>IuqO&l$0|Ut~wvsfho8d-(INAW1Ryl7Q0iK&KX=g#NPR} zz;M)=eJJ~({`-xAk}=T=)!8A0H(xn3^oEgsXj2pS<{H#-ng&%%=$1%QBO{br!64@K z419PEC68n4fw~UUrGd%=tz5S?p`?t=-9nZ5u)$ltMTy&#*@j}`&SUloFX;?ffC9Jg za-YT3vNbg@uV|&4D4D&fVa)#_2afbil3YNlo&ZS+9y~4R-u-Z-FLzL+n*e&eh745X z*BEE|@0&zXS(R_HDcS7qtMb`NX7CxQX34*^Mt-;9%+5#pV0P@)EG;S#PFJEjkeM`n z922B@f4ZL#z?_oL_@Fxq;vIQ1l&SBqMas4AwydHw(^s}@;-kZ|(ZyQ6xB_;7xw~oW zQuMylHxt7s;nVTN6j*urXl?OpRvsuOPu&1k^R9%z)`TE^uwAA6&Y)5ij8@NMZ&c2i z<)Ckrg}>qfsZn8ZIv#D0lq$4uy+aMwGwg2mBTAHCRmrcqcZrjbmZeqgZRMy{`QuuP&)m`?O z`adpI?yd&fvU9`*yfEdAq8S@(@_WgN0QUJyG)S_tURQzD}g_%%>m{*kp-!+nE3UBrf70ACXUl8yF?W_C#4?uL{k3EfV z$D)I=*x#+ACJEH6^_y=4MY3}pFc{gq!N@w*L!k7)Bl74ll*@L8Zkc*hOe&gZYEn(d zKE;wv!MN!3R)OY&{kN|?9pUMv18_#}RKa`4L4z{g2#YyRup?G!{TO@3YOx|4%Zi;W ziJ=tw8y$ih$qgfJ*S9{-FVF-p?B=y_$607`RZVtZH+SKv5&yiKN-7uDgV2V93Ddt$ zmy%+`*YFIX#2;l?MmbfZMX5C&{3Z75^GEM*JzT0HpDbI7{%n-X0tfFBtoi=YwDAWRS{;&8*sH6vr#Y~cnGKsFjYy|fF{*^ zVPx=`f?`JH>D81L2?Sv7L@RqPjM%(M%1cMdAmn{b^zFWP`#VYeGSaQl5wO!>eL})L zWelYu(fAvwJFv$o~oe2g!BwKs%W+nhdhQM9q_>_uSGiB6a+w$8}p zRqj)Q?_9IFJ#bUYVxw1oYhJn706U?R%&KbTS`k52*KAA|&V4#~5Q@M`rvN%>LEyAx z|5oRB3ss|+xA0^oRC3k{smYzjWr??YZ}%wNVz>O@#vFZPQNUp=W7{B0MNBbS;j^<& zyP27k>2r?(mMPyG#0IGk9>dE$<}7t?luBp$XO|y2@%33q>Jb#c{p9S1S&_-+`aXX! z&e3+jl&J(tV_cYA%wA8=WVRN;^??L9Zn~xoCW)YRd@u?%X$YTXfftezV*=*eK@;0q zaLirl_9_7@PCwzBfLp`MZowgOqr7TZgRc}@;G2@(wZg#io+0C~M-x_mk?P29WXv;f zJ%{rx(Wj(%)FZ5;0`)tJ%6ngl-&j$UVm!glT;^C7SM@Nk{5aErRl&cpuIYBaQPewa zfw!cNL$FUp0X8Am+*qmpY@L+!RX4_KS)NfByE`Qw+>!ZmZfd%lM&`QYCVy416WLB1 z%yI=b>hmZGFyo%|r%}iQeLRSEALkj5@590k*qv0EVlRe@O|vFY)LJ=`Z5A=qj>`i2 zS+mR1M&&WHyIv0nCAx{Gjs>^pWh*4&w-K2IO}#TB$5_h?kLQWd(|x*#9@P}L*5O~z z!w+97)EeyHnKNtU?1@9`c?G1tx;x*H?M*S}7r!MXV(Me)$HfU&GP4h%`S@|6cQUx& zzGl8$sL>%F@6nh+|FSeSQDWzdLil}!nT7i+PMkWizK?~&y``A>J8oDElVyejh0kd? zkM#sf<0O4}9+_6Y6$iS(t;AQLzF7;KT6xRXy2M5ToECZ%%I{@YIp`}|xWWarIQQNl z^yP?W?BMr&QtVYypi|RV{-^_`hZW-YH`IvE;iMWivxYOP)XKStvpjw zm4$z;z|Av-4UedhMRU#K{h<8Kx!K*#mEgOJ0|IMhV;BoNqK|Z#xKwry?GwB}NH#{H zW>vG^vO2-2!$bO8KAmwS8U5nduC#MA1nU{ED$1p`vfCD6!@-SH< zX!Hve?uOHh{~i!`UufY9bb!66I%F(oo={~1@pmq&x^z2R)eUj>rKa;m4fOyW^`&IP z2(NI~AE&EzfVGpJnS06mD?1R4h67e+y3BG=w2XVyRNJ69H73!eH}OYa>sOTl$Xs86 zS?b5nV2jkfSfi~)nKb7QCJ`A1w!HK~qt$lovrZ+JZrw}I_IffOwl?mLsASJ*a5mD| z_NXe4?ckAA1pHeJMi*Ak|A4zeQ<{1#D^kDO)O4Yr_+}()T#K3r&u*9ZVTpRWGy{vo z>%wsJkQ0x`7q64b7swXC2MVR`puM_I(7P1O`VhTqLu3uRns7g&v~OS#P{5=*)bpiL z)s;CcL{_lEisvc&Q4G=j1p1%hn&b@YcpE^y`D{y6sw;$z=uMB3L7f%$-cZ%vrqyt% zPQLcnFf-nzb`EucC}?{^#pcqWTEX9fGD-9bmBzhBfr8!^LyU6?L~BfX)j@aDzEO44 zJ3GK>qf)~Yfb6W`gL0zGeg_{+avsG}^Z5_&I-ZA6@(|-VX~N)RC1!G6l&^qWI~d3Z zYG%i&0|u-|E$z62`|n(v8%nXub0otb#L9d}AvV)=3UAecHhEmb>q>&8s+sqlvxCXn zVz~5l-Q@JHM$Q)~RRjW_!~wjaAy_LUi94?!%6+xGbX6YRW~tO-IOWKt3!%(8VS$uh zSta}%e5}d{=oJ~tY#+FW*8-sl6I1lg4q~RW)4n-BO%Izv%uN!9quSPRyP`;7k12_-qtsqRXuLybb`*1$JS-H!iPp?TP z0nU)h6Kv;_&~!L1U6>q!2q79JOTFi|jq*t9f;dl;hYyn7Mfo?wTVlz%zSTVfEr? z5)qrBwz1M@RgvdpYC>^}t}7`*Ne6FU>`F_WB^P86o%g%SynPok51c=Sk)_PIJ_^ee z2fk3qArT020ZKpUgFKOD(kg{B+!H{ar#-2{<>)`|v5aO6-aHxl0Tu-Xu1~5o`9F78 zHc0I*1{fDZk#=J#@_nM)bbwSxzFxlJ%2Vf%!K3*JR?Yk08ub_-fTLy1K}d)cgkj;x+p*{RBq^#9`PrDO6MKD6M05ssZX`2T_w(MT#;Y5Y zW<3w7%{6(P!>!=DWzqCH3^todKih@lls!Y8;?`@snNG5@vR(-6KC)MMD@0Gq0v;d& zb#ih11`Q*~fj~<5gU6BA2*f5zFjX1&xF$n1OHZ<{#adH7(sz*Q=_Ma{51SS^r7weu z>_1P5-3JZLAYNbQ?2!KLNjujCPLX^JL|}lCad-5zIsPaFAubaBX2bISe<5@&&_i-4i;JvP^wc)V#*uv58?j%zXw1=H*W78xtgE* z`(-^qA2#c;lVFoEPxl{7IU5#91<0+)hw>l%W^-P($Bm89l=RdKyEz-;gjcbYfe8Hr zfz@^5|EAAB%lm&vq#tTtcz635wTsuk_}9#Q@VP*FwqBc)cUIcL(DxjZ5Nb4>uTVXj!vm4od3Xm4+FyYGMWM=_ZK zY}@hxr1dMCS^GX@jR3%^*!=X+&w}P+EC0AH0R@F^Ir)R3(DO?*!EXZHHv{UAp@u-< zjY;vNJSh9`s~4Dfycl~t{KfmeiMNI4xde;WOIN^(h|7H;JXL(S*!=Cbe7xzqQ}B#4 z4di_c7?6zWYj_?oKv)F%8Xn{Gl~)Pa<<}Wb3WCmrge?RC=H1HO`0@lu7e`@FNUT z$g}x?4WKKKEaHy%=IV5dZs$9TD&G4#S|%@`AL)TKK(=U%ti@27#WK@)n?k~Y;EwZ7 zK%ZeBPz;HGoLDgbR7Wioe5=gzpurmzlfFhi1#!AH3X*J70W<^h1cqOf&~80IaCgB) z;^$8RjlRI7Ct7W6q0Fd5*T}!hW$R#fnDJn7aBAog#v+f}_YsIzAkcr=MZ;3Hn)IE| zey9X=49p2CJ6tm<$ub)A=wO0a&lG1z4jk<1TDJh+Iyj*G#n@bvO9-rPcU@Yo5Y)}JVPO;0Q{udtRpVLWuj}RIpC1LjsW)jkvD)`;PxmJ+aA2N>j5#{;H{XGt~_iP=Ojua6x%iGXV$7-AU|?e zyGaU;`0B&imuJB-m$gj5ON(b>*xkcYITM6pVy!4BzHPJ%g}^JfG&CI~PeEYLxGdzj zZukz3$^|BqM)a;GH`J|)09upyEUVHDH%tR^G8)>nN=-IHom@w1A3P-Ym}7=pezlSS z&Gi61>etIlI}-R}xnMZ!lPVpDoYkeW~R84e_pIOrb;5nH(p>&v#k) zYV`M_+a-^&58^V?pn$(!Y&Ke~J;o7}T-I83U_7{{#CR&aJoP~EU?}sU*(?p}!xg z@^KAsI`K(PG?SOl^&dAqtxkV!Y z^ADuZdoy%P9uCi7Ec9Jd(OG#bCX$;apBJQ2V$=aoX>nY$U@vZYWUE~-8_)fO+=k1n z-L+p6KIt3T6y|`(bCC-~0N+tt#3_^H{F!u9B#T#%0xBp`ATL)vCC99&UMjj~?a;{C z7p#l?P169s=vmt&I3Kz+7;)4%JJ*$((&E#RRP%SU+~)?zRuTbcD439DwkcewF2~>^ z@=h4{6+<-Y_Gr*~H;97B3s83RuteAvvqt&Tt~Yqs@tH@XR_RJta6AN_k0-x;H0JE^ zeMqTT;)zwYHP8-fzIq*xVNR=-i(Ncq33JS4xbbRrpC~n6r&%z-7h2hdtHYj98it7b zW~w-;H6w4&Mo+yzgWh>K2K_i?d`vuP2_dAc!e>|dPxKk2bdTJm~ zcwiifX}(=r%sVcK+PZCsFF?56m6N)+ zTt0{^uRhnuwKo`p5(i!AV*q~%(zp%C_G^U<+R-?Ror?;eN)w>N+gF+7=UIUgI~Hij z26{iLk0xq_wz|RMp%7S`Ql+DURx7#3cBQ}3=Y}?^=-grh^GTrBbl`6&a90`LZ^F5s zrB(&#gY-%=^8TZq{Dk3B*}4#is=0NFG4lzG0u z7)FPgeGYSIcO;zx&>Xrt+q$St>{JeD2s=|Xu4yAEh|3yERbi0}>H{R)5MR%wqNYy7 zJ_;N31AuiAk{6W}0y^7U6Yj?7R9L|dQOVqvr~Aj${*wO03YI%7fj&`O5v3^#wydYJnC6?Gz)My7(BDLg=x)e8adHX6e z=sm(v)!eJv3n5N)ny`Df!2#LY^Vk8x^FVD&EUjAmE2(I!u@7y_Z<~2A0BnXjW+2R9 zaddc9Q@N;yoOg8z#cqk=BKVc?2r>X};h@NHK~>Trlg+ysCGtbs8Uhg7;_t)v$N@Xb z+V{v?lY?)z6r8`BTLpy3@W5SJfL9evCM0$g-<1pmjz~AwDT*qzA=ZMudpC-%PaCs^ z8M4Kx0DaplKsXlHhAj{XpdpLw{-P(DVN9{owkvW?^zS6SV}D+|@NVa?`I zQ=rlcV7WB+S>tiy_~M!_jOAwM{u={3HT`H_jLv~3OB*1`N)>u>IiZ4$#ZNFvu=MoZ z6p{l#F)9Zdw0u0mY_pWOuqQ<7B~~T@RKpjI8S&q{I8p)J zhF1#-MO0^f%KzxSrV&J9F3a8{qGuh6I(jrca?y+$#Tn$(y)UK*mQO-0hVFc879fXT zG10;lkk--e3;4+#y)~Af5J4v9$|A4#eK9D?)GrmZ&Qdo7ggkL4N^#GMgihp@k^s16 zglj3BU=f|yE$0kAHxqErPKfpkestdWo%c-sFrfV)XtO-hRg6#Y{R(!fP#>+Y;`5RMBjV>bH486{BE}d&IGIeoCf4 zzlJbXF8~NhW|8K!4dU$9gGg6x+A(7Od8TvcLcubm^znQwpq z_y*U;AG~ipKkYAIZCH$eqWr`=wvPXsjU&EdPoUncs8<^OQf zA94Gmll~~~Ki2L4uM05Vi|X^?Su-}HwR7Nq`x__T(Kb32v$6HURT1|CYRupGLO{mF z5|NOSBJ!i7+DLo`+V38fND~(MOnv;YguueZ!0s>Z+Dm4@!}L44ZB;Rv-#)K_Oo^WC*eaS4{=+k@h!jZ3`%g87@?DSkJsl{LvHY#( zzO0Yt1-zovxhgW|n}u0Q?6JS%SB7vg4D|~QglF&zZetsbP*v*)8eF+ejH>7%z58S0 z^U8PPlJl|PUtU8%B-E?*k*G|G;4b9{=4(&n-b>yGK%~j|9XsP5|Moh7_R>>?>RO}^ zdg_;uu)Hg`)ol9i8Nt>)E3cy7_}EhLyHi4Y_Vfy}I4)%&sjZltxqFbm52{c6ZSrB& z2ov|a-`=@K064MvOuyV=fAOfB))8sACow>=Bx+l3>^cUn1XCnf0R^NChEfbEv0?6! zKmd3kPp86_Sn~Hr)r^FTukic};oW8q?@)uep(j$F4dMt6VRCkf)US9BDU*TOT*XtJKx(d8wARPvx`1V!TN%+XIx zVg5L@b-l^DasAYpY26Gto&yt~{eVzkB#T}(EAfZl0$p=gA#K88HAWp|0`#)?ZXVEa zKXs410lSHJU5^4fq%3m(NvUm~b%Tp*56xJr3{(?9d*V#7yqjA>^TJxDJ0AcNoNfbi zIV=OUztf6C5T)+lT(vxFO>QUu@H4C<;kA`edTLHL_l%z|yN*0yoi5kMA3e@>qm^-p zJ4{2lx(z+TzA&xvuiO31-``r~Vecw%;a=&sdi4rwwV};Zb97jNXdr3)Fty6G0LIaZSPW@wkXQkSMmOPAm2+4a^{Dnh1T=uqf4D zK!NoBRT0y7TnMSUJ1ADt)toPAdTsGk(?y=`TGWY1(&^nFZVCesa2)i~W8L{YT(_1P zg?}$0cak%F%yQ9neOfroN}_<(W{x3M<^meI!ep%dgG+~mNO zCtcEkWF5(Ba=b%u!A%{oTLuEi};& zGKO3FLm$V&7T!M<3c!q0*|l)aTa_HBZ{m47K(*TP%gz7dWg||w*5`J2@696rQF-*W zR7u>`PIzQc+7Uw|^N@<60}U*#jR73O{K6Dbq`fptDxLOPcgCz?cPOI4jMIyjdl5d; zz(?HeUfC?YmEm3tr6S$%4Of;WJRiUOMJ~9RkffoM0qH{+7In&Rfx;L0Fzd)tOpziR zU+7Q-a)kTNvVd~6)e{&L*kzpiP-h^>vQCHwwk~QWQx=8g!sx@O8$HsP zis|V{CJH5Sh>~;S)NNK3&CN^S#>3jEy#7c3o|BlgP)|fcn&>AEM)-1uw5SiHhmgFK zp(yT^2Ika~vCifpI>qP!?l0x-D=DmdN>kc}BoX?=xh0ZjG+|D>@%|`rGEjztuc2lH zW2Q1!V0C#G8s}q?|6{2sapfgMgvRQ|pa8Y5gG*?{hZ!aUPzDk6Kr+>L*#pEJ9BBd= ziv77n^x3O`uXHvpHKCZtqvt9TDtQl%K>TwDHH1xyjIsCs%cN}|Z7y5#SQDdOHU6$V zb`%~V=1cD>CAmQEP)52Gcbx!91luXHB7X^sLf8}G3L=sq4QnH(!mI&)VMInF9Oa;D zpHH!+wU8H7L$Jsd&;WG}BLRa`$)sF_c#{q>Qby!a#0nu9jUDQwVk9i6Z{yyRHh1!q zY&aSok~~q=Wk5R{_kaGd!fry-_c(mbI%(AYj5Z*rF}T%$L)^$?$tHmdMWnEcr?>ea z_^_H+B$=9|rEn#KDzLSyxzX@mB0F=3p|$#he^&cHqavYUIZ9B}1>Q@lcXwfA%1&kH z5*OHQ#j!S-hq=NhTsib`(CSOc0(2Ypxur+AVTn>ZwR2x;_U~BlDcG=K60RwP(i$oK zW^n&n3Cc}z1EIiJLc7E6){kZ!TZMB$Gux1w$s8MjBlR$w&5${GCiGUw;Rg=pqBxI< z?{G-XAxQ7up|G}n!va5hzmbc&;i}0sL}0C_M8Eh)Z7QN4q_sPqMZC&(^En-=wMosr zQlhplSee^b@`(H$jFf|1f`kEiAC4)bpf<7IILzR8+HKmjyi*fv4I)|zH%x_}&gVkrUUt)$j(14r>>Otc{K3dZ_rTK9)^ z_RsPApi=s&_u}e5jLtRI+-iy=xplA|M~Zye8imL85&dq9abWHhW-l4tD=pV<->Xpv zHQrd1LlW_0X*XOFL`2a0wE9Q+-f^G3_;pA44ujcAZgeyTdR12P z#7F#w1Avk&0g@ZgHYe_d6)UpXMfC)ht=*Yg_ttL6&2Gk?{+OEs@fhC}@$d2UuT9S- z<%Xz{w8vNJBwc#oKkj*j!x-t?Ck!}?Zh_-jirSwFHPv?uVQO2)9NfgTV@`~ga=E7) zeo(2++Xds};SV^N9c0=|yK(vHXpU1l^Joq2b!mW%Vg@^&!p7lJ0)nXv-Y+UMIdX4?mPx|>@W zqi4T8j((b`7p;x`pCWU-?`pc|YJagGba+_{1{Qivvw>3Cf$?CQ8w;^V`ZeF#6Glet zta0@9DQ5LuQk~Ws4k-G|mezRxTR;F-_u@(WsC37Yr*g4?M`&%!?I@0qB~x#oSfud% zVyA)L!CHqp|9K(F>^^XwdW z$(vIv##1+GFgMy`f}P$h_K_%EIu4R9^K()tNgi|CM{QpH2*0+GqYcyGDt>XuPVHx} zuK1W4-ZJ8PjiatOCtaD#^`r85BI}H~;c}?+@;BKVUPj-zpe2{(PvaNaLAv(}7`!xzxIIPe1K@!RBzLK-|XCJM_J0MYUB{^{x zY^4@)tsxLd@uXgQZfLHGDF-SI3od!Dewex3U zUtZ4JG+v92G^&`WH^7CTi`*>_XM|-Rtu(r>;4BOrBrc2Ez&rE{d9B=aL3^f`=tE)8 z+H9m~$EWT~ABweSzG(=d>Z*{WvE)0iw<*s&9f!ONOkly(W@fQ07QKwF`ySUAP1>xT z-Z$6lbT9>P>5jO3ECejsN;MeLT3=h=&E4GQ_4%sVGKB36UrlkG7FdC18*bu^!5~JMTS9GAm+65YRyQ4)4IoFh zTl_~V?0yxy^j@6^A=jgC?r$-XMOG#;sRS^qo|bjqzSK1F-~OSkyw<6Mi2)bi)~3LPyK@vc z*}4mjjX5>4Z&$GyFfEgV@R%*)RZjA#`sRlOtEz~r}; zEpq*})MZ?qTve-;nw+v#gqTuDTPVMG^no<&G97^Cg(>>r^A0VF$c~=pGdgVj`5hcBv8j@fo?A3so}SLysa- zt3yOI68BQmK2D76F0o&9-4@MfQ)&KE=0ieDtIf~(-(4^j@|PnZU}`-UeW3i4ZcNBX zB1}Tr4{u(2o|3{8%J>XF-}r?*!ctef9ciT7zb`&93gQu6pWeLgi(}ULfKkLO?*gkPsJEgn)oifq;PWgMS7*(cu@f zfq;Niw-6GNmk<&nkax5*wXimUfS`!AiQ$rh7QhUWb0+OTg;phslZ@y^oxO%OJVmQg z&)fL4WIY=h*I%U(dYLr)l2yVaQxKljka#{E?J(7n$^PznlPhY+#t=$Fc{&1j%KM)lVX0b_q=`}Z|()vMcHr?VzmB3krE;1dv zHSzj9w9@TvZms%O$+TPlVLg>8@CYJHqDIv@aLXGUGMYOe7FSM|OiG^aHG5h{X1HYq zu8N&i+JbXrSSZl4$rwGv(PJLigBx95L_9zpf0dNe9qnEeLNH?ecqNLv`U;H7?iY!t zF5Y8cmJr7OjEp1d&GSH1l2R|3AS&j^OdY9O$*x0+Z{;8mwx84EjGBc727McI{IF2& z(yd%xR+{2`mO?tWJgi5Q&Xo(^=`+9E_Ja;Jokkx-XTF-oON8!Z!#HqJY&RfkRTFgy zQyCcuDj*FH0U2xo0RyBUfiEubg@AyL`v?IC{6+`9!Z}dCa$!_*pns*I{D3?N0VN>` z3E;Pqk)w%;t&_Q(v+pZnU|J#PER@xq)n%kPjqGgb42nXmoeRo-H&fCE>_~qljeswnO{UO3Kc?tmycad)P6+-FK##KSxE&C z6$Vd1aSsclT=H(OeeUVrG&N>rboH3!7}@89*HeOwIew6B(DwVNr=8)^LhDl&MRVa} ze>8TW3L-)b#GgKX_)r3&=wxx8`zOaMt#J$j+|*+X_mwTC{%utau;gn%HyKa~7gT_5cfq>d0k)OVN< z3hN7}{$rCQs6_rb^VLSh1ohQ*hNSNg=Lt=}%c2uN{_%qii6z_zlJ^gfsa7X^^T#6S z1pYAy>ai9lB`H*x|4RwTHJHO^lma0Jo+nvSxrS@sTG_AuEJ+9i7@RxImZwwGKfjTG z7f^sY@$L(if3ora^4e~_2!UHO7=f9WGs3Q@kO>i;6qXh_Im zMc5tOIEi7Su7E=EKQ{!4QAML-UXISdY)bNHDNaaYIsSP#km&Gu{_}P62zU(N$^Kj! zH3x)v0{v&f!b3w!6$^$ZGJG{c`%?-3{vJX%4N5IS5_Vi{_7l zI&DI)TK0Xb2ElFjryhU-AoC!B;Fo`AgPkt&ABmm5LT_?BD$s6o)Tz*JC!DieO?tgA zMCczvgi5VSgAj(Hg-+%sh+Zrg7kEZeeJlTW_XK4y$J8pXK&)jDpFBAtz_zRR>DCLk zeD3Yi7K2$lTF!P%OJYzHXVP@D!~laEk9z=1?nnggMMc@d*)Y3yjpb!*=R)TVT`*llE1Z%BF*k3edX zcRkVZU`_B#UGe`QMm;!e4!=5HZ6=oeP=N_A5Y}`(9lw_y;ecN_5R*sM(f)Vn8|cRJQR=1lBd%i#VzfkP&!p{ z<4dGfeIhjp>I(cDZa4W=x7rNt4zE5-&C0A5kVL%bY(wQqlX9^lB`jnlG_8C?V!Rps za40i2sSCI_j!Z?7O2OK?3AY(0$C$(6HZOzMS0qa^R@fU|>=;sm>(>yvh{gD+RgNh@ zh@9&vLdA|pi!6g_v}R2LZ#ldOhOnS>IYL2Fok=Ksx6`Eqv$W|XHJHLuNi>Pkytc(qETtg8!wQXtVC*AEy zg7ynFC;5AK_-@+^KMtM^CQyD-yWPw>T`LZEe4J!)C-Zi+Nd-5ZuiuEhfK;z|!|kCO zM=nFLr$`=|CVE=*dqFYAK?KX-Pnvvau8v=B!E!%?dc3{EFBBSTcG`I}g|C`d>2%q* zYfyinz&8exN;VlyW6>?t$l-^4f7xEdPJVy0BioOcOs5lvNvXK&Jy)scI?^L-2Sq-v zt4PPEw!L7cD5bsq9axh^L=bAVhx@$C=O>h*pA0L$8j_Y&z(h;^we=aJArh$=PtstQ zH`H|LsCt5(}MLAHJnfsR_J4>t}5oX?EPM z!KAX~YC9Q1Jxj~G(4*h# zHRL-?UL;8Jc$prah8hYB#vOD`?)QrHTK`L&+Znq}zOUhk08|IUI?nC&CdzgXO8Q`C zt7~GANZk$M#mcUE6Pzkl@^szcc)lEd!ECwqP5Y1Isqt#-p#)0fy|^Hz%hI!`Gds=t zdub}Qiu_@stodt%c;kzbnHukYWcSCL9gt<>5O~$IzN{skr?(Noifh>f(>jaY#BJTO=0ijtGK~I!W}9arG0+)hcrj`RwIi(q&LvWO+zt>@R}$ zv)C8bI!>T07tU=_BkFfFe&d0dnr zHfXOd1}!9lcgD#t_Ge?;-1VmS3h3gC=SwS#a(1@2w(~@sX_%clOglA_Xl~Me9M1@O zT*3j z$n1cVz-BDNoyl?fmHXz!eE(D+HCq1Z7?oA(qBuV%Seo1@dv!V z$^^)%|CJLYLr;IT(UZm6!E~`wsmazCXg|fR>oW{=KA$#*(N~zdL5RBMa#`GzgK?x& z*+m`l*ecJ%nG5BlJ`0DEB&M-YaNkc4&F$?sD>omP(d<}$T9M;`K% zmt-h3V?U$yDC@rPil||K6e))zcj<86Js_G37M<2ha_Vy5rw)&G{ZSOY-MYht_75WI zxA(M+#^=TxFpi;;SiVI~*}u#HezXu)$;2w%$Tgokoz>D!-1geJv%!9RiSzH-^YK48 zb@x4f9BwD_IuGbmsvXm2>b85(-Wa8OE(e;9t|rfxYYsHnENu_d2M<)Hvue1if%WciINMjZQdDWJk$lhP zZkUtvZDk?_ZB{qST-l?pi|FJ&woSzKhR7^DC%$}u%h4p|q$wR!Ka*6O^V9XFW-70D zL7DFP2Z@HHUHIt=9i1xkj z;FeYTFGQ2>KbdTfU*@CE!J*)g8TI>YClx9W#!=ZMNM|!DJwv`%q<${_(MarxrF52w z`${mIH(Lu&tWUsGlmCY{q_?@R}9I4dHV&&?9=}J90#lp)h#ML=(9-n1( zJSFpQpZn4fnsB@8D^*Gh-dWCf)rd3PjZE%oe$Io)oTwVOhecB9?oU|P)m z;7r!&jpqL1^YDDRLGE&wG<9(t-|oBMnx>AAWUR_PqB5{a)F0qb67FxbGhIBr<$0$| zRC==V=W_Y|1!3pBzeiZyw!S`d97^;R>(9IW5g$zwtGM`4l|cwI0Zab-b$o?R%fVW# zXe6$9YeRXxV~zWH68M5`4e>bgWj0R=Bk~muOoiFgqo??6MxTTj+`-C}3N;bZSxhqeN9&a2a#>(bl!W@7z6ge* zwW_KlHM&v@13pY=)I&t9H_$iO^tx1idek7j&pgquCzcpIeb37qK|UY8L;=|-#N|95 zKa!T+!3Sdk;x=9IES&u(%4LTI@&Y&+Pbhq4iQsK&%OLcM);{5*o|YYNtjX%Clii6= zx-MN{IDx>W#*-}<@1qNm-gdvJCJs2yl}ne}r;R?TOXGHAU865i@t;L>V+nuA z5UyaP@1zoaglbuc$8{57V<1G7x&wkhX5+lTyD0m6qR*Z7wZR%s=2Pm{-?miRQEqGZ zN9k-$eW&fMkQac}XYjcfro44z)TsA}RLc~%Z%JZTRficrHOsEAsfcWTrha*}v?P;@ zJ~2l?^eT8eLnhT~&W@)}o$7A7-H=AUDliej_~7aB>+sM?hZSYdw?`oIzk7ODblINAY!dv9)ww%MY<4!q!K4f(^;Pi%8=x&$mDkgS*`CyfDu(@ zlT$1lsq%6PQ9Kbg49!?oc#{Nxn|=G@z^6c$b@f$hFxQM{veF*O7MX7s4ie|wIOEK zV5Qbo;bmsDZLpo1ocb~IvN&P2H~7(E+x{%-qU$LC^Ad`oE`gG;?uP->LpQ|+VTur2YBjE2u-hvpk00vY z{R3ZK@L3EaP*4(7*;XNyNoT->vHOCLTe0eA@DmQ@wS!246Y3FQUedlVeW|Y7u3J#2 zrO@=qPt~alw78t)(kf4`H6nX#M$TPyoZk05gx)3m1B-Zs4=j^7RpU%M3?5_? z?bDYq#E!^dvt5?&toqynF-x5V<+Q;Mwe{JROI{!tk3QRe9HIQVq9o3F4SrfpRfT%X zkJrVD+bdr&&r`3`?UHYncbY%Rt@%Wet!Lc`w!W}JZYo&c=Bs1U?;=>y0Jk;BPr~HM zGxqoFS{a8FUPMnZ=Jf!({52HcN7Z%7Q}D1zzHR0e6dj^ejc)rLOvYLkS_Oh#Nff5x zV<3q?g|hU`%aSn{zH)?kq>$ns3wHqx=;`96uV)<<8nrF@9|>E9w^-a>MI6~gBOlmH zF=sl|k*kzUw`kZCepu(~er$KYJk)3g+)om@tYw>mcQ7AWx{aQAoW)z8?IT)0Wwbl>Co(Q?Xq7F=qVVuvt>%7i=O7!NgGLwo-U8xd%jrK{^bUdwM z%2$<9JIA^PX`}pAh59o%IIY%iL&i{-f&vJ|6=j1^)dh96U%G;IBCrtE*YD74sc;$z z@&yp78rM$|kL8vN|AC2~iV3Mr)PBsi*5xPC^4VPqPs zk?`}B3F7i(yNGE(5=wJ+oKOXiI<4cPET^ zKX@*l!?qxs3`C^XzNz(Xca9BfR_Iz(le}4&E4j$}2~<(Ppk6-@57W>WEoPLoLy@!^ z=eC~LFD?iu!!52XfGRI75MnVsA>+wQ7E-pCael{bRvS9t*-c?tV~n60mbj{07;_i2 z(=J*Ri$M2Wc4P15hbT(%vbV;etPu&F5adaY4I^KCiO7$IyCgc#cWnz9~SzKE;5v#$>i^f%7<+ z19@3dGLb5mrZ~(}gzR_%3O3w)J1x{9;N-pYY!8)u91%NR0x2QF@%BE8rIiR`#|eYf z>oNv{lbH%o@)t|gAvtC@`~7LkayNfL^O&^H3lw4U5J?~8N*2lpB;v>>u3A>@uY-36 zvk3?oFnv-wUR4-ft_4QE_Dy_AtEr{JedR^R272P6@{>Lxx6GI(E}Z#Hnl@xS5_!oE<^(+tmP*rmU6a@}&e z94xV2aDv^_m^@9u;$1}z3PmY8yCHXJCIodA#PXOlIyLg+H0R@Mty}AmSQ++n?*TkM zD%50_CiN)YgGU~epe7Iu6S2CamlaE@)ljy--4G;X8!I&QhL^~smI=p|6aV^P35$xI zj1%)H(IqsVM!}Xsl-1^Tw5)~J;Q_Ef4|_3NtBgaW{p)2Sac9~wsn|`Oo3LNfI*zg$ zn)#)mT_Q&;BvUGh`o~QwjSN(qwM;csrmEgv;S;2I%)(>J18_;=CoyEiER2!fK%8(~ zs_hWI?)HG~Po8RxQN_h@nbsq57-#{h1*kormA)3>Fc-LaHxlRp9(!>2 z{P}%G0~*YajqTU6twc1V6jZs^nT5+{BmK^&-*nFt(@dT*7k#^en8O`%A8DHE)LTPc zGT3KL9eFU8JDF%t$D;1bvK`XDDM|Cexnk;?44LzU4Jk5m$KZm(FWu*Qd6k6!7^(CaL$#cwcoPk`S4UznwELH_MzURlAU$ zT-ps;2dyZf)oS$-FgR`mo?o0|U2Vdebo(D5pWh9{q)FzY7YX;ZR{?le<#(Hnd}DK9BzjZ z#?tB1$5&^WHLwY+?vrl)UiMSHd{VLCUG>7Dq||s2-NSOrYOcZp7C(XK{aIPhp;lGb3gVYy+xWST-uB}K)jOXu z&)J~8?IV+nvAJ4gYas)KzC!vl?x>vxB@Qp_#U(>9jN#J7 z#P3iae_o^_EZ)XQYI`|-Muo!t^;t%o3vPi`2D^o1i0$i;Zb*#NukZnzH|XT0Xj?qq zw{?|7gat;pdeTQN@*0S*lul8Rgg=ix-(zN5=q6Od@@g4hC%$*DpQL$bc`@ zzVx)NjY))P^XEhqJP^{xlZ25=p!X$X6w*sBD$}VY#(?=Ey#2YOV;7LgP4tZ4M!VdR z`Q0&vD&7m+h!OrB(DDU9Sw&a}QvD=+-R=PwVl3uvwf^T9Y!;IPOnS&a+(OYk;5Ocw zj7C74F454>ODD;sb&?wT=~L-pq?q|_^OxG&6d9Njmt3tw^U zOMWdDhKeadsgz%*hHY@*uz7nm6FuY!38_dd$i4Y^UFwwK*k7brZ_1yf-qetSsOn1= zRl7kQ=o|q!XV=S-^E9%Kx*80^Nd&TefbW~H&2d$1>CiUN@+@|gU0#(kTbd*|Dmy+u zbQ5XWA3&b*;0cn3_RiI|_MB17AP6}#n3sNsZc%xmqLrnwa`+hrD3#hbU(Pcc@PUIw zD|B1;neUpNj%$TeB0@39SxX^lFQ&6ptgcmxxJObgpe)@;jKM6HUXN`j$aFM_+CIdFaCg!fb*ES;xt(%M?a&*d5Y?I^T&!ANlf{aDOrN4)UX)hj-sL9{b%P(&>ufQ_ zne`>NCm2=$Art1zl$%tkps+lDy11QIqY8sgHDvA^Ni3FJ-=6wqT~P-%YSElT%lo6U zWt)A@BS&eZ@IDMEb3v8QXJ^i7ADCgVLt$`i(i60`5#cPMUT z8cTOq94F@{-G*4tcMzA$78?!-lnSMtODUNu1&o>Ab0P4(-fdfLc9Oe%%Sj6W{<7g% zd~Ho!VE8UUSj5CF2@EQb`eyeTCJCK`i*j0Ayo0=(D_|b`D}|u@#%Ya9A?w}JzA=q;wHsnj>) zR)cY%fE4yDa3|lReckDxEs{?fU1n{b>E}QR#p(^NER~_kPTR1W6jqdT-BXkLAa=nl zM(@+-*I^I(`v~DgeMlXW{N5>|SZC4<2N*DPeCOCS39IexW@Z`=cXZ3#bc?= zYKwKYdx>x_X=+V9<%%PWIGYm*dFmAFEln&Yn_}BkE^R9FN>$5~fN0d-Le3!<@g1)4 zGb7JCXbrh!&SD@AqjibLTTY{fE`^I_M5;;vn;Hy5g*MR*i zOvh~s^Oo`|`x~*S$LM3g0f*@i_{!n1v4yH{t9!aQHVEx^KQQF3AV(wvkYnR9>3+m1 z)fnM&vdNy2qxPZ;s2>Hy9;uYh&BwoOc7Zu{jsv!f)dB2XhgPHAa7=g4p~UR%64sE` zK@bvl&Fm3%iX)aPAFvMV<51pmQ_yPFS2qA)X-^0CTVxmepc)4cpQKE0}HzzWa4= zN~M+r2}iBfHuqthB`4_d_IRwX>x4aTpw9*UcZRV>Yi)g(0Prw@+uc!Wsi7RNw!wNv zRYvBRS4;7~w#eDmJxLz%>kMAda+8bJziD?m9Kdj+B168CHet6w%*D&4wq#OL%KWMuUMO_G_~zEJaV1@UJ{ zY-@kUs>X5q%5+XhPjt3@oqFJ8x_F9YR7p-EtClBta)r!fW zJ9f$K+Rj>f!?EQwYVV1s3P$Tv1om8Sz&?1^4dSt%b+^4qbG-TPt7dK3XnLO^gS869K z0l{mRnFW#HWI-r25s0-)fgvU;g8*`p*jxQY<1sLXg0lw7ukDcapQ8_tG35k~YIk}e zkqR)#>}eKDRFE=PH)`cfE)O|$KTYVgILEu6XN*2(QuUSz5{}Xs59MrPY7VBeMJLz5 z)IykyCMn6Wg!7l~N(anr5|k&VKU?)#?6`c64V+)+D^0aHKEH>DX4kyuHm0%=x z&-6{L^qmM0Q3@F^Bgum~D3815nnv3JDB;KMw;DSCB^dywYEOtAc$(-Rh30e`>BTD2 z_b^uf?1o4qb?Q$oFJ5aXuz*vv&Mw7LBx!T^jR6g{w zK3%4JE1f>a8OCbFgS7TK>)Q!PHHAuyBh{TsGU@;a=gSMcPG_;&FD*)Zo3`V&?)Ml+ zqrp^aEnKlRlG?L_3I2(icRoG#b7}*?Bj90Jva9{g^Z<;%bw&cz%|xoX3LOk`YAolh zw09O;?-9PqZoI>DD3sMn817eTY|DCG*{LfEM2|<97pz_%lL9E(OPaY_22(nVS6u_V z%ZV8qy>7Et6xJW^0$`n>9S<0GmfCK}7ty<{J?Xk{4nW~`Gaq+&Ya{Q>zWf+OUtsP` z*>tBPKG5BruJ#T&wzY3;cG&zl^QK9fR-=s{m4V|OlleOKq72LH+`kw^jGhFp1EA@FRTn-K$~8PUtu=IkEAk>10!vf zNmpgE*kC{UxZaFGye;qi{4KYvOwaZD9fy945>ES?O8y%O6f;04s$=1ap0ia>hk~K@tTel zjpe9>1H#l#09AG5SpZHjI+-L%H&ubKvW9HRdyxzDtNpW0@~!Jo3`YeW=-wHLbk=f3 zCeW2)o`|p(-~FzVM#~SY#uC(}&E&|{V^iByB75SRW7v`R&H#qN;c=Kk;AW(`U2>k_ z*bFYbZgbmq^ksp(F*r$lJW{jFyg2M7tK0IGKI@x^QIc$ZW8%3g8lkTOrmSzUwX{+zGk zX~dyh183GGS@ors>fS*+9(Ps*n2y)I??MNxP!}SMaJ3qee;IoJ@#h4E{3H{HFq8NJLL^{`&@d1^%qy^7d#WwWh4%? z(SMr9H&%G>pGH`qa~Guxui0SzX=;5D8o{CfXXIG;AD+^$CE_3awkT;pf`AG^xm;5t z44eLYErNVOAfTtDqo#{-JO{}6kAIV1{z~}whX4eh=!w4X#bNp$i#?Chi zeh*#&S6-AcM?doyd!iXhILI=?#l-Aq4qf`Yq5oPcsHRXEiX0=m>Zb~X`UMueUe{I2 zEiO`W^ch4Vh%D67xZQF8J{$hqfGkXrvP0hIe{YfB13VS-JLdC&aA5l%^8JsX*?*28 z6mjZb8u_k>K+$%l!Gp z{y*nR5{u8T>3`urXZ#$MaFE6CVg4(z9t?=&|Ga&_5=GLs$O~)k#y_tdf)eL&#GV)Re+_^#3!HB%YKzLXD4de`$^DbfZY4^l(@Q>JvqNg2{4JaggkDv?j_S?cBsYgm@wnbI zQWdZ;x|mI{>az-7BB#czIKC*|Zzp!<-$WFAw0GKY&?O@8i$ON25oohv>Sp6QZLT|G zc+K8-4f!(hRG+C#MSeDYT7=%@a9452=dDw*Y7ECpro9;`*PBFBydl*_aD`p4`yS7` zehPaN;GqmoZ0>Adu6V`~_-G>_h7rq8_9{zcayv-da4!8Xz18!iU{lJ_(cX(S!JDxYi^HF7tcqkbJ# z{sTmQYoqx?lB72KBXxR*V0F?;GG;Bys8i70B2fobXg2%#-v zo{N4?$5w$;kr}(|fyc9Cv3SrNI6O`ZQkO^}FrFhDcU=B`-nj9vhc*es5or*055V|n zJs@cNnCEUpD~>EgTZLNT>HMiE-z%zw6p1dMqr-!VBkTM67iXTRKe46X zu~Yw3w2;zevv^XO9AB-6nLwbtSUA71wi1=f+j7qUGa&UFP*d7e?>J>eq{a2AMX{0vWNU^SIQ?KuQ~Kdgn+1m5-^!&dAe%>BP_%iDr1{G z4pPkU;?l}YFS=LgW3i>LO*lw8AvTy%`Ey`$&|e2^S2(}?;XLH%)+_U6tV(DG!bS9u z5GzTLWLR&?zGuFtlccN{gg@wXGtcgBa00XD^|_Z^AQ?eqOMC&|S+ z3;bdwUXLFsZ}=PpvoWBUzmF%=3yz-v$T|3m?}>djmB^h*BJ-9~B13&t4`0Y+c=kzy zRxXvO8SuummbCw;r3=sHA6%jQlTz@LacS#NqD*OW*HCU-&gZgUm*CqPcYn184U+6f zKB55)t#=ER-wS<2ZcL!M^vL#RZ7q9ns82jm(7rhz&jfb|XAe9++_lT1Xv3krB{7jq z1}|b`V3>}k(KgMBBEOv{mg7DPTzG!vIKIlGm@5cEJs3>C5-HXxEtoD+kO3|+yf$3r zcg^DQRJC1omRWg8E*qn`nvYm#UIbnkFE<_CXSyEt&!rk40aQT;0;Vr&GNVUs9+qDwAVt8SYvR_$)pYULOG7A6246Z|E8`wbS= zy8Z1BoMM3e9r2du(&00D@y=~O{!%{RC@3~NvT(dVR1bV}5HF`C{so(vp*4(!yf~Vy8hQIZQ!B_x0$$x;b z%Z$#ki8ri13;!DY$xV~-GUIIvNK!n%#pQsq^Wm~J5q1_58tzB3`sqy*y-urh+*}y; zoK{~rpO0iB5H%Yt9MyXD#sgt4Ax|V6u}tmoC9n7GrIMtdWON2s%+jFP=VxwT)aZ&lX@S-qo*_l2dowsqR#tY;q!86Q7-%x|+Vx2g7L^iG; zOAsy|OWAA(=TBS*qI~6~I!1~??(R=?&RUn5F`oP4u(buT%*ho8HO<))q?GY6vmJU* zH*)B}JvR!WP)?}MH%$bz*vE-II~7`y_KJBab<%^I!!c9~`R3or%kLRYOm@a}9OYK( z=-W=U`DJt)ZQHq@?w#V8Oc49;+3Z&1_*{<@pzly58>}@{R<+UdmyEfM_=nDItRo4q&D|+x5V~BS#yBs{gZD^V)W%Xcq6=-RJYB|);y&{C>z$Q?F%vow|)7zbtmVynh^k7i~TpRaDSvjm>m z67paihx+a15#>UyCw{-~Ai!*Lek2x)LZk`l9)IKwZhIVC)5V`v*ong9+FtWTk@!B+ zeXHrIS)tqPD1wjevNLj1*71enHQ;jx9zeLBd)8{X+kGWj@C)X7Ry*7dOqx|f~@@38Dmo|Ptun-b*NY(`=y zI(K!k$g^WIR7q~UPo^dwNRGk&^!A1`TU2C9vSAvbYz1yyI~lYzJ`gHJSL$vRoSisk z$4i@?BuM@SABq}87J1NsHRd6K_?u3e%rgv^DZtU#ySV|>;w717xM!X*E z3(h~&MfnQs_pL$Wisbfo&npdE0abyeApmrlMw*~&c0S9)q|+AXQ6IGNTv0pwbOumA zhbKOXZ6|4tr;*m)c8?vp+;h1e@8at!abBku&LC+>;;~~R65g-x$n)`z7dh)WZfr>` zG}?7$C_4x$f@EnIW{~6oaL~)dRqAOwS;lth;$TLFo~@mv!GrLFbSA3~=les$?VGdy z?0nU7+*wvt>E~$b+9cvJ{52+{c^y?u9_=(6;n+4oy-LTdz+!G&2T+=8CDf||^9dsG zRy>MsTQ@5G`yyOH*#_uj;OH`;2HnX{0WoPZ?DKfcSXI}D)_YNPOej^6yw6f~jJP$kq7!BL_ zF8H6?fw*Qn5!t1L&xN3w@7ePotM6Pyet`2ld>SY!VxVBbrPw|BJ}3^S>jDcE$3bRU z?xHJj92XCvo;~8CE}1+hHyHcw^PNwAx81yip)>WvIX=5*G^w6T36X=tN%1~$YEGc! z+(^l$%rD=0$n)pg^h~5{C*z2;^d*rR5$~-d?rqaYmQJHFeOSwlC9&q67|r)yu1us) zY|t*aUq{rXw#a^Dqa&o>d47mv!(-EqId+@y-1a&xd$#$#+^sXZsOQmHdHVEH;Vch;Wc9b8dk zHD`O1=W9o)!^r>|N@L+e93oZ5bBBjI1wc!2U7zNVRnbDj^)5mt-)_V5f%!@rQO6x0 z-H$Kuj9tFQUUtJ}4=vR0)Cqpiza6z*%+GyiHLE`7fBuHkI$v9Nx^k+w9 zsuwyIOAR2EI~Zz4=diL;}`@C(c#*K+Pw=v*|hlGvKjA+r?Oa8^l=A;nXwvPC-1WzX~dH* z4;xluCiy@I4_^;569bnO?reXgI53$EJ@>Zz5{)mnriVq{QOG9gXugx9F#P3$NyY&(XS6(ly&FPxA6z)GS7~%9XO%Om$Xs6Z>9*3N>yMz%2k%qwS#+kin+{QziOX-;Kb^ zY3My(s*BOa;jQ!WyMtJiMkvcqT8(u3u%K8VN-K8qc{h?rv=5*H{*an$I>T5Fn+3vw zEv_edi7!pz49$P+E@-`^Q8$h&BQ0|jjeJvp#i5$lGj!7VbewcMDFs`Ojd|!+`JUD$ z3yB&@{Bt16ySUv96nsX>FHsLe!%)zYWd=fUQowaAXO8=H9?vMOVHnB0Y9mpJ`hAv_ zAy#X3z1zz@QhSO0`QqB8jyXMgVq($f^$D*pZ{?q^sFS50o<**dS=AU15^eTJUMda{ zbkg749@rTtIJyMX^wTvvbrJ{#KSxy2xdf{R6IFa(+6KjJWYGH(T3rQ(#^RoTO!zz(9!Xo)HEi!M$>(~DR@SL*LhACg42ae76TZqZr_Gbw) z>8w%!6JjNcR9i_q*p;dUQ-xxxR*cPJar$EOd7n;W1rJRBIcCDqN@?qo_g-r7(j$U3 zpPOcu2UBi@C9d}-%|q2g)v^NpIipN5`pSw=R7R&QrLujY8-%r&d@QLHs(u{c}k_n2-v*@4cN zTZ63eN{WT3bja%aY*@UkmXDXnM1&acs8#dMPE1Of$LXYoJDw%>Bco0Tn#t!YK&=d%egydMtnxN8RwjpXblZ88ai+-k zIE9?(bGiW5f4$)L`MBrM>&oO=)k=BAiwCb9>D2qgC9ZT{{#Q@m9x9BMzN1yBFVr8< zm&@4wild8QM_-oeh>=7^cke~A;4^thwvQh@DQZbB5*R5bE)$< z^ZE`b56uRzp!?GvIVR6pWgEhvlQ_-#*F`>q+&9;orkBGdi@JiohoMsi zUt+yjUO?6PI>r_gS^NW2jz(?tGN->d+hnO4zQt5Q`@#=R*)(nyZY-(+n9_8GPhZq; z&PbKZJ#55+5Sa)~`>89FZ&~5?$8j+q zppuQYPv(ompX0upmpL9Rk(>^>%0!fZAs{^`q!XJTgA7`~04R9s={NQp}6 z&zpNGLTani0mXlq+Jp2@ItwWfO?WjwIt6}Z1G5*$yuVR#C)nC zQ3ZadMWq=E2LVM(DR_se?W(}cJ9puk8aH-FlOaB4@_YXal@*T{ZNOfh5{+EJ$|!i_ zW6hYJ94`p#F8}gs`}=5TDpB;P(@zuPSvC34t<^Hw{3 z8lUi0O20lNYPlW{1##i`nIEoO0RwmqN5cP&Pa8rFTa`hfmwZ5Lw*)2GX? zyJYnx;p|Q`MrUzfcqb8y%FeUSC3rvGj%BUI8Yn#PfsH;rD_9szDpU&c{WdkF@8f!9 zT*Bf~xtLEUY&H}UaU`>uYv65dMEsNyA$^PMF|O?y@j9v8FfY6IiPet&p@;RNp>+^(p3%fKCykhLX@CQXX*nM`$g}L^b z!Oesl%KM&OA8RpXx^EM|S|y;<{?Loz084yW1b2)O!+!#ssqyfkk0yatzKDNa_Wm23 zOg-ro;O#nV3O_K1B?<*cnTIEa6k(ryMWsM7$b}i!P-l9sqN=ku1*%7O5YHT5@9qJ$ zC|Y|L9ft$#n1;*l+d{o30nV2wSv_B5c&A4k?5^Vmnv#$D5x26!i^t!LP2uxx`Kt`I zp0r@byrQAg%&$_7OS!rN>Cwk0(Jl>ErZ2BG12+lj`6_gNhN?wbYy(dC#rLO+mnTO* z?l5ByxT4co?$4ClG-q_zm>#AWfG4FMX(`S!QGz5tJaZ{Kft*T8sj`+QiL@;!6od^8 z$#t|dc6i_@oDF{5eW<`1;IQR%lbAheC9rvUlKgg9J1kw&{jGNAWu;l%0}s;RMQ-K3 z34mg{)EilvCXd-Qb2Fy3#mSB#yJ-}TTO>%)dEbQnkgt$bf1H?b$;^^{E9YaLB}Rwr zAwpL)9v1CXy4DI;5*!^~m~7-7J`icp_rsxOxpK(|`BRA*M#ce-OBvcs&V01V8eaJ< zeuf6-JEWmVkBiqWE?=}7ZTHxr-X?u-SNdjSFUww-bNTi%BW*MV}a#%XZ{yIQF` zT-T#TjR*59jEI=m{(0R>%vP7VyzpiEsNp?yAA+Ax_46-&771VZf7pA=sJOnQUpTl0 z3GNWwH3YX1+}$M*+&wrn5Zv9H;O_1ugy7n^1*aQ_hTw1iXP$Xx?#!(B^ZjtYowcgZ z?pQ_RyYF=gvHqBEUV||97Hm?nanL?ffA`3OjoB{}rn-hK2ZI~4^0#BB7 znCxLi0FEG(#T-e5zC;y@)h-Z!&;~qfLI9F!y8t1Z9V|P~def3Q!HjR`=mrsjZwk0K z3D~oQy6G&|kmHLuu6mtok1NQ&CSmf84IYD)f0mnY<>(!Rc}X?ED<+?#XD%b1DkV-g z2B_Sng?8l;ti-?b-{Pctb6eU|Q>Y(7Gn8U)Z zGLdb^&uOH|sNec1tlxGz5TmCL#pQQg`FsRw>N32k`x)oG8aU72dl%4mo!=+lH=Z$? zCl5rm<+IE)>N@I77_M32DBxVHUUzRS4$#=IelgsjYBJz3?c4i`T#LhLsaSMc(S9Ea zotMY^~)?>ogR}krVtX6$$C(0#4iuW`M`Ov{F7x*7QhIglivOU&tFEy5+9TF zGHINI{j)X+w2CEPcx+4GG0JOxN5x~YZYrdBTBcdyc0tvwt`A!44$$o&e`3Q+Yh?IS zQOrU(u4#Za?>Na>x?z0<3? znilwLqgY5u(0yC`{Uoh*Ud)Ft16$sYBI<2^Y+fQ@ z#MJwI*2AAq^gb3dl)aC!CV?O#r8#R-JJJCCD1<0GvS8YX~F{-Nu1etXp>9 zx6Sx~cUGo!l)REW^nASC)vUV7*-Wns3lLQncV+tdE}hR9_r~;?Mwd!vAg;q?n4x9TVe>a;DvXlmltT?6W6;wBgsYDZ{ z@K0Ngeyn}?J&Tz!*z}z&tGLgtM?Pg24VLN0ho=h`hG^gLE0%z~Baiy}uV9i<5Ayvs$i>#{qGwc~Mp$P;sHSB`@= zZII4#yZti8w?M8Yy(i5Nx7s=uIEfuovPdXcKOVw2!DuJksgU|pOA=+=<_9Lwj3D$a zO|g3!R%d8jC+Yig&Y|dx=E^7NqOvcA_&vLreXXq0If8nPul73JkI63=J4bIkG*KBs zN)*z#a-7C6A&Yix6hBZZG+Ms43UQN|MWtvD5e@hhevjSxp>1jdv*#dA!OV5kQ`XWs zG)R0pdv?yY$=LN#VGTu1HSd~mJri~t&5i-$B03ir+}e2~oGyb6m^(Xkhm4;o_K*aF zpxsU{)A0+lpP{nkYX~W=3mkwI=O&F^cc9UwpHF6W%Vd{%Iz54$Td5DV zP`O>^D?;hIjPcKe)h4!9-5Rerk*ol+g}SD9dy!E9l4NR|?;AaDhc~%B!j{WxH^CJ5bM41am#z>+U7U%~CimT6%=M;^{ zj@JveMa~y9hMc2QUGa8EuNU4D)onCihI#MJ581<4WhYl+B0z}dKS|c>7O7H8}##sS=~_61YZ@+3%cy#&sWr5+d6(q$;T% za!)%l@5g=e?d2YE&JIt|wVSu`riQ}MYW?s$w^pR0Y%;hl7!R#0OnPoTMC2aCs%g{d zdU>Z&0G7nPc(9N>aQ(pL?2DLt{+?)GO6(x+mXUi*}k|r_iGyi1H6( z`Ft+9zb=SR(vKHy4TX1!etd>ucl2s?*NKp{J&WIYJe$<~kj$FXT|*fdi{E(5>Rphs z*eK3yFYc#KN~BEYxKsVHLSx7X@d4LW5QusE+T3;u@0YL7YWbT~Qdo$?%=3CCOFDu= z91B*JISuL%f~Beg5GdARVd*Z4{aN~qy9&c^D@?GYa{?43Nz*Frn(b1D{sf+Q)9R(F z`_P@i!QTf3i;%t2i5zxmc(52zKeiLBrdjK*g~#}gO=|3TnOj7{pL8ozyQat<%-%Lz3>TCN zJ%!slF6rQ;eD99jHb`YPTwvF`fO(&E0s>1qg8?8tw6_H43C&KC{W^=@oA>opq z^-@ZAgP5u6tdtf{g6d4Cjdo^QnfMkvk(v$f z+Y|RTqtO~<RtyY1`RrT9B!JIr|wot7eo78DNQ^Oz180Q>gUMyQ&m zmVBr8sK{N133Eb`jv{;c?wa~Jj|&`qtDoG9U3=!b=zSghdoM$hOFrIw_H}OYuV6z` zSShaEWY_D7HSiv{^!Zk;TDhxCFV5;+3|ECcmM(>j54AzTXGtu$F`8cB_;L_gi_4zM zLi`k>Ljb>rY$Oh|p`Sh5r7*BL(DU;yVAY--p4Z9|6zEZuqP`EYM_Xr0K4j{5Br@^VR<5b<93TLOWmh{4ap9NZUj&(bcYwD^hd^vk@$hTje}tOUxct zT4bnZrum+MI zjCD*UW1mp4e%T|=3D7=|E{`pi*u;Azvs$1#7B(IgMDiE#55I=+l ziG-LVd0Tksl=qKPH^Wy&hL6U<(Vlu`OkChGKqlRO#*(a=%RA_D$PzzI=O_-q-_1LBcJa_jef4mA470zUp8vGQtx=(m5+}hNEKzPfm7ig&Im{aF<=-@B z;H0I)2m{TUbv0M2#@DsH@_3y#vZ60v68cToChjVw- zj@)5=Mp$42 z!Bo0>8lTI$ejP(Rpt`4CHbRwOqFyeN#~jdJqjh{DF^;Ln@_VjbU6i1_BZN(Z+ci7r zz7Xp?rdyIFA<2JKl$@$tRssm*N)a(5JHy8DGm^?Pdmu`>ZTt%eCh>2_f-Jn(VN|tJ z7u$8NvNN78f2Qe zV-W>63@gt_sq53XqF*f#OgV%IkLacK+{utYoK zIGCAanM(}9Zj#Hd%@z8Z9(E@Z<(>uH=#{Ls93sc&%Yy139K1&ukc0dUAWJt;(kq^46o7zgFGSF)SREdJu~N##?5K2|`>mXAew zoI>r-&s#Mrm!#K|XACGGM?b3b{)WHw+1xOxrE&))cu!=1Iz#-v*Y6*)GtW^GF~NaK z{xzv|Q6beU1|dWwvh1??{!O#@%8BLoMltgrOniHb5^diOx%LAtq)$?!u{@{&lMfRQ z21c3N<}22EgIk(qDvlw-GCjVSHI+CnSPBG)M*%RHDAx7regF!tj&w`~BioqbC=K$Q zI@v(0aV&kL=tQ*zKIS7ZjMqFN)M9p=rvZJE$mC81$)rg!y*dkO^|?ME^S1OUSER$F zV;g+DdIfa!nxV}`!&^@2W~)7(lU?QACduOti00YLXPVP?vEIS5yxh9SqImz|SzCO! zNCu04gxgDBi5Ufl3h7j|qrkPNerMR~`Df6zplHrO$+CDk;3v(gd;+QTd`w)n(AjVv z54g+m60-TCzvuQ@j-!U9T?TiHee6WY>ydY^8c2 zwD0VvD%W7du}JIJQ*NCWT>_uA*jW8pE=#Y+V>2a6{CL*(CWzlj{P5aIJ(`$F%Xfi| zWe=l0za^e`VYNv%#&hQ$7N*!Kd(&I3d3+RD>9U476ip(^k}Y^ldl8@ZAQv`7Z-m35 zU2TRW6%IiM)PLY|CqoRy^10fdfh?$}Om038L){N1$A$}{<8+92}??-1qgbkM2{LVE9{3|;@wutiq62*tFzk8PWLRo~&*zw=vAjbIjC@~*Z zSup|nFZ+K`&7j@B6gt|_uGks5Ppia6li4GEhI&7X`rd%h^Qad5%h;W|ZV!uu{}60= zb=-W5_o(b4OZCG>Oy|xdy_?`S&A_EMN`IRQDnQ4Dof81AmA6X59_9LxEQ z3!fjMIYFLo?P227Lr1=ko{MC!7F_g&l4J#s;>0g^75%Vf>%9>AZuJj-V(v^-v);J) zOn+*ZgSK8Z8Z>%u_Tm&!S(IqhtaRyQWwtkdez3J%P8zM#K+3@i0H zJ;I*!M;2{Db`x_7s#6-%KtZ*>;@`ulAyx?5mEAAT5jrOA-41K#DTcv(cnO2#4i7gJ zz97xFTrju<=o?T2=05uOM>LnH=*{@rk2GNVA6|I=zNT05OVvr+ti@NC5e)TEI7Iu?sM1gt(W|2y6;YzZeIhkX!7H*AP7w{SM`pI7 z+`jwa{4_XT)Lg&as!|XrD>%VaK8Zirca{eKDldjbn`I;gthe9xP7)B-nG&i0PNZZ@ zv92=SLzdaNvv?ysX$e80;%dW>Pqc|eG1A@+ywSSiM!SR-C{Vt3a-p7uP^XP2;BAoKf*yLVkMP-Ovux|Lfwhr zTHL)}$4-(tN(p)k;bNO6t{IS2mNG*s?Y~3@jA?MS!r>!jq8TUgkPC{X40CbYuEfVdIAHJ z9)&okrW=mp+GS}d71G9LrBT<@^!G%OWV-|zsh_Q%2z$(M^Br?g!90_sg_>;ps@jc! zd&t($qxpxnl#f4p9tHkNDUnnUIg1un7>LpzHUpXCzmbmVTC81`uiQR-9mMPPU0YoctWGi zUnzz<*MpvK0AAnO9nUkKps$4T4S#Ukt(6DHwrUJ?DBo!h(W?*G6&~6MeD|R?v(dH` zEiTo>f*gwrV115_j+yOQn_D?SiB4%?=^ep-$;CrV5?!iF9DjaFO`S|qGVx`I!V)p{ zx-O^%z&%FzsitJi$*=N|XpgsqxowSm)(8yv*`N0IDSoH1E%u3ety~HqXAR zVRxoO$i}VxO{)Ul{>_{|tA1k`482ooLQ-tee7Vum9=bJtb3fC@6IKtX2t>hjyW4(y zUK)V7)=u-~XZ#=F@(f>3=|_}T;LDDr{t@Yo7fCK2Xtc@6 zrT%og8IXSeq#uXV8i7qUEAGNj@A7#)=gUl(`44#)huBnD7RbF{QmXb++5*430)q{DDfc+*}-M)T^9cWmcP5mil4miQi2z zg@;qG?A&#kXs_BWXaIi@r+vbsQbVq*-^@?#X?xasfFY~Zt8Hb4U4K@jB6NiYr#%)V3i`faLelHZLP3gHZ)D(Lvzsy_isl+eTF6nwCVqX+%xTmrGUSq(r?`hpL z@Rv!4%lnYk$wPuw58H8@R9-0Pq|LSAGm3;him&&h zJB?FM=kW|ER$9wM`grB>6g8R7>J@`;3YmFjE1@hA;dxzNI9p<`deWDGg-|N-zG%C= zI1M}=N6Bk4rEr-HX4{euxG=v}0n~*~nAYo^0m9+LWPrKBG0N193i?^plVK?uNJTfq zk0I3g(Z(|I#MQ!OS-dEaH#?M~_lH?dW|Dvzv-Tbdv#d`m%P%pUp4oTSY}`6^cj{e@ zTY8c1W*MI10cXTJh?26Op45-lNweQ>+kc*Xj143T-9~p^n zvY!uq6q8m`QWCJ0K_Tp^+qBUE4r$RWi+5BejA^LzgX3nyd2G`fS@a zHgDJ*$WpxrjgnW*qUzoGd}kmaW9<2u8Xj$n%NF9qj6tPGIG}+6KZGYV@^hBS8y3U` z+K7{gnKxr8M2lEzRg*oWc6}k7VXoC^dGA%F&tp2vYx3#*rzQ>9B+#g!L*kF+Bzbio z?}hP2V3X=Ky#%$se*wvDAQSz`;`Eh}pkqb=1XIxSvRNtjo%Ym1s5Qk@W)$|`-8j-^ z-gSE8`%viXZGB0Xmlo&E6^(dvLT;w4Pf=g3mzW~VJJX_n8``d^=&x=|-(56`7>od3 z)kn4f%xWTwl0`llF>}vD#Vkh=8@mq@j}Z2pn*KZ;SW1+z8B|=}|Dw2T61o}F&&MA} zEPfr6mNR3?`~p%jCe>j}e8A{&dR}j!9|R*Ea5n|2_%M1aAK_tTApz zSi!`1JoM=yXI3*0FCt#jq|5m7x6N0H6{7c?7I~uH7nDK^hYlsmJ3O)p<5u7KkT_Uy zYzEq#SM4aUnkHeu9bty!Z+NR>N3jVLC+#!O&zC&y*`{ZzM5b01+lilNU zu1-x&+4-)oRSxs>@{H5#@=;1PwRQW}d7A=CD@jv?-bw({85sheml-=b-O47{McA>` z7)5UQjVaE4L{a%raAuE9WIlI|n4Ch}HW~a{4w>6R978H@K~i6R*O@lI>_C&VlW7Wq zF47h?4HKX0mU*>;cC0SvH7(|M&Tc$A^qPD-tf^UJ1Ke)cZ+&iBeL*~`65u@VO--u6 zTi=C=d_F1uy{3!^OdOG;`G%r{+-#*Ufd7MtmcG9ROci%${InS{sh znyE_eGHfrWt9A37be78f+|J5Z`%}81MftYI_%5W2a7N1LLxetO9S4CvkP~ku?t6oi zLYm97-YXrs#nLkB)sId4HI9n@Q}M*EeXq%U5=St_4TB)+=)83O|%a-jD^~9##lpCVzTI)wN`UL9;f=nB|w&S&Sc6eigb7FH? z-X0SMoZDk0-jTrmTL>}_} zb-z&Gg|QYYc`!>?nFk$^2Q6-+AkIw;jP$-?8%)61AI4<#8GpZ2(DOjJ@O$aPm}KP2 z3XC7GJKxvbd^~{lJo+6wf*E`!zqXbgCg~XT=YsKW>#6M;kKXmsX)>I7_=I)Seewqm zYOF@W^G{&QZw2B|dQs6LjSa}YZOKCCz2B668=9qWgD=bPw|-qb4`T_#q_Q->F9r|y zL(LRA?Xm#eS`6cBxXt!z?cjwL`9?OGv837Pw8#d7bA+{palj=~1+o3qenq2%=+}-P z@4qVC#j$$JAH`VKoJp;Z^{V!(DWY14T`&8?(B(}e(O!#1lL^I=Y`=S(2`GaC=_7g! zF%7;`0|6e7{X3tV?;ClIgL@yr_I&lTi@p@2^#>r<4}Y*t?}%B`X3H!TW+;!^pw*-y#)Tf4VosN#%|!{dEp*JS=7Z$pPw4C z-?r(RVf|hQnuVFpHN8SqpbG1a(D~*45Opd48kZ5J?ha38*nrKZ->qZaNj+8{oAUjx zR8v-9oQ~UxkO8$M_Q`?1FSnu6g?1UQZH?wnTORRzRsDq}>d>DxqW}U96DL z{KV=&Z0NUH1{o{?ohW zJEnZ^dtI%D*Df|=hs557qxAWkgeQRn27wO1S??Lu2H10_FT zL{JEOm6z6g&iC74_GFu_Tmf^4WI8xmShNuOTdtRlK>3VDSI?anz$gv_fi2hhLgX4H z3Uw7Lt8{SCvKn7n{CFL$)h0oMwC4B;nEcyI1BvyoRI&>Dx#Out)>{2yvmiRl&sL*9 zG0Co5jLTFgRMm;`?<=b!eD_VsUMj(Ee7|@T(2T|oLlfMW>OX}7Ex=zas>4GJG-w1P7w<@5KypO@DH!EvM`wcV&<>c{yu^hZ3qj6W(lcaJqv6kBqYkf zFJW7*ze8~I!C|%HO8@xT|GZ%bcx6~QAJ)`fK>j@#ZrIn;Rni-~G@CYfSgrSZ`^s&- z<@>HIR1U&tzi@Z~Yc66(535g@M_4s~WyJ8W{|Xz9PdZpKE!&OZHgu<7GwM8{!V1IV zY@=o^CB*LL&DG)ma`y`9#yTV!7wT`yfF8!wUkd+rkedvN$;Ax)qclb4urXfzitlOl z9Oz^T0IF$j))Hk_{@BB%{y!YzAcvSk@kh-z`<9fIUON|j?>DZAMjaO1(^juhVP=(r zL)Y>SDHaHH(7AQrtqWXmx6Zq13(#iAHfdv$SBcH|_HDbelIB+N@87Ik9lpaS{Jx8C zNfPRikL!R}yE%n8=&Iu5U0;yrp_2iRUv3cMJ95mY-(pRD-D5bF=P7iJ%gSh7-}yVE zxq1HM09Ek+eo`$ZpxTpM10$_&P#ZGq5x@j9)Nv5{kR>57$sEe^uq(V0ILbXCQZ`V>|GE=l<#As{`DF=5JBn$OHtR1JTvCg7Iutsgpv|o(`*N)k0ty z>!1^n`>L{@jZE2>O{+NjnDP)P56@L`eSM}y^&h}C&)*j^7&`ppW?`??U5SCfDyDSXCXHIYW%QL+`eY?f-N4AG`re92KIJFopgP0YU$W;Sf$A{9 zlxQp{oouK#NVa0<^>aoV*&+qV8rKpYU1z7W=i{NNYU;_!!I4DK)kLrP^eIzUjV{yr z+y96@b^R-Nrl^aC&M|C*askY8J;ea<0Va>@saIAXcg|*?PNtnm+*K^M*7P1DIlI<) zAy2tE-5-VjL;C+mtc_6X9}+Owoc=2@_Ejj04504cG~sXZ*&hz0an!dn|5F+Nsh3>v zuPcesdNuy3YyVU`A{ec`f4lU*4vNb4|1(jp@@@E-oc}r~Z9gzNX^Zv0&Bf&{jQ0N+ z{O98Q!+!o>wt_hJ3^W%))))73$6p`*F~|QyfFzN8y&XwBawNz;zAM+58ATStsV(|X zzJlSC@Xc-u{=RGf2YH?t4q4l7yka-xpCb9c<{3vGMx?2j2>6E${g(|x%>t2FtAe{M z8Rf%&>X8H;60ufP@%vlp|3ZsfI$9}dP6ZCyt=@j5^CR4*N)yYjScf^^BbuIrFw;+V!}|ay`9qa>`C|phmP< zA{a*v&dU5lH68O7I8hDz<7~8+%WlD*VTp9giiR-zj5_F28;72kRn?KKgfm^JC0ToV zR9(mEKiMjGg+J^M`HIoefs~w4z-|kE7UJ&Rew!5O{i5F!SXNy6QxQ<R6@)ri6J!dw!(i?*$`6J;IGK-;y(l2U_0sO z%7=Xy5430-HOo8jiH4$d==5I1NXM)0E#y8kW?AX=Zy-=|GC7rlW^LKO4Frcy?gHO# zDkJsvIQJ2q%I{++i=a<93(b#U1tx1ur*n*Sx2qUB<|w!{GZiD%e_uS5+E=GJd21FZ zc(DIQ3LOly=gKrg(V1KLju{9m0d5~6W^+Kpmy3e@%jxZJk6RK%{Q>Tu)aAoT;5SQj z+rON_Z-XT2L6&L;XW7~>g6#vGYJ>0T!Qa$4|Mz_KFQ)0wo9Ww$PhZB}VAFkF{zote zi)e1@Ei4uKKe+oSLH$iK4V4_*Tk_v0|Cjloq3H)Ie9Y{?`(JDKPtmcevW@+uCF=+!;dd{HQxCM4M^=0BJorE?3s1( z+L=M>p06hPDkDjku1&?D5ZpLt|58r%9PrLN2fcDW!+O$@vjw+`>Ot2uh}B|PjI->? zIx&{qwT?Oy5Vke?K;=(YR^Xa%5Lkd!|Am6u`aiixDVLb9T_-6S8XD5j(xOu)epQeZr}@k+4Z82ggd z-a?U+tO%d%V#AukDma`?B>l+uUeijWM2nfqR z9(I7H;~To;298ZB^KUX(d*1A{{vmG41}>9=h)qg9UY&nVG?BjJ_vUt2Y#vQ^_Tj)r~sw3+~~UZfbzj65(FmC~Ck$w)yI&l1t| zdJTuuxK)FL)IWWvQEFtT-KFL2`19>e1dqi&Il(W*MA$r^d|!e`@TWc1DX-gSb?Z$8OwB>W(g=KJ&g#H~1M$~(c*mp7j{S9L>R*%kJa-QjK<`ejEJ z&=zIs^d9IlquV9gu-)9ni=QsmndZ&<`Mxlor^^C3=BUfLPu-x+fn(puSp4|q`mS*S z4w`p;#}8ZWDG5l&pjUXfwC~jzrR{VeV?u?IuH?Y5~1H=wP|WdxK7vazXL5 z`$Zl4OnHcQqj&q=_FvXJn^~@|VM-O=?gr4bEwHTV)OP>WTC9RC!xS zX;fviO43$J{+BKVfCUEkkhbd7wS4h5H*lqb$LW!bN9zN2Wp|AeK2nh9Kd=B|r&;!r zP|oISuo^*e5ZVOsDrdFf*uZI54PuM%MHccY>DFXJTT5xZHb;G>79&<)2Fw7Hb zWnG*d!Z)cip*UJ==<&bV^LG2*qMJSBU-HjAxcoOfNT{60!n2bymGI!z0B#xDKs0w{ zc#NE4nf`|jtQy-7@`tlp6tj(ctdH?U+f{+e+U~Hv76%Uodta8n#^vl4?t>!HUME-0qzYj(#{f7LPOFI2MbohCR^1Vyvb&SOm>yLL-`_h9lY7#X-o;9+! zwQeKQ2j#WI7x$&$-Xzsu@?fG97}Uy`49IS)#9HRazjR!brG2I$fUHBWMW?=1Nxv2x z?C5o}LMvNtntxICr9I#G-P6?aY^OFxT`emazoYs(a$wTX3&$c3tEY;kWFAuGF9VW5B*B+O~tt0DHZZMa<7$p*s;Fi;V54fX&}s~{ou zCNuZFR2Tx*p8731`6e2`3@t#QTJQahY*qz4x{bbv8muv-r8F!)60k2h4R>P`FjJ!_ z8-Qxq=9pn^@dtVgXm$Hq{AKn44UT}$qt9mfTh`;_suqQo zBr5@;SnYFPj7SaRr1-7Jy7JzwZP2J~S$_G|-M#bW{E^$Q0pk{g&XzyumCd5%X^%p8 z*gd9eTEg-pBl7p6!H#eABq7Ki_Lpf}*Q=@GpHDh5XSI;zkPF;9o7EpaX0!|s_ZAy; zU8mut5#buB_?LASt_6;@@SMhZe_p?j1Kh4gr`aRcyxU4n$ze71hlW1Zbk3%xrXLa# zT0b7p1v~*QaVDwutt&Y=?B~V&DtE-CTWVo>Fohc^oqd0VgU;{$e&crReSPa|26-J?YMsKZWfr%_-W zQeAltv4Y05K}*T_?-MF^mfBroa=!t{Mnq|98=-z9hL|G#N*Gk z2?@!OiJf`F_9;kJ^eP(bbFTY-MW^BS%!8jt3%u>>4vVE}SVFnAfY%hM!n0xCjHBM- z&!zAf>$}&IjH9LOhI`CVhFNR%MMb z<~+vmsz2f!k2wdXO20f-wTWuwMdW-nJ?Y?ZY3e*ID7oJ!BRgJBDXfb+ZRHlhiIm(z zMU&*CTeHat+aiNEBI9@Fjv4J4B!ep~(q7E6h!^^R!USuWZtNtCNRDNSUPNAs7Wd^QL;H9MO|w9`|4@mlwu{2O%a0Z$wR zhlW_EB5+Df5#}({U9pvGP6AL9IGD43E{*8HO;fIy7_Tny_#YDFyZI}dtr5^&Wo_G&m5q%b;Ew`?JJb2fbyeeq zOAB)A07eXN|HSM)#h4$mrIbx@ZEb-_@lVEsO8_7kA zPnBI<64UKwK+`ilMc?!eao?YN6i+;Zz}TEKZ46R}gbOk*HP(2f_0nm;fIQD?Apu%v z7!W%AfuLJXMP*@t6%l!%N(Xa6(qrZu>Ux^eSO^S4V&uJ0)jb!x~BG0oBo@$fgv^Ke$DfRX<&(R(b&Di z)3e|9bzt-YKWgP4(yi;Kr~-(q)N~Cp8hhE-O}9EbWj<-s3{>JtwZ%g}mQ27^Bq0e= zuJ_js!bR~~?p%9!l^IgRMYztlg)tboKT8Mryhp;VArk26g=tBGSg-G6YB^C?fZ@u( ztB7uf-zy&!vmVYm^-US|HdI>T2cZa3bC*aKduC(;l(jz{JFS1%P;d=B%ms>ioUJV5 zpUq*gzIip^8dw5wx3TD**qJ}~FK!l}Ds`(6)$9Pvc`zYG00`K`Ab5lvCh|<#<1mW0$Z9Z@35?F+ zk+KchDfKT~#Ugfz-AWo&31wL#^kGSM;T1jxEAFi|sc7$*z^uOW_)Om=Z7@J$)Q+ze zW%dy%MyoBeQ6j2Ce>g?cr764tlgkR(AO$Erc$rqEeVb%cX9v~lv&m`pRo2gnfS%eC zRuD2zc(S6h^>gmZ1^7az>;7Q#s~uj3q;nG-i3K;FH`A_V?l99Z6e=PIDi@re%33Aa zxh7T^0>2RIG3eBoFp6sFzJ{bYPv;FHDzfF==N>PVq+sF3lJm)ImKPaf#NxP|XP7nH zTxhIITQ=F10Lbi$*+97T^G@nEN$=!6C4JA6$~No`u=oGe4TDOOt4 zRlV<;jMR`ITzV(k8K%Htqz{Y51}(YRUa^csh0svZ!WLwBIbw36_0LL!p1q%(?Qx7U zzH9aG9UYi}s%B1*Yg`^n2*3gGM0j-lUZvVd$cxg6uSXCux#Dg~aScv@tLnh3GXAv( zs#<3w+EOJpnGV!SYPC-Q7F2_*V4_Z!x4+Cc4nk^CAic0RSe~=O%s}gH>twNhURKgo=2}Kn#|w4V~F2GSRL>xz(*hCgtY_z?bKi5?m|0Hd z`tay`uHJ#iR0lOY*MPZh+phOify^%oo-KkexpUW?+g2$1KZ&nUJGXQ_Upx2}kXFBw z^<*7T)-VJ)B84Ew)|o4VBb-$Sm$2lR!HbU)BSQV9o|_?;0{R){PWVY~w+je!s7loO zw{s0rhCSoWvD3VMFH%5iRV3@`5s`gR=lJG30HZ|#afPAaxbBYBqo92)7IJL+ZJ(Gk zSRL!<2mNo9NNbXD;&Tddzu|)r8`tRkBrFo`KF!JGHJJwHlp4?}FVxU+sO{`!x=Q+| z#mPGN-Tp4~ttNt`IDi+}G1_Ukf-gQOtuz!J%S&X|)fu1+;2FDDtDZ^b-<)9a=y#i3 z;L~{+4mNBGZ@bocqM`yHqC_ctzBr36jJ<3;OVoBB!#~&+T$LjLgilr|wVVPZKZTfl z4Gx8pN}5e0($z~+5KMEU)$qWVIDl3VM+{7)Ks=}~IOAL+q&6|}msmPNqCu#1D+nS> zoX?-~d|QWAN*w35_v9wLW*cJ2T)XyItx zeg4&}gP!Jtt~Q*a9lVP|r3yECe$`ClU`mnyh(Pps5wz;aKjPT7Nec^~P;k}5LO|~K z>Z1f5pZfc&iT$=O6(_GqO%d5?645cDuj_ti%4i1haxocTnLWl3PGp12x`6h>Bm71VX2zlpqxeJY_bB*XBbz;7)vEuPV$rtSN#QeP##yenLll?J~M9@2!6xwwD- zn&aT1TEB7a+o}uqDptw@vwb|TZMqukKAP~&;i=n#Eh8id0W1m8E{1C&Z0b_K{#Df;u%7aDWGc~VkoJ@375=2}g4txjSF8~Q^J1Qz$Fn!_&O z?+;W-!9YO-ky1gVMWtf^MM7YRp}VEKOTqv|q?z?55PoBW!r>A+JpTAgo@yu5Q+cvR2qoJl`u0yGL zydSpZqI4+&ul-UwgU^1=39s)A_kQDUk{R{vUTQ*op4G2A^I zf?wxXXuqvdxN}2O6P5E!3zwWp^g{~C;PEi$?OXDwnwp|)zj5he(n856L{d?;B`+P8 zx89v~-Wh2lE#xo2k9zi=BB z$4^eOqdYWuHEXfHw{URXpJ7B2A1wRyO#ad(lb+cw4(i!EU@6Ig8yx{GYm9SA&D8g| z^5VFz6fi374?DwF;_kkwF$8JDfkK66igSSbZCQd7>O(TzaEE_@6gm5!WMDrNqg%h!lnKxdInI zmJvTf11$$(%7qZ~g6=PS`UXshl*uOhVggRcO{Lt-z&o83UBSNnjo+$%?RJquIo0L$ z1|$hDQ`#6zk+(xU&l*U)d}1{^8jA2(*j=vPA<&gy8!HLA(U_plnc$v0(C|A=*iI=( z2FK(O=LHVv>(f1kPcf~ktE56o@aQAC+-;)E=TTJC_5{Zv~ zyu0^P*sehl^ppyGrI|6&gRSoaga6m6Dx@-Z`RRx3vGinoyoYZ%-#(WSt!WpDTydZ* z7w^FLbj*0y9ZG09~L0=*0umaEG6VR48c!}db}`rhC$yPYIsh;m|H% zkhRsb$h!4IBA-TNdMxSY%3aKcpe5r=IwDKNoOVy%%SqLpF8-#JtBW%$e11A&+ma=^_9%Cqc&F zgyF~4yr5dGj^|BY{v83>^v0@RJLy)+4mDmc9W`Kj7CEEBW?=h}9c{ZAV(r%1TQ!dq zP8Y9^Sj~~$MK@E_>K_UvZ4|)9h$OCjqBQ#4R!cu6F~2Y`dYRZJV)jNY_jpI=ljC*I zV%kF9f(4fZ+dlSMgC?>m-GVN^-ci?pEJxA%)k`RCp5p;h!U(taZN#q+<`!icKy+!Lf&g7LgKeSx;rDkEn?9u!9F6y#_foaxAkRb zNwAI}NAFX!sqfQBe2nqi>DauUn?y$&8EGmm`Bs)cfY34|^-?W#PV{8#g}a6xbG60) z1m|T9JYrp?wphh0_nzgD>bEhr2B0j7eh(Yy_Iqje!LHj5gdM$6b{8{(H-&pj2P%n%R@NQktGo-zeH9)vRRZHjmkAZ>THFMtlnJy>c7fEmU z>=&^kW6X!Qq^EeyHWYOC3P0i7wz>YzO8wW@0DK+s8GdPLHR}67n7BEEoRxKs&i`ML z@0ceZmNxR`6GZ|8=DO1VbM^f@LM)I@=rBW@O~VX%u2xS##Ve!uDY{v5db^Hs&xVx$ zi14*6Nl8?)&P|(V7X{sm@v80JoFeG1JqG5zVM`f6xalvZ^1ZDGHe>?NPz6xv;IKV&6JyVIIVDs4qD3e}kt34WDP=MFP{WxlVp8Rvk z{POL2f)--M?ZD*d+uv%>h817OWMn*$MRdmEjWkQ4DV?JdC;!HT{{7V|{nBQbqyHz& zVsrBYSygo3Pa|qoX1+o7>bVa1Qog&4mtE0X%k6W7M&OQkp3qWmfT8mqX?`t@&_E1S zwPhGV{4YzigsVEN}{+4*`7S4?QV~~&!6?bAi-bf8$iR9j`x`Q z1)-kbfFv{RWy+P8|A7hW@IANul};40qx9d`@NYMZFOj^g$AFjUNMHYR%)d@7k^(>y zIgS3JxClukbB-i(dFuK2kLTht=}Sf6VyBif_=0Q0jOTEvfv&}`e^T%9O~G@xltrKD zMR2L0bGVcQOZ10};8Kgg#gG(U^q*jobn)xt09=YFRi2*of{pzD*d!yLQyr-<7zlxX zwJ=xw=R*dZja9ig1OkbrHHalryUAhnVt)kRG1}VqoT-t z=Tm51!UbDIZeB2Ip8O@AD-@8B&o>Zn9s>{W5oy+JI<;gE3M3-VPUSictelg4X!*CN&P5)-3B&lNUDAx zuk~%{^^md)9*mdrKL|ABsTkMC=;039iE>x-G}(hKA#qc_DQS1?{^TL);$|d_#evj> z#*`nm7_}Ct7127Z5|pana@((rXnrR>CFp^IyU+8X8kRax>Bo|Ey*I zdjl3bsKPv^xDh)ma={yRJLd+ToiR-;Ii%!ab?z5Y?&W{L=KoqWaGDS%^IM1Mq44e_ z9eu6G8~_6R|4w?&!wAT?sq(k0e(9?NM`)f6lmvL{O(^gOxa$1QJjqKXq!h4iG)<1a z(e*rniCf4E*ot^S64TAf^w5x%F~?KRD*KL$iAafuGp54DB@4ah%rPb{ZzP(man(^& z{gd1P%AEWP^ZQ$I>7mhd!sA(av(*L{9Lo)n%Pb|K;*+iKgE$6mG%Gim;DNe(s=@d>SXC)U}Za*`stPHd_iGovcL|yKnXa4!qC`3naVhh)( ztgoMTD(GAp6B8pB5mYA|M0C(YHwaV&Fx{*t^zwXBfitW~g+l)>T?GBxAjvItKpp01mw`w~AzBWcbiaYX-74 z%2g6+7YsF4y4KqK1ifA?`3Xk#?d|O`3kyrDs6;W}zc0aEw>2#sNTkMRGsZ+Q?FF`L zSn^6mb~PIK9$a4?&JF5cFvTpft9KWkHRzc4rErk!>?oG5yHEBe@Vvgmq07|rUY|0q z_F=;A>__ENR}`P#v@=5NYoLmBJiGU>3AiT$gw2bGy3C7vu60TG*ai`fkB>XeV99#y zqy5p^XGbd^Ob1w5aEAR)b4fF0TulcRVZ|6~l zY@9js))tg{Zu2A^B)I!u51NjHxZ|r>KDqx2Bsg~4n&xEi-%Zp7oziqjP%fJ6-g$e5 z2Az_}r2{=2!14F&YNx!3#eQey#W6ohpEs#MX6(Qewh16bwYw@>jmEKtAorPPl0c8} zhZ~a>k?dz%Dln0I{C2xB&}x3A57&RKBlE@k|M@nHhu;~41+pn3TEBzg5dL9RvyRWH zgRrezPF-z5nSNNWz)?!D7&e9LcP+|3_Ti1KZ#vLLs@t7_N2kC(XJ}|h4H>=Z)N=45 z({s=Kv)eIjEoy(RRrVChauZAL~cmJe+wx6)fBkErK{i&Nw9N`s^GJ!e=6P`}jef z^~YDgmsu(7b!8jKOx3zB)>?m%Q8tQ{_rQp5IJB>3cONgOGV}28)Ltv!^+Y$2nN5`6 zRVk?LO7R)oaoUkueyyvUQlNDC;|F?rPW~B})Cuzp8|6ajevt);;KKgdiumxoGjAOv zWuY8b-6>7YV${{em}u|-#&aigrxvA(Qs;CD`w~6k^u6shE_SI$BhLxb+>Rdqja)*(hm>l%{>;dqT^0ur?CQKFo7o zdwjXh?x=8gYtZcJVqTA$d+uka0uLHW6>eIU@vL zP+wLUvZw{; z>4DxA2*N^kKg@v+f|{c*iC67%l3v==6nT-e_2{UW7^W%6mxaJE9N4aQN2q2y(Ajk~ zF^{m5vgb7cZzei{8b&PKa;2Sno{6yew|dJub%L_l_0iU!i(?OGaXm- zu~x;202t^pml34?I*ucn;*cooX1Qd1`Ui$uu<%3GnZ^&VlY_KTr|vVJ`MO>^gkqw% zQb=O%ZDMI>SY+pI}JM7sp= z)e5ZG?HyCitVmIBAB>rN-X(w(Z(EH_v?#2NeQmgr!$_uG%jmi`rVpQoA8t&LrpW~d z7YR_$qEp>L!+S@FYd6F0+#%=v(qcckq4sX{!9{KL7iLK4pRjYp;Hy1MQgBVKBc zF%@xLf5X}ROPk6O#QW%b3$Z%WaOq^Ijv`GoPo64p`MZ-VQx2QRy8ha{7s}) z>rz8g_dRz_->DX^(8Jl0aPN@il!wV9Fdu1 z1SfqW47~oE0gwL5spiJHTd3~iXA-~MPkuJvMV=ixvO+pUtoBu(u7H+Tc;rRi1wRSM zMi)#7`*nlXR>A0B!YZyWP88$!ktv>Oj_L(c$)h})m44V)h`b7GBx*J2uriH@UEkX` zFzqEfrHid3sTo}8;o0B9RDWr30r;;Nk5YI2UK$ZmVZECkfD3u9aN0EjpxSw@_aXC9 z#-b6ktyMGF#}T4JlAtuIh%1}Z4f)8*0P_J#q9q-j_4Lg5vR76N4MzaX?enmG)H?k4 zYLP%f6VC5whYI#oDeG>;cja&IYh6QFe@rB`ayaizsD(!dF1*s9FUS3We?{uD#^+tO z(5bMQtA6~c&zSrKTBu#|N|fmM@y5{*nZeqo+6ui|WU!soqq#1SfX0e>a4>*bJv+57 zo7fAL2vLa7K!c8CxH~G%dv8++G=+{>k9H$xd|*{~{ibeWL(e3~VJy#B{%K^-zP*{F zEJ67x63E?uqO<{hW)UC0v$MSr1%<+D7x$4Yn_rHM~A32(V6ib-hmoq5%pkhX{F^)Wn3{s{Q?F^ zimN-%A4j)G_^X05VoB48%%X;{NgKz1n8L(q;_o^jBrnZv8*aU+QyP_$jp@Hbr*~-8 zElzd&QxnhnMDoD{k%r$R8fnp43N$Fs`i$hOX>NP@G~4@y{06Zd4Bj%EjqbtOZOw#1 zh@TPH_%Kh*FkTygUMnhqDnm4IEEpuG<3IPfz2l64XIN>f^NS2p1x<^I9(wwkL^$d{ z5$9~zmk`nvZFcV+0>WZjx*j{RUU#)44F`0-`&rpg^e(K5ya{kzxZXk#p>>#?QLoVJ z=7D#Eyp|^1|G;y~l?co%+3c8(`dopD(4Sj|n?R;^n9}BuXBtn^Iolt2?ne^4Y_DX- z8w}Mbs)Fx4#a}7{nl%w?574pkjUJn6WV_imfvlh6_c!C2bTRg+G~GX1$bBJG+^{u0 z>3ZpE6T^3)r%6{r_N&znYZLm*T;)CzwMIuuSSy@!twEWn!9Pta!?Qc*)<}i5`zzL3 z$8zF4^wBM;plHdeaZ+!LX|9gII^X&v)1?Eipu#6`S`^O7;{l#p!r7 z+3kjRZZiO-DZW;aX!j({zH7L)j^9MNH+&!C)oYRx8xwOoBrJ@*ipKSGLF`FsN&v#{IxaKJqb&#d;7pmrh7nN_!k3^avxXrH|imcb0E zXD}N8i~e(Y*o9h1+{=7A%HE-+=4qY*tgRXzQ;~e0_9_Aaz;I)1F)Y2#KaT{ z8M}!e^%{-gvs|*7C=b!vIH9bj?s=%xEQUu2`BJ5rTG}CkVe8PhFqo{?d(UIQ7Ue@| zQV_vY8D|TBT!>;53U_pQ;ubEN9_YmGq|dI+{rjILazGNhk_nL2f{xkgT*rIE?9xA; z{W`wiOwWHECHSWWnsW{CWwE`8HG2iQR2a-vx8MA6Gg|nctno5wOt`Kb@jv(bFT+>k zJhOFvzWo9_SSelptpue$$wikK34oa;#ZB&9H0qCZQrLgZ_`fr(n}I-9&i!rituoK{NZ`>3{XK&Zki&@ovqjvr7o+eSTu~l%XXb}yS>f)BMvAaU;XKy zrtM$81t6`G`N~a=i>&&~26*eZh1bmTJ%{UEU&fuOWaQ<`X{RwaWfc^DGE-4fc74)v zW@cdle_k0uT8P<6$ZcQP+5+YY9&}T8~>f&|8|96sRF711naoidtS-; zg`K4+b;Y=8mAbt9g&t4^GHWuBV#n(O$Ll>?X1Hem#eU*fukG~H^l=C7pq{JTa8^M7 zio5l#y}Oh$pFP)&Bks?A1%#3oXUa(tVi#u$iAw4ho1ZPM_v6iRK ziW;>A6776nW_;AdrR#)aDw$E>?k)e`xK;oDNIN}YxkxXO$#w;RCr{O; zHH_wKXb`H!bysc(GxHYO^imc88e^r+OvzALYII1-FCSQ6RP>=}^I+qRdqmpMFXb?< zu~A!`;gYkjp?@710#xm?8~lY5ArSIEJQeYu-U@d(O1~Dpa?fu@sc0)FN0XJ66H`yh z3>SoYnBfNCpmjgOcg!lf^S}Xjd^uEmR9dq07 z;-E(Je0W(#*th1BV1!r&HOLO8g@B_(oDB8kZO^@LxPsy5h@XXdI zI_p4a$z|l~IXR(0KpKa%zOP@5&19vXIYNuk)e3p1T%X6XFX=!fTRmyGC^btv@B3Av z5-IIEyP)q`9%pkVyGP#Pq2xSgFNag#X|Np>wD2_{z0F1^lS@;VU@N%98Pv7MpU1}D zAOx@Z;Z~NHvZu-F{aTKXl|*6OA)ljE^eWc0K+f0cJ+@}Z8_$|gu(T%!;nuKqQDbay z!6q~UBUZ<@yhVnUj-+hea)~+lM1sa3eYg^k4)GDY^5d}!9lNV_TcX-p$gRe$!vWCQ zAsPj*FPw>BE6TyUTnWi#+Gp@fdvNs*mc44qB|Nks4rsUtkM#A64nt4Id_L^k}04Q?R4M&ZWB_>|g46ge8ZYlcWjiFsqN$ZKx^ zg(lNEG$7@8O%RBKX*|jUR!-KK@Oz{Acffk}SEq$Fe(omDOkwcXR|zqG4PT+&Ak;fr zE_m-JmxC~S`5MGGhgkchwX{Gx~bR_IA>PFuF8W6+HqR*$jNAZveIhn}+Lq584zQ;*-}34>#-?B5%P%Cg)Lk^9Ur0CqiK zjXOFLDASy%5|n9&KhY-BPNq&D31PwiL&XIgpgB*^1zn;T*C;;^eKsw_R$Uh>K3lAh zisql*V8&~BjazFiN>9T6zNr7kqBj)FgYwQ=JOOIxjN{yGSYOGr+ z)^2r6dD(+-B2vG5bskSvZ4IC8Uftc_g~2ge`X0v$I^`3~$*c-p|Gp)!FySo*&iv7W_|F@YopH9pOQ&Vv*rHTnkEOH=c(wgj z#Vv~qWKPbV^T%t@^3CY?$X_C-a(Z4~ud>!<5nmpK-&;Edsta`sGx$9Mr0ZZdU`v>8 zYehi~7y)bTCxF`-23Ym+D$>%+8+TDm<^YHpW=0`o0h9ET-wCrIWfpdcc$#lFqq;O`^GaVFPAO0TuaupiQz&Woyz>#u;iFT)zR=Pp2it3qoT=0$DN(_ zzE=-FyXWF7IoMds7(aPRIR)DDhQf1J1T2S&f)bqN8SJ5X)ne#|tzGfPuGFJ}s0VQ{2Lio|dnP`!jnVe#@fFiT8ciH6$KIBO z*wm+0*_n*$#A{{Oh~X`Bf0_Z0I)AWC1Gz85%3n$ma^%)xa%Vm=rTEWi-p~WTk~Sji zR}sO*shkz$X81kMhhY1bwy4>)#rEpF{WTGsS*seNr%qv4nT5D`*02F{AYN8ydzBxSPm&9xPpu##+7VG7@*kO>> z{lf%kBl-#}a&Lu(q`bfDfMVf6PE^887LuLmt@zMQ z5EtL8&@fUgy@^zhh2Pem8Fqcw-FNZ#Zx6n2fWRP2OS%%z0G}z$ODX#N*PEo(^eyr{ ze{mj?A8o`xm5+8Bm$K;jiMOb82k>ZIqr#;h) zqU!W0s}AFf_*xD?UP{XS=(8`IdW(fSCcZ@*?xyyu-Y>aD1#FFt11*vdZEr;FaDR%c zulFh8Lfa^{JTkY{TR8f7!`|o1f^E(HKh$|fa$wCbCC59&G9b>X{s9#JJ-)Zg47k0F z4-uuJ{Ol_{!(jPHgd+UWircS016=CnXVQUrqSHV#Wj?iDIWIfu;>fo zBrRiN@~E&imKE~j<;}GdTQ1)gpVyS4BK?rUdOSuu&{AHOp`X8{d97Kn$rU4$o4tK; z$g{-F#|(V6`G}A-TYo)x?=w1^`7cC$nYig}7KNE|x%OTxujZWwTzOD!SL_tVtI~HK z1{E2q5fm(Cw~y~FJP>j|#*1UOd({q)+KoaM0tckKJjEAk>pE~jM!6}Ii@fGe@ zXw{g7j~wjz$Dum<#2S2t56b%H4xDYu4xLQP_-eU?A(ytp{mnhr)Y9AO*wiDEWVMqQ zwainCH-{ATV5`&MwOsKBgXQ7unLqe)zPmCUt_E-ld)-OJ9H7!x#VM#WcA|&gd+>Rh z>|7g}^jJyP*(9mx9Mf)&kM>!l9n^aJ{&YFE>oW!mwpoeftmIHPk&zs_ zAdOgL1hnth?$oFs4^N|>NgbcA4rC|p*7VLVm_tXMSKE0x#UyT6|I#kA?eG6`&kxh7 zxZ>QXgU#A?m^t$p)k5XHheUoVxR%?{gI?Zr75yBiy<-Ocolt62<7Jh;R1%Oz?hDq0 z;b%iZB~}B-kZk=WR)^DOkf}SaafgG?+%{_Usxxyx-)EAiv@o%)ll6n~m{hJUj>IKa zma*W26oSdo8LyO{cwE|=eFbvYd6MA)mAhDPS+AF3Xjmu{Kgd9(iesmsN>LLfq;R28IsgMeo}U%W+R9#By!n?j=Q36dn4GEyK1PKYhT74+Wx2=DO!D9Wu}6v!v4+#5#pPvLS=n4B=67fewmq#wrqnC+`XDzd zzS}?td7PtlEL9kbcxSZjDRpcraJX9FqrKK$&@;iwaEj454n5W~7G<&PUkVqEP!lsV zsXndWG)OG7ZLlC4U)!1$IGEZ*VX*1tUQQC((`mL->qFYecq;i=`N@Q+G)Y^E?DEYA zAD-J7>2#0dpX)>T$Lo`y8+7v{CAXTaY?Hms;ab=T3!#D5*eN!8C7vbWDV9K@(Z%Nm z@P+{DXf(^g+~-SgqxZ)xrwgsRYlK)|+CFpcp&9>*Co%fm-?i3N9n4=Wile!jN^g-P z_DIQ$txOoCaZ}tW>L#S*QMPMCw;T3ow)z(|OG%#fLcsWJ!1y!DeGRZWy|swh zyKI+MneOKpD?B_q9Th^kPi(4wC$gPNt=jtCYVeAJv7*S`E9FX_X7rv9AA=g=ZgT1| zBk*fQv|uZF@k`vQmH%fS$P+|b$|i*brL|KMVzc%kw~o1;z6odd*7NhpT%a#(kW*!Q zeyaTT7$TF(ILlPK44(r2Ax)|^i?j+|{-L9k*5!cc;Pg;l!GjVwcXlqK&V@ycEx|&8 z{czpE$65GyLRq2K3%9o8go-vd=em~sH;8NJL+|fdtTX{-7<>-Cf4)Y{&vM0WLbb-Z z)UnE!LNo#xF1E))&oWW0C=-ntEbTrp%|V_FhqKd8)mO+A>J=#}M*MrtIKSx(Jg?DY z9qYtHO9Himu2nG@Y7X0&QtDV^N_kr|Y*$e47Q^`kOT7&w9bTF#(~Y5X!VLM| zs5+Kczl>OKo)zO%MQOTcXQyuNwW_B!>KRR8=4P^;TK;BZVuPw8IwYNxg0KMZ=jh!F0ST8$1puY2Es>(?Kh@s;4^!7a zcWkuXnocZOr%e<^+p{V!aQ)@jc+GzA!*`hjXey6&(cd0b)jcj9^TK*(PS1kdlh3$M+#LrtR$BhQ8{5Y5{P?Q?hIH=sirk zNuc^A&BrYTNP|Z|^`8SdE#rS<=7-rR75=F$JMgu?MW+c~q7G1ZRHj*2R;k_8BhTY;X(sJ(FVOGfol=)^xz+J+$?}POuj&0}`7B4v zOUkV$wa<$-&`rjRYJH2!>$*rJUr`3$$(wV5X4e1Ko*T6Or#*L6Isuk%^qS z^Ll=7`$Y3g_jcQcZ(-b{3l0#3|p%-xs6>Ix|w)#N>O-xF_@Mp=))HTi?x66rnXf2X$PVMCl)5DNisx zBWMlv%GO6AC=`pdtI3UyWoJddH!}uy(*{y;@OOrKnkvRDXkobY@yidu&0FpQbqXhY zTH!m(&tow-r={pjA2~e((D<6O3B1Nnt{#pE(>q#kpINL#4Gv(cl-OHzM%{Ln2h%tU;MOFT2Ps-Lr zHYx{q3!SBrDL9)_hS(dZ%0jk_lAZ@q>T_|8M#YVZ-43X;2yy8vSCTwcb_FY>qAI7_ z;6XKeNl8hm+Z2(kg6yFUpfq#-I0W!Af&MrZ7nc~g+EN?~3kwlPzV7>mtK@2o%u00F zr4}b^EXDjhp6!}5-EMXsa9BJ%(=FHAT3ZGB^7?gDWW;259F2A)1nr^^l@HvKj3G!~ z>r!tm&jT|T*b!^czz#b1O`;+u%0X14}vb(KoQE7=w!G_tJ6BmmkM~j><)?1 z@u{rCanRMZppz`7M@RYEHA~8sTh17?R?W3I!uy!kcguT%_glBz`NdX}>=f)8;e%0< zm{VDmIHzSUtJ8>C zkZ8xxLThPH+h*cYh%3I85F&2tL zP-~$lUSW&d&!5u_fur?@tC|PIvc|_m^7y3NbGP?I?D?O)IL#Y(#MJ>kE*Lo&aKdH#mxHNoQ~T%+RIO zf3d@L>-qQ$SeXqzbbAeRHGmf7C^W@TS@t{3O8b)hW`{>q# z<*{=nynH>_hF6nf{=am~00YBp?Jc@ISt!ZJqvCg1g)g6G)gHfX-9YY=nz2!TiAVue-9I$ z0#!Jer`Gv0c${69vvoOs+1OsH__fCJfYYT>pCcg7{$-|*?8PCfO+l&1#=!1n&u5|l z5|m@D;45n}{>zN#i?6JTuigm>zrG>R^4p~DFkB*CbZFyKtghje- zA0+q1~lT7Lt~mC9)idait$bC*^ZUBoM#^(J13 zYN6u$DHqsuj~P`er!-nvmrGqDrlX_2Abw7{=R7ZZsO5tm7x*(B%elu}VI+a$|C>oC z>Nu{wl%l@J8h25IrVfBmi`k+xd}1U`<<3PX^2mt zmhj&dh`XN0TktH5TiQ8G{T3dr0*;b~Dj<`yCvOBL;=Ku!#(8c(s)<gY!b5r2TDeR4L5i_eSDl7H@m*jF6n? zW&yA)J!W3cHr3=>SL+@(N*~8)xAp#Qo3s>a?k?GowBwXtB3)hV+r5)WAbRCFN|-zr zn|42!9Hr)0ETRdGjDDE)c?_OxTIe4qbf=2s*gexiu-_d0n2XCT#a+WIi%IsAHMF(OlehlP`_-mdEqQRsPpFgzq!IWif=@|yhh6d+fP zcDuU!cPwwdF&aN8+uCCpsMOSW;|-!5|Bb)YaS*LUvvGorjZJ2VL$R>)Ll~B~V3L!| zjwQ(`3vgB|GL*E5MPv)cabOZK8H}>1I?;DbBDJBHYU_u?-PoYjH+@Q5T(LP@5>>Jo z)9PwJn=Kap8H4Q*1qvh*JSOHZdFs=SE*gSBR(u<7$HfTru?fe3U9O1Dot$=E+c_Cu znm;M=hf>vSk7xRxs{x6EbH}G$5Gb= z_MiE2l{dgcZS@2C!HM8d42nh9|11YJV9SQVuuMAgVP=9l8CGz;wLtNf-yYe&o;*1B z!vv3evzY(T<`BgWQ!G`@WCLEK2qi$?6B?NRP2TrYn-)n-X#;)H-nP-0me_yv6;e2` z&LrgMF%Yy2ktNUhjN3J;slesN87ilXjJkFjfa~E`3Q-$FB_%xiVaCSw%MI!i=4+#h z*ZWumMZ_%gXsbxXT-9=VElUl!-C*KN!&iS2FN@M5!8u|F>;O>cBv*sI9L2&bj|9s_ z)gkCotaU*LuSZhfx7@bgD@G8ry)poWVDQ=lDl3YvA`haIZqH+S-hop#_Qv{_fk7<0 z<~;o~a}b_Yvi`Uj0l441Efi5y1QlAtu-^|xu?XJhfPy@rwF)Pg{NXcnT|>RVB!>Ob z#4%a}J8}Occy&)uDt3Wy6#*q*7AtX__TOrKDJ?v0CaMeC*+eDKWC41F|Jktn4vr0t z-E7XbqdUM-27;@_{8ggKX`!#n=FZC8>9>_{+fw@v$uRCuhwbaX4E^{(v&86f>$LK1 zjxq0r7s|?)l}ik_LK_%!7}Z~f-j;Z&^wR6Y{$jF4Gp%>>RNYjM9(k0-Zr%Fk{xM>G zy}xd&cLmc!#xRMExyfLWLF!$guTTMfdFJ_vp5e?^V^0~tH!@Mqzi#z%$Oi$RRujcSd*h<&dE`3 z$diW(>I?z}1&5(UdO|TWM4pb*42+|At;ZhQnk|$FPgAp(`U}GbFCX!9XBZOVNl}Aa zk4Nu*Ebb+IY9PmXI=i!g47}?5`nkMrFqja8l?;~RFx|;$A$Ip*dQ_@}QQ4&sXvPW3 z^+`XF*Ec#)mGQprL57;LaG?1)Php8+9mZ~C5BQyG-;~UyS=5gN9Q+b!xbljU%r zvCPH46%1m9V6`$Lp5!}<*%ddJlrP3+Gk+E@u5N5KgYBDLp_?df%I-`cW|6BuNrJ%a zIBQlX*j*%~uYthr;r`mwK4=p&1060w|2M1nKgc65k$m~bN1XM(_*c1G5YyBN-lbd; z6FgSB36$aLR9Uiq3Lmo>oW?NBT*0inwM1LB&5GelCj~j<Ju^D#WKv)ya(H z#p2g!=2U9pEH;EzhZ_r@+d)8vh>Ld?CG|Fmji(@DfB%}N%b@daXRyU$59~LA3JrQ} z=;=la!mP>u^*F&ph7bZ@f_D`b!bp|mUc*Bqo zBVU{GS_N%B`v-uX8<`1*4YNwT-9^u!Om|JtvOYfbXK$$Hr;@1Lm-dr1j>_Km>?kWnzyJMhqCrD- z)^GQxc^PH0%+aD$2-&7Roap#~qDUOG^Yd(RojrTzFi2#cDx~E7-Vjwn`ORtYSy1B- zt6iT(VPO{GjKk>swIAAw)+clQg>yF}41%@=#U|(`-i|CDtxSetal4Tks;~Mwq~T`v zAiuQ4$lb`tqVUp(wji<1Tl=x<3)yYv%Zs27r-vY!7B8sg5ShE(^?1}bx&)8C$q2N{ z?{N&nWJL&aHK7c~u+!7Ak5Y7eUskr;wG*j9!QH&j(3ekQCz_GeIMptiwQe(lY?Io? zeTyoN8xnmN$TjMa!vH6mb5?6?pus$21cwHKW2VV$eS_kkq7D~=A{x$0Mk8bqUT0%d zg?88kz0N#R5GpyYyRJ@mgH1`U~Fb?>5JlzoOdep_R!k73EKB( z5j|Z+qTcw^-OS8#?{--OP@j6`yL!8C=uS>yUCQf*1~Z+Eos>=kKE6o#ZebqM^>7ev zQg94Lbnj9?Fj7aNRz`-f_UVvgPgX*x9LbW;o~-IpC=o;J0`e`{?#9UCgudZMy<}UE zSI+G%DA}4QjnBXhEX|Z(3}2##2^@NQ?Y7&NLUibkY~v(&_(=1F1h#ZA=|_4k)VCh! zuMPS5db^M1q1*-wXY*m1cLW;K!*x_f7WHDJXS3mMD41YF`rxv14LtNamHG3|d3`mCFR#rYigu8X=ZuaER%dHuxaNfR+&q z*+WQ+f-;=^bKPIUAHn?<_h<_)F+j1-Duib~PoHMAWXnuMC_Guq_gCL|&Vv9!8xnuc zna~k?*xo$e0{KmV9nNg1N`vLx-L;eEA2x2m_6r^#fFi|ap81H(*amWLSB!@F`k1>` z)x9&8t;%4TwKvt-KW2Ajt+YqVrFqV|Y87Q&9w|`P^E)+bOc6Ex0#Oc(r5VZZ-cKyc zJiFz)-(0Cz=d!Ja%Zp{NJ^Ao9Q_@qzg0s`n{kmIj!E>tuyktWSbbcrs+1K3_`ls+9 z-ecGoU9K1nY5v8kP>(b6%S~}3OiWCg+%M8J3aRfxhn*#psvIgY=z4F(TGm*H6L2N9|9CqmgIAi0RVwCnw ze}1mI)&b(ywrn^#R0acO6P(6C@ete$K6&brn2_R#YdbgY<@s&<+^A=Gb%a|81N&_6 zi8N6`NmV3#WA?4t@-Po*u+OF`PHDCa7r$Yd#y4RE_h3q^D4ZZqphzAc)papSl?O69 zJGn_44gQsIGVMtiMY6-DqR|@-5rTSn$ZarAPA~6fT1sZ{V=|GaTJeP)O{tmQRf;D* zt=oI1zmBq(`rJWrUVt&dyiCUFx?~aXPjLuH$Mo`>fJD4vReE;o1KURQ3w&0(sk0|{ z2ey=WM_8o0V_%bwRlOO7WXaR!Qxz&G8}PolV34;2a$J{5)k1Uaic_6xoch_aZ|B@r z&3vNuhp@g(zAf>?6SDOX&x`pY9?uw1D)Uw{wp0_v@$3(E0gzncUrCg5RNe%C`iEfu z*PrPe=i;4XRH#S(B8jB*22VGqa^MP9dK;PKZ#rV&PmEV-IU-3j4EqM7;?jR~R-ng{ zI#Ctd9==9=x*hz7`fyG!(_86Tay-Kw`*+Jsr%z{0hq5?N;v*A_oOgCCo|(=s=9ao` z_&XsJb^vIJLE9JMN3s_!W%k`AUbT9q&{F8Zy{gVxRbsh1KF%QHG~Q*48uaI%DsX)| zOFt!wW6Mn+%aIJNFAVw@i}7oK!gBkCsLgb}l)j%y()Y|vS+rg1;`;p{riTwzD{Uu> z2-!MSP;q@rfZlNX#byH2MO1xD1q|cy^|l$v;yN7@09X4mOq%<2HJ55J8et)qePiRh zapthN+(@2Uq=MYhe21y2IiV+*EBj%j+Ki$qM%= z-SDwNejSX6AzPc$?pLxLn<|(qEp4cBr2vaTZJh5OzJWuXoa&LXud-^v^Vk^!nHKH- z;>2=~;`cq>yZVY0gw5X!wyoATI{fI^(&T>`+}iF^Kd|Gp$a%hQH|j866IlV3XV7)F zu^huZ^u`q+JFQ>oW^Cc^T59%KhClmN!>jupTLwEcSy;%%n&xQ^y4+2`ayEFUJu##8Jlr#y;j+8xv6JU$WO(Z_zO)nfMQ)Cb+q+tJ=KohG>?D*8;C+$pRC zd-R4li*^>3eI}t(MI+3epNtjJo9ZB`al}o6%hL>QRY7OH+x59n6%7rVldv5NI_UV{ zWNn)gS%bIB)$d+|KfW!Y?BVf^zFuq!v2;;|LiMe!FSY(BX+sV&MehSh>~U^L(^cos zOKnY?o6BEA`gyZyiSA$)&{3dkR`T?FLuhignF!vqj~y_HBMt_#XpzYmsvPUhnc+8{ zu&n-AFxjep5jWJHeF=6mK$$EjV%`dLZ26%xJ&26{wh|_6@cgnm7>T`f1IPXK&kGnB|OShMUWn?Kg^t%pw$bt@eiK$!g#G*nmfB zlzxr7eQ&ZIR#*Co^CrRVkM>($1IOMY)GlnUS3Dgk+vZUa`H9@-`H5@fkeF$aOJ3|ziRfk&8F~4**QY2SJzo&73qXK`<%R# z|6xuPpqur#Bjb0PKp*ncZ!-Ox^-^xu_C-J3WWIOu&bnKPHfl)2u$q?JWOIrg@p`p_ zS#%Yx&B)4+ectE|FI#@u1J6H)>VJwI1*%EIQYp@@OoKZv`9SK?H|z3xPbk@p{AYM< zaDsg1VUDo%ryXAn?ZZEMR`lI+|E-Ncui{=>zqpHc*48I=IDdXw83eCo$>8f|6Om20 z+m$*@KyfSaW7~V2lwAr0@!#xhtJQ6cV6Uub@@pOk;vicE8W9zpJSx-lfIzb(Z&>(m zTvJy9MDG}m zwp&m8!MO}lpPl|8Jw&ScRkCd71rJl9{8@h?T{@VS_+>c{Tf5oKVNs@VW{Xy2vl_3d zOUe(U6*SpxN4}_fHqcIr&(-bEv}x@jzGHK?1todrz2QO>dO^Wt`2$9GR^}@Wq!&~$ zna?ju!0#SC`(*yYD+)sVzrEP`iAEp0&i0h`_P>4H7XQt#*%#e9X27d6kcj!R-jg;M z5fq)%H&^x4t7F*R9~|o)`$d}t@x^zP1Fl+opA~=bY4BF#sL8MrI5y&mq!aJG5_$Ci zw4JI_IJvX7%Bo zWMXQ#v>yrRQ!S^ZYVcu&t^oD^)C-UWu5VqXtrrEz1tO}2Cklz*QC zgcHO=E`3fbCJP5W#O~KpzuMvXcN6%}@*gz&6XN1b!skv29t&5;JTikG@cDT?PI^mE z!I?@vN|AFx{Wlw;$)qsAbn!9Xzjxe_Omi?3sGH*-INgzt>n4$blAU5pJWExd$hm z?V(=mIY$JUqmhP#!kfI8_A@{SvdhZ?$1>+jPeyY`C54v9!`CUn^15PjUiW|>da)_w z(a6{Qnu+t~cC!FvbYKHKv~gJvKcNlKu5xYH6g5|YSJ4&W;c46VB=hHpn^y+*mL3o9 z*v5+v#rd3@2;A>`uewZ1)}jyZZ;e}8?D?9Xz%r^9Z_NeJ&&sX^X1SM+ONblBU(@N6 zl9C>myB~tWU91GEw;RIQi;e>uu8+La;HSe_S*?zTn{SPFul%lMN73*@VJ2kYLB=#8R%o3FPr(GA;Uu9y_5u}(>BR_;Rd^E?T> z`Dok8q}Jr|Q9-fE&2jlOE*6Z}=_pEZdYN)qmV`PeD5%_J*WUH6PR)3Y;@VC4qi1eB z*k%-l<6>u5S6p{Y4X%Gyu?1!*bmK~7=X1UWq2k|>*QvtaYDfR_)=hvI! z&BCWX?zLyGj?Q!~@Tk`SO-XO?a-1YU(H&9wR`-UCK9q2|{Y2>TaHg?iVFiJ}^Ba*qODm-ZMeujS!e)j7w5*Liu^=WNx--jcnf<;v<_ zW>R1+?$>g8nnhyip;>tz0h`K1t85eEzSwy;4td9;$w^3i~p zUt5FjprFO}l8BLn^IAQQNgJ3;TH1TtTL=5)$O5R?1Xrb>9#V?N;~c~}4;p+ubBl?p zcF9R+#&4_wu^dZ2RD1Ta99g@DR5fVTkCul!J|bcY=*rRlP-ANE{h1~-YS88)jQJZk zUm|FyMtGZjnM1c}LRG4WEY|Y6GOiRhIE^dIF`}7M*Wl7aK!GbJ)5ChWH!Ari8FGuC zM)JTQHtwRSVX`(;JMRe5peyVY2N}FLPl-L5FN@XS#`Wy6N3ZWhvF10xKVfu|?vvU+ ziusa&|iVFFDFH0q0h!$UGLp&T6(^=eb46;aoNSide`FW~-Yn0N&TLQPj(El06+W zAs@IF0MP<1u}MHkEMgiZb59SV(wT{x1?l3~LvBZ`rM0u}LRaHVh?x$7)em^9&_Dc0 zbGCUKi_~x99v*wr#tQ93c4wNui%6jJFB6wx^_`V)JpImZc|_?P%~nA)Q)rP}A)xm7 z0k!(=HUOmI3)OU?(I{Y`#sPrtBhw~%aZ@KZ`(nr8%Z7uAf%?Z(u$(7-1CK}4 z2^Rptf!3ka*+fOj?*W_UahV^C_agi$kKZkocyU*2q#bRUT}DDZjmr6ZTAodc>f;&w z+AYadIKk-MQOV(63e40|i(~&_tGqZ`YF91E#Hevp2`S zyQ}5dc~rI&C_euv@LC|Tm}2{UQNXZ;JiEZ%5b%*9j#cp!Zh1paG}hvbK0omCNiW>d zFOiPwlQ8~(mSXk>6+J}*%mmcTS0B@`!w41)Wr47F8I?A|n%?Lb zHV^?0y8HcAHYp1Tb{OyMQp3caUDgQ12s~*sFtt3UCi5P!A6{+iS!|p$nMkgSA#Z%^ zaHGw$S5m;!b)hab-hXR0+ZY6}l8C{}oWX{`Au|N&;XY6y6HY{D08PLbRCk0Pvt_j= zaR`JD;f}v~-oH;dP}NG*<69FZz8Y4sFxt$Yyd(0(QHCvT#VtVdXwcH->k;lbj0-esVlwH-K~bRw)hOs)}sO zL76z#rb0n_bxY5}9(=WPL2tKT;o^-YyI82Y9@Svoq5`42!43seq07^KtSWFe5kTdgursyd=fRvB=2y*Xf0CAd{E zyWCHIsS;0R4}rWlJ?V$B@1*PfhT||#%3!%k%cQO2)7^lEX01|@lre)$UPkt((atcz z?|YM(!HGwZMTNu7ALg`@YWCVlptP@e)XOacmh#I!4VtrlT6oQu8>%zZXFULTx6wf9 z4>Y*#UInd+Oe|1XF6rmynCV#HSNTMrRRmGB_Ld>3e}jgpmnZ8|SlI=_GbZsZ6fLvD zcyaL&;f0~~RsWACn&GCKAMC2v=rAlLEtkzGh(5UfS3uACQN4>AtNEXYx5EP9HQT%f z!OJzquc6v*gw|t*ou5KMUuPO!LmD5t+3U8l-8W)6b9POj(kQ)X#D-hOD>{pY*Ffle zM?Vb+KCiJTl~^A_=+2m63krw4dMzj$`^w)lojSmEUm&*%rhCb~f>ElaxhZR#Tqi3i z(FS>PB}l&IO^vR1R;BrxT-txM1^iIAs-hl|&A++?stxMSMo%gkD8R6w9Enl5K3-Ot@-^o|yDRj(pfj z@a(6RO*|$jX1%<;&k7V@iDeJqYcDm>KKzhoqz20F;syp}QX*Gzk;l&~)o2+SM5X3) zn>!G-4;-|4l)pHQyuNI#T}@mSg8p27JYADRG+Gn)*>qX+NI^O9BeOAdJ6NI4=ihB9 z8)F4$X_7*br|r1l_vax0b(r5Bn5nVNQfOEG4-Zx2Wa_Kui?~zY-lcJTj+n^P5iv8# z+RK|x^WaxTq$nD8;Fo?SOn51H#UFAlK7sBY7UB8BhR z{6Sc(M0<9NI8?2QnCY}Tq097}d!rI_Lb%$y4riWzE+J7<7g@7h8#GGJ3NbhlccrMN z4YX`ee@rAijx1>bk(YnNqkRRTj>I7iUqwRTP_W=I?>Lt2=y1DHkq~B=;0_+P*|Fe%`eHb!2bShNf${m^z8GQ3}O8(DE2FA2uLsiH)+DE~^C zpHdVt%nrOrf(;q&(*N#PQ1X}Yb7EzW5`4Qzw`R52Ra}(uNJE8VBbl`B?FLNZC#R86 zu3R%rO7%P%YUFpCKWYm@KGjk{^GiQCFj~UZ@b{CHh zY;+FfQxE4Q?;blp)NS6O3+Y)<%cSP#@PPfcF{e({S+4RkmqrIbx`2zK=6;F`A#c!Uj<9_xh){nW>=Nm{hh zVk6K>a5fh9`Ci?Hegkv*UGIEgXg?>}BgK@pX&Rc;WLHC4hDhvW>f6R>T6=8ziUJT# z-r9W2)A^z`;rJtJMGO}Wsbaw_ey_Kuw^lqY z#*Ea9yw`knmaw=^yC=XkY;$sY5q)}*T>hQ?ar4dk1&iESxIShUtR7VB1HcavS+jhv zewC|}SX}?$LHt-M;=V(iW zF%UP`Z?5VLI-Kg$z|;4T49oeGZz?j&Ipxh+ ze}#~ed+9o4B5Ao#u6WSaLbUwZdUuPfF4?!F~#+hgu~MC;FhOJQBm6I?ABM%@5Wxy`y9^K^!q|1X6m(g zk%NTOm4ptX^mRJlYAyQVHLfEf$XdehJjz`LUhTpa`pwv16E-L>`)}iA+uE71wy=i` z3*7P22g_mdLdabsC^=MwJIOWQ?a^^>M2KVpnZVJo`u9D7k8da_Dq0(`(oJ|a1vsvNW#JVi-%-6IqfwygmI@*>%Xwt< zHN|@k1)k#$y|j2B@?Mmh6l#Q&n`Nt_6SmXfV()`GqZn;Yy@O4{S2NeaDYxeP&GiV9DG8BTX?6)vYcW|;V&Fpp2UsLp?=R1CIjg&=imnYHSc>Ky9Q&ZN2LNfX;L@Y6aWaolb=9}c zdQ_HE#g{F);B?KUk*`{%ce|};KdytiM`LPzHC5@7D*tg)ufTXu+NL+OWE%@VYP2S7 z^wLNkO)FW>Z4bIldP{k@`4!uwY8x}%M3{o}cYG#`=|^hJ$#$SE`&*IuhUf7Se|!3y zb?T!Br%!h8*ID1Nsd9N-wwUgftqE5N*)0zL7C2uqAa8VYa`8j6hn}GOaJI)e*L1{~ z=s5<2=KicU_|`GfAhvc4e3a?KV9pm&TO@$)-VnE6VcP322{(Q>H&qck>EvqDsPI%; z5T8JT5B$p<+t$>3Hphxmo}my^3`xB^igCMDj$+ylftnX@b*gC&WBn32BI%g;hjt9dO?_I3PAbxR}RkExY zVv}m?;oatx*^+zsV|!39lSA?Dwr8-*SU2~CK>8*&P>wL9!o|Dde*3dqJ zKZc(7y`Pcsr~cEP3uOzasi?X>fvs*P-Fo4{X!(iZ*Otnm;i6L}_|=Udw<}c5{md-4 z=^gLRpHUf85FXc{;fW#MDrhY^Qb!}w*-EpdrSCa4ZX}7R=tH`a_q0-V^EX zpB>Yn;?!Tg+Qk_80}niU6<{<5h%MgJR&cL%Gu%{MFE7nB-$3-MEhT6B)3$|lU+ymI zp#E4zIrQI?qQr$rD=hqwZy3PnDg#-pkGPlP}iRr{@4}ZVt6PM=-2h!_vFK_Q|@un z6g+F|(aSgMNV0*60j8a+G zMFc08W<=cx=T?YBvzkkS>fNoc7gPKBRhQbbq6KGc^wwTR)Z`yQW1Q9L@VvR+)IFy= z>Kv5~>{Tno9IJ}-tSHGe7~}1uepSm`14ZVBk8dp(=%Z7;6d7A?EDxKHS}vtB^q-Qq z3HFHeVnW+Odetw_?DiykV2TjeKH0R#UaprQ;z)~BiAhe<#%=;WUhlM&1!c_b6#y1) ztdN^-4+WMGtFORGT1qD3A{42~cAKw8kD4KgbJ7>X5_dtasBFD@1$S!bR>+Js#cofK zc$g|{R;frcR?rPQ_Uky%sRUyB>dJs<;ov)O_}@6Pafl$$i)o{ow}u(ipJGo zA?bxfrSPp$merVOvzjj4tC0A*sbS59SLES8NOzY4%s+MA}Mqr-Ox}!$E;Y8>2jvaf2)sv+BW4 zb`m@|rGbfYm#Prmy39-u_o|s@S8J*`X%zng?YdtFA5M=Ij)fDXD8>QSr5`BfV-kTJ z!(yKL_uChMpou}oV0uOpru$<6f(E`QUfmc`7-?X%>mo9CFJw?ime5RPqOam|5OrMwm#)9yX|R5>)?qjdu}5EWMPl9Z-Fr*XIC#`{jA z78SXU9CJ1O%d$H`G)y$)viaJdk0R1<77qO0#jYZHB;4!damagJcqOpf6~5zjO`cFZ z?_nu|)oUreVV)}T0i$E!la2N@2ekLl1ns!`3=UHyv-P7%UVur`TQjnnWp*VV+Ci)V zV@?>_L8l5a2BMoAOy$iV`{Hk~59YwPi_O*inOYJvREl#70wP&rk(jE#b>so^2KLnk z{GU*uV8ZK@Gs5u;c2#8;xcAJl*(xE~QE^EbQvtjh-rB8mmSQ4KMq%V1Y$F4}H)fZeAN1sV`C>$a1ehIYl6#2IL_S&RNuRM^QsKQ9v^|@0Pun3~IBqbk)Rd@- z)=gT!(>k6O8X{no2-M4+vTAG38;Qr`-%~yOdMQL(P@8g)0>#avfd6pqrzs6R#~)8& zEhA9H%z!i3064y5Wu6xJc7um*!K(K5^go44lgP9om?;A zd!H(<7-ZoilK1(F_HX3xA4S-k@5#@rGC&;D(DZIrdMgmRXnQv~5e^j%mjfQ~8`Q8g z`jVFO$k(}5D`NQ;kz6i_Z~F$VY1Q)Igv)yArekXseB$7KI%soqJLuX@%X8-Hbl_1j zvt068mzb@RzcC1hoVFf*-z>sC`iuCF$a(kIyYQQW_;9{Ibt+)%gOI7{$KEC4!OXRm zGf7ubKCzZH`5l)eBob_oj*d>NBu;-2X0I=|Me}g*))Q4G!Vrdtkq>p(pzs}OnV8fs z%^XO*08;~bFkT+YBg}7PRhRMWMIWNH3Q}C1Xk_D_(7 zh=}ae<@rF9cQXDBAdRo#V%W4$OzkM%t4K?Er6<6z;N9Qd7m^CLcWrJBIltj#t$fA^ z`|O}SJ0z++t?Jn8`fOBh#iJ3r1>_9L%=7Vtjd#9%{iw@R*j3F*u>LjhHh2GciU5VL zetVeXt+j5r+^#FKwD%+Yj2;OK@y=i#Yg?n4C3QeJXuY-#vcL1?p?a|B+3zb0Lj z2oOl6%wddw8D9MAwSu}V_E6WG_C5op7jvaqfzN5=97YX{KR5h0#Fh^b(*oez?VtYB z#exF?v~mUOKS(_2|B8}7L-=nbQ>%|0nbNE%@L#Yz>RV|qCB45uCBrG?uDuU%dhrEc zqkRS5P#3S*U{U2V0 z4PrDxu~R!2A}B0!&&b522MLDa<$HpcK!t|3)7G32Ox=XkDL})M`#pze5)#bDHebyA ze}M}A4rYWEp@JtGA;F4)`7^jTg2RDJ9_ZOuSXd}=*30}K-U%BbLRL@=Tmw2(5r$=Z zZmgpv9!_OpO!SlU!HiH_Fd^Ao^uI01pRb)UU{JIXvUomH`WVvmG9PP7BTm$DJtQS0 zMy5;q2M1$|v}&ZJq=I9Z^mL=5q7bso*MGpie5(jBI6)F{eJM@N#3=1XClX*Rl1TVv2MvjdwzZWkJa_x8~a~3o`J_B|91J!;ejlg83LE$qmaw`G)Y|C zemsIo1Ph#)47kjvNY{)YgNGStI;wN5LOhIrj`_dcsusNzQ9P8s-K`QqweafOILQ(N zae?R009uI&IR3(IDv|CXBNXT_g3!L$hB7WQNe=5@DGrhkio9IpUQEzk!3i#XG(wpg z>p)?J!&|pDLKidanprm;k|mn5*srteDH{>SwlLZv3c@Gc}GoV%wIFFwHuj;ohI!OhTyZ*4)lBU~ljV4?76%Hamp_!r{`p*7W?fpyiS z-@&?MAcd)9yT3nx!3U2H(9Pg@dFZq8kXfy(F%{F_`V4dEpDlx@y~o_LkkOA6)pl-{%^z8exBJ zMG=6Lvwcq<+Q6OIo@k*AhnZHl^&igS0^H0dTy6Cu+R$&ZLOVPG)dq!a7W8~FA)`(> z@xtxjmFR_d-dqGNT0q2LU z9X(odzv_}Gp}XqTBup-VWi@%hRQ$#Du7~%J!dI8JzBXy^xO!d1?_|yLW7G2t5 zZo`V?-Cc6Ikf^_IUA4~rALawN9GbE_EmHhT^5sHAuv5{{q2d~3GTPWr(# zrnR=J*AngO9p}j}iTjmS@)fFw(jTpibjeikhJf_3kH|OI($o2(QF`QFTy} zYbTK&*oK8tzkbbiglN_N@+lC67$pPK557&f34Lg16fDyte7Z862%x=!3T1{Cr?3U& zVJ34IO7Qf*y~E$HEEHgyC=X=ny}iBgzu(CC>O#|W3xu6cg_x!!h2r@H2jSx9I0gS~ zqj+gT1r;%w*-XeXn7e6Pm|2n6arW?@MJ-x_ZyS07hZ6bv(2JLW!DDfNQ>1+($EZiW7>KZ}|#csil{5_4(F{ZTdVfPVeg#u~yoG(mv*uWv@dl@ej|-5&`~D zm{57Y`X9tO7A|-NWCSjGFkd(eE^y!}w9BZ6EMAs1Zx|s|T}8_fR1Sg&53w978*p)% zv!!1;JAx2oAC0iZobiM~cVp&0)bq|k-ZCja$7 z-}S}vD?x~|R|#-I5@NuRmnBLaO5H2b%$~J5BKa6 z0xL(LD6!@J+NTE0*iVdKgfHzrAOb-J0VqtopfKXFq^3pE|1=aX;Mt4|2eKp?R3BK- zHN#giYVJ1wgM`4s^^q{bQ$){qk(>!hTZ8EN{Nnudk$^Lm2P=35%j7Cu<$tAo(FWrh zfd@>rHK^Z-xt9yQOouNko^&oabz__<2PW5`;OyWy|DC{>_o);nkP(nlwkoH8ai@uj zk!=abE-Wm(qC>)b^}o06^KV+9Ud8HkzRz7_hwbehvLWC757zK6(N;;-Rio`6x`6ig z!f@z^I(%^!B+@f6Y@lF`>$UDE88} zMU#eL!OpK8T(Et8`uu%klK>89-eiAtoj!(_il}&FFewRAYR5 zhRq_IQ%k`lZIx52!RCp< z?2&ZAUs*!5&=jZbbsOvU(FXb)ASU@;){~O%?fp=u#GB&$7+}A+L%8vk(5BiA*%e?r z*b;nq+|0|6xg51ttKR{`y_+e-y4I(7wpUQHZz&tkEE#9G0#7Z@k+j~;M?bCW-jw|L zjI6h>FW7wH+d!Xp_dv-nlBWP%o&36YcQgJGcH(1B!eZ)T#D+R)##j~;!B%%c=R*z5 z=5{zH@3$VC_mA8&5|MNG-{!+Jv;N)2vR{O;-$Ffq{>JLl*!Zq)eW=0s<^=t0tiR-U zB8PXs_Y;Vk)a#;*WG1}+PE%4|emd`Hp-$QB-m2{JaIryc-f?$9gLJ;eVxQY&c2>j3 zrP`8@nO!?ywTM{LgN!@@P*CquWpS$1N6&7OExinY*7cB(W2bsn&L~#v(ns^34hn&_q z{8KhW7xI6k09vY`feX{cU(oqVV5d$wa`kdbSmt#$e{Ti&b4} zMa|}q6Rzxb<>7j2h#Z}g!VnbHR`SYg&30|y$V7JBOLyj?@YMA?9W}K$1_nl<&}CiR zTj=ng54Q{gYlv~j3cCS_AvgL48lO6kDM@u7$QTPwF{zT5ZI7ltgHn0B4zt3)XExmo z5`vzMa6vO_G*Hdim|W;41t7eA(4d$lJPuBS=3t>{^*kPfLWx|n7To$}&u&dfVTGH| z_AGoH?%|tJuK6A$e8fUn=Buru?|VWgl?4gjn&ZSH_+Bg^Wn=2kDdr3v?BXT94~)Zyq%qBNnDXcrT(Hkpl^NI;NJhd@XzXdtztkwfhx6)T)-QkhmQeMgC6Y zOIMFcCpN>!>n}u8HEEv(GHb332G_UKyvb`8y>dPu*_VbPj{7?u%&g*J_xW=md`y@1 z+pk%6<@{{}FyBml@FhHZYd^u^dsmS-%zrP;*u24NHeT(wWk1M~VGMLvP-QCKE@?bV zyx={{1-l1Gm!Thcs!~KlyvD71{J{%wbv-0UoYE;LE7Z~iT_)(xK-*~rmBcXZ^75`? zUy<;$$3=*8MNTRRI{jQmzcMc(?{6e?9}p4aW;eBcVO#4)-R!BX>6T60ukvfG6p2CB zC-rh^e0SOzok+NcbRbiL%>QfW1<=-_dh z73at+nELUn9=~waIK?>={Zq%SR{iIMR7TS#QU%zbGPzDZwjU3trlf@vWM{qZc1^g~ zLx0vE`YckXd3;K~umixw_D`UvXmD}j98mhQa0^yndbo(YaFR%pSfi=Q$R2C=90___ zT}uQmTP&tmQz@(6+P8a*T_1rX8bh)NL4s0&{e$z$s<`HvyznkipclT~s+UmO^=2HK zjM6_5ft%N853avWKDzz2!r`b+dPu#Y=!;1>lxWq8iE4{g3bGq-y9>(QWFN6mYD!v? zCNI!|dLp1%4Y3o@&CdRcdwXA~F=#*rU$g#m-aEEU8be|(12Vg%TU_&1xJp5Q>_z=# za?G09w)GCGn@k6e@zYQ;4I=J9^x0-VA+_g#64L{&j)#VV?$!`U^hB%r!r65%kNN^^ zn!X(13W4-}=vd*}OfWGX-;!lDTU!@;EcC-ZbX{&SNp+P=^?ro*bX=<2{!NpUOi!o! zK%SGr&xOWB)N*4`|JZaf_JP}6(ED)t&SrW@M+ouB0L}W$WnH!gY6u+$an1k?vIw<- zML(3U`1+uiDXq-ic0okwR7iw|jY2uq%dPwhq8UvaACl3g2^8jWc{zQy8aNK{F;aEs zwW52iOyk*-x^2y#jfXGq)|c0$R9QU5vcaG_8bMp-pb*c&ZepMQl1WIwPi!N0UMPZQ zrs6B@LEZ26xM^!p0)YBWrDwY)Nbs3HyVmN|J@JS4P#@6t@V(UZ9IRRe)ZNVjvn}J5 zOxA=5&`Rk)KooN?d)h=zjK?b}D{r2y-os{fj~;`tiupkspsHy-)EHiBPH_O#jHpfF zeS0lc+KO=X^FjY~Qz$2u1S`Cbv{aDoh_C^Enh~wL4{z1ZYR=6rZZ-zimFKz<5yDun z$~;!vZFZA&y?;0>C6OOKbvxNzNWmML9LWm}X~|<8nJT{(UHJQ|6xuiUe!R{Qr)tYt zR@co<4~F+OS2rM3fxYJIq!N=I{%J(IXq2##g}vExG*{3ir(@bznqMwqAA`}3_~Lc> z+`lb1&s>!4ER(%2BbZs`bm-n5t1h}W%bDW(8&fh)0Masj_J&jdFxJJeaZf!VYpE)&7=qs&SbO`(Z*x#5!)5Uq#B+2qqx}%b=sn? z_3?H)Ef(NEQg7OEpzpp-(d_uC+vH~7ft;~fqC#i1;AdDx2tzR?ln)=;R?yqOvtJzP zJzYH24q>|a02&rJ8y2wmJ}vm}dciYCaAp)BQnTW;nuGOe6N)gIhlV-&wA$?j3X8Zu zY7xJ$-QCi<{0M*hc;a`xaer)rxS)TepvmBc4D)H7)K!8?&V`;C8QvGs)NE#OZFx%? z;PtF>>izM;qU3&9d+!lbfg ziQJ>GUT>2^v@tea80cgJv(e|g{Dg*MvCb&88HnOsgZ!0JdoOEqQ6| zw(c#HQNDY-1xuOfbNgwkrdvvm|MoqD1iSJ17;aK)n%7+&w~FtHXt}|y68FPNbG>(U zJ@mWNzjfMV^gz22f6@1-&o03WZj+X%apZmL;O_PbR2v zVCmq|nawM|3UB(5#vjr@xrG>ctf$G8;;MQ31kU4r-WmV zy=RzK;9M$`1tUK94|47~>XnzXLXJZw!vw-j6>3xnn$o9w+?nO{p__vR2*r;I=L6(D zt*HLQ*)lCd_Z%O+=ZiS^eR$ZlmORcG_)H%j?;ijJwpI5#W~WeHxLViqEw^hrLmL5I z_d^c*Rp?t~yp^pS;x*}d_z;~8G6nEBbTy>u-ej-4JU7rQQ-H|u&knO3NpCJ`Tqj9o z-#tz5iYidAoGsmwuQI>i@7N%9+}uFD_8ZOpQVJu?5U)rf4s}!&5Q5V?Dvr#oxSLVq zw7M`gD)um;R@qPV0nHKor`3A*_e|xSFmMLOaahp9x%MG31O{9xb5|C?OXTy0EJl#j zm?MyQO5DP7MOSqBEO89)w#%OB;r_Tjokw`SK@y&@3@5rOe7@8xM{{&KPsY{<278X%;{)Q0VVeCxQDYtIxc^6I5?tmjY`j#XDH6iWhxnre5kOk5E zx4xdd+MoBQ7)o=gVPMpBT}8=4@!vzyU!}w_r5V&9Xp0PjgsLW)C+3<6;0)5yzi=R& zwA&!NpLXH)r8qBwE#0ku8+%#3J@8R7gyBQ6N)nsPt#9eF~1wt`u7V$hJ=>EIYf zzIy33Yx5E>6j_ih<8=}o5@HUy9ZXe8uZ-F7TF%%$c`9d_KN<{4^yBTv@EV%%-8H2N zPv$H)ULP&;w*F4ckr*zz_Pf-rkXya+oIQs2rwuT}?b7+gOXm=-5kR@M1iGB|Xd}DR z$zj-wqkZf26Tv?XAgztw<`7#rlH6!xqEmh=1I}YH!^{u?+8CGL+)A=RlcDp)_vqfe z+o@ri@|kFnW~x&+y9OG}>6tFAz(TH$oDa)J4*f8RcUt)e`&J70rtl%(NS@cQmDk6~ z>KZlo=TF-OyB?_KM}0Y7oNa$FD8E+M^D_>{_O7LR6}qO6uVLUm1qK3j5c`huXgKZg zY$M$q%}5=BJ3c<|#!x?Z*IH)Pf?fpA7ogZi19g z$qqy1u*wA3_xtHz3|X|;mG$Dk*WDlSUc^~Cd^b!U^KJV=s|iDZGIG`yL+Vi_o?>WW zgI8Ga<M*e0@ZYWwgR31)$**v@4aFSqt z*!0;5kW~*3lf^vhgiscEAE{w86z#VXL@q!7h=@FNIG8QS;rEN!*rgfX+vN!t;1^ySjBR^F zft_3S?xYpZ)nLs33$Djz6+t1TFKH!7s>fO07v+1WLx^o_YKLYJPw87Ib^|i3*0qc+ zx_2MWEDFp778^(lr^J7tVd&)PEk*gM9Pxr(9zt;*GQUK5!N- zxZ6`i(vke$BKol3A=oya7rS4q{iaiU)F4A(GlmmhoVRHZWkMh{Hz|WaSEonl$S>H# zjex~FaDn!#lHZ%i%NPb-b@4>paeCaq;TPVWa89r{D^iriI4`-fjpP{gVX|9R=XQ;i zk)Yzta%c)rz56HO3l0DN*g?Im*6dH2p>b4e#yaU(2>wtis3;LtK>DeW3`Ip*x%h*g zU{j*>L?r?J5rWTv=k@nd0nDoik@|gTnD3=9SCX4il~lbsQnir!C}&@~-XAu6!5f71 z=k{6&G7k)*^@WxY!8fIhr{T;gC=xk^ojM1=@}w9<}W%wc`#53)I%(0Nhkkbv@|mGG?Hy`6vXN zhtSbTS%EGQ0Dtm@RLiL>03tjY;(7(nIYKFGCLFjrpM5UNN4C}HI}6Lk%al2r1dH+v zCy2e6(ISKhp|y(E0#njTuMpTZm|fT!{Nj;>#?3P|nQ^yXbv-apVnLub2&@ZCutYiG z(Kg#!dmZN}oQhH$s~%EX)`T)tkSkOYa(c(xbGn=)XnqO4Z#Pdj)1UmrVy!zLpsd9N zZ~S%>&be^~V)E_euW{2PKRG^%+>$T0Q)URS?zk=zc9hGI&$DF-9dB&Sxa)Agsx)Fe zCUbwb{U~JGiQ1OS5_!=Dr&Zv@z_9amgtYxvW~M#3{!^*GiTTf?B%5Ypb*(+ys#+d@ zMfSgO@gt}!ZxXv}5!}BqG*YP2h;@J;o?%*-jkZ)7$#GK0qn5~4D)Z3|k)hM@3%RL-qOcL>CywSo*!lT^bnZcWsa zQw}V@ufXKhM!qLw%X?_^HBXK$)`uqgh5rwZWrq+K#O?i z)`Nc_16>4<^swZ%fB6Ll`k}S9%CY5eB!)p?%J=Ees{e>$>>mDf2A~;m?J=l{PxRgW zz>Ma`ZB|fwyYFCX({%rRv`>)e+y32t$++^Ctrh3L79V9A24fBLbL2B8v@@KaEt)6Q z9YUqC457!-Y)+>ci(L#pi15KMpRm%0tk#~*+O-X&tFB6&%EkO?z2L6hzzSwpgXMe_0-pj{epswki#w4~gloVFUrSR&70>5NJj5vst@FZt#oW zG-fXJoC@UN+Ze7j*w}sm$5QhH^SmLL8@62AX~=s{1v&oo@}g&4tYO zH!ib}1llZAN}5mSW3!tg;R4vzfW{vPCW|BlPO#3$S$>9#Xh_v8Sx}I8aLK>Sm~T3V z57aRSYdg9EQc|yS^TcL~x_D+#aEJE7QsT&WsHCe>WC=OV$y2oE;U`tgIusnM z1X-Q*%L(B2$^3!#gh@*}aCU}wVC;q;nZIyoIcjyx4pUeKUb#GIi|=~{t1h)6Tahn# zu5B?z-M2|M01;KntO4D9LPun4r?wI;7u(sqBl(&tJ@9b6-I?8gg0WA0!Gzc^U;;{_pk;;q&wiYy*o?m~nEZ_Kj+7VQIF9R~t1iJqV z;GqxY0zl}kBsB2<0$%*j5ATJ6W@8e$EJ!bY_TN9z;DMyy ztDoI3W3P-;0bH7KGd$Y=0)9L{U-0#FGQ^*t=k~!;y4`*1VN#lW4?sb-$Ni#w z`Ng$>l$Gpro7S_lGb!!c%(T?byM*2r1afwC3P`b$DK0@RkG8f*v|I4nLO z;%8^_HeYSAYczhYdpJ%_;xl#}PHkfK*ceo*GRIDMn8B0RPkv{$+$>_kpe!*g7E5{k1ZjWxwmDg4AJ!z!hgs1%@x8I@eKX3>%BtRH_A&DEiVxMV(7GNDUQ5d~A6$NPv0g6A_^X#S)f223L*nwf%G4MsT3X&F#7Z<-~u-& z0~66*OR#bIiCrG?!w`{2`Ma~$6rlVV(QG<9i`{BWfq)|yS8_}d`FyP4c!%fvYo(mh z$QTCAQx_V)rZkWZNKB(eKRPb`;;%GNkN`$a^I8z*PnMtrN=Yfoc;Z_K#F9YLV^!nB zT!Z~kLe8#_L~GkBl%Euwu`oW9S8}^J!4Qes>r<`(A#R&SYk$7Gbc-BYA(D66EVcpEW37p^BTEboNp2u8*jih zfI89(uG$cGvx(N;kW@DeS_Y`I#MJ-O-djdhxpr;Cf;19>v~+ieAgxGuEF>kQB%~Wz zNJt~y3#7ZdJEXfoSac&@-v#b_@BKZ`J;wX<{qr)`k882URcFn4&f}QJG=wE#MpZee zG@n4q^0?B6ccEX44_v_8M}#U>(BU&nJ%AY)5S z+Zdy&u|$%DuKe;&Rs4*T)ew;A_efeGyLwnkg;f5SDJ9Coq1k(*<0w4i(}cqDF0?MkurB z>tU+Ri64ncg1=R#ykRCkIG-eA7*8gVp4QRRX)KAm_4sa}O_)&@T3FY;d(Ul6qoM6c z!gA`+?N~Um%&hcr=<*@yZ>#lG4dCZLXeW3!-1w{y$w-Hv?tnYXRLn{$Oczx{g|oc8 zx0sfG-iea^z5)ccbQXgKNg1pauHW!Gm@?v}2z0RLnq)VzG#7*DZ_$NS7q6F9nBkl+ zYmsLU0MW`dk4_>L8vWTk)+@@17s#@ouKo7Gz&$Js|$DK!#^TwCc*oqTEC_#vZ8=la0QHDR!ADMrf5Ds-};=672;+!0Z^=@Ey^QFJxD-Wa30 zEZ_#B*Cl6WWZ<)UQ%*P5Dfnyvsf`iwOYXGdLwr&X6NSr zy-wRNgmd}bT5qrA$k1$djxq04KAx{d+cKKF*bbGWHNQmM!_IJtsKX20oRg^s%1f(2 zj-H@lMZsH^7zcffQM}Byaf6eykqZy$kjcbAEui}0 zUYFDx(wE2dS3+lPzsmBhP-L%bF9LU{r50j`gf0~!3L^K4fb2|iscAK$%Aum==9Sj| z*zNP16tAtyIu@mDHXSI2X%L$k|-_P`^VETxdyzMKD~mhLQ>quW7Dj z#vx}B$SQCu+6c+^1zcwHBA$xofM^UK`Iua72HFKP; zNRjuOwXGsq`riw3Ns+Oc<$eV~L+4Q*TzJJB102&OKu9L`d+^KOAfa5w{Fkx@}o=Us%3JuNmiPn#&k5Kdc2%%j&6 zmlsw7Wc``^(1hOp}`yPu) zo~;fwn+so<6#IYi;lK2_lpbhKFc$~JS5yT)*tneEuAXuw02(!$Ft>fe8V^}PkU6^7 zIL-Qf zVc`A>%xQ0si)|frmWA5J(+tD-#f}yWcidO3Wh(WsdEv}=?zD=1zg1dHL;@*ef(UZHN)Tw71PXTbcl+$jRkoQ<0Cqnd@fi3Pm!Ibdt?W);O=wCs z@3K=livmvWrV-3X#HCHPv0t{RJi?eb1*B$>xoCgl>3kKfWgC8V{Zl1GqkFZ6y&4gB z-(#~h+o)-jZ>GUGe>_jKeWZB;E6B~@3r1S_h%J5wg5K1kbC|5+OFj2>rM=tu++s5{ zEcXZ=J%@a?d< zaamK7tu1|VlG}J6@K`mAxZlX$l1wxgyI=JFCPSmW5GNK5cw$$E#o-N)uz;`a&oLZG z$Y}*0SDim--jQG@q@fd+_~`fg_1U1v0;!X|aIM=aQ3P=AFJO*$+<+i**d9cUqYxnuPThkwQ&VttBrB>HzI5$Sgt#um*oBx6zoM zEbG1@0(*a)$kbSb_~TZMPOXoiED7gBj>J|)pN90)%G8by4aYrRw+NxOYdl9+F7>W*o%CHA3W6RR zJ_v-j{%O9%8<$@Mhj_@~Sv{)USjP$&2hlv)0@} zU*B@RRQ-!m`BH^T5E-+n6OcEAijbc63}I?AIovhZ8}=(h+~o4x9M}OAS<5nXSa$qZ zF3Th4(!&Da!cXjcZCofwt_4qVGN5mBz!z=|&FVg)f}X<-mnvvtrOs;!%~R&AbJb7< zqLM4#jfhFswrVSfaNGj@z=0KWppY^cf@8odSbs3Y*oTUSC_5llpQl~>eWAVy$Rm4C zFsw-M1CBv`rR7-oPSrtIMzQ+B>_^P#lUTL<`^i}1*$q_Y6!lpVlV^lEGaz5ZOYgS( z^Vv{JOY0T8k|qDf#m03@uV;fM0f?Wqu3?Y@-&cNO8Fu7A7#q}Q$jU-k7(?5c8Y9%f z{77hb@j-APHzgghl^HIyl&#bpBcduTP?`}QY+_0v`qcW?FQja{_{OpJ^Vml{Bz{Lz z%3&*)H*#L>bsRMtklXbsCKU&Nw*e$oOp><3jZ{}EOtlP;fNxLEd9v*0z34(cy_pl{m}~o?`>)EHuFP{29pC_%hRxgJ6Io>h%pF~ z1tMSk#5KZil?iuO+Hxf{zkviakls^)QGH&D9}LzQKDj_%ETC-jq}*|-f;^vSuvx>R zRG&Y1CJ@I*;+ZWQ=$UbFNzVm+@uau+jIcHr%V76}*ZmK8n6tNJI}`bZPj3oU_ao1t zX%ZpZq7htv@JxAJqW$Yz`dIkO6R#mRbX$q5diSX7V+ zKD!8Z43{DTbLS(ECnuzj4FaQpTVJ1}yv%2EptXfqAiU+qdj5?^#ob(m^#_%buU#l# zc@w>GtOz1gyHJ_b= zeN|)8{Us)Tf_3N*rTOMLM6r{U_3DAa4ODq~LI}fl5g6i&yN95~BS7#YC6r$9g2J3P zI!Yp#-T8>8Eo>;u>qm3XtW!lRMIGq84gW{l;r-bl++x;t&}x5NyzW;7!vJZYH&Wk} zm6gp#Aym|=eu^B~Mv_ViQB=7v=o7ed){3L(zQ2j5Xy-I`_SAP4YfNEJZNfd zyqVlMNitK|s6T(TuWM3Rxl*=*BfF283I}6ZKR-1|XMGs$co_MEt7k{q`j|;jLUH84 zOHu`?2HyHL1c^>1E9wP{YLE8&oPEwoSrXdasZYFm!?)z-UCmO4Ar)2*Ki(UwYFH#v zVN=4WQ$1;}I-i^6ks$2WWM5Ps=kCFQ3k{(Woy9GDrrpiSWirv=^WC-EFn*L8s!$2% z>MAMR8!Oz{hJFh+`N`0L&cKu?Z*=Y)VEn8Vj6MX*r1ReNCncQ;L{*e+E*RyQoQzMK z_5-|s%beo-mXN(x#C>GdBx57y#5Uu=Q{rDS{>#%ylA&?R&fVg<k=Upljj_uz) zSkFtn)wMGO(QnkocEw*%fM($PqNkRU?1$y<`B<5&zBC@zB1HL;O&4mY=jUUrNjuc$ zX0~Fp&&<_3r50)b&gM0XA=MaLE{&5EQ8I$p3(U4?kplJW!v>w{|MKp|`?*%=o(W@X z`24!EX+4)a7z@TqI!4A8?~3Z?mf!3v)kyn;wVF%0XFPa7K4dE6^h01ltR`JTdPt8 zX8tr;3oVoDFm1qRJKcrZu04hXR8S7Z0y0OaPgr#Y`j?$pMx>T!#;JlB5=&bhuM*(Q zv?@4kh@tvF>tG~4f6~}5HEtnBDwDjPvhBuI=Le>Y-pxAjQsK5O zNGPl|r0>1U%1xG9!Jt>7OXNJ(HO#Z4C9N(J5toaIsR?fW-($rd3B%zou=gH3eeRk} z-hVdi{>Wq(^f7~bqd%ItCX4R_kijCAbJfD?9ImGl8-l)P zrO_Y1A$!=Dz`q45{CX9cy!gFPIHV{D{lT&)nK7>g4lp7 zrI>EDL}*<=^vK@6T8qQ;piuo&Oe6!&n&Z%-%_yxoP?^#9-lurfL^YFg8`VqFv1hu+ z-5l5!2rT-W_qcTlC^30^lXegWo$Y>P*8|0z77F`35cuQubaB8k*ROVjL8n?vO?{7VU^PQ$a z5DJ+)?B9{A07YAt$hHc+U=Lc~s>fiwtSNde+Sl4A<^0k0l$3$F*t$q&D!ZpX@5Nh9 z#XNWqf9JUkC-;a@c+hrB9&(J(S@K3~%*G$I2#gI;rsiYJdV~*NQetj(v(U7vFN?u+ zc8`Y%VeiO;ziHIhTM5!h77X|>Ytxi`WoF{QEWnK+ys({HNf8K6H{2?N9#8O=haAH* zmW#Y!a`e#*`IT$(uD|DLzW?%TnmcQG_ocY#ReVO%<@~}%#Ozv{3ybVf%V2}2`;?e; z#B44lGQ5eA1Q*@Vm5(PW-FVQuFngQ|QfxJ(0_CC!{aiZJBJghiZsp4>8?z_ugm zrH7ki#9dv5CDrGHF*zr%Yk>i*sntd2sU(TyI5@*f0^b+Xt_q1-4#@Md!Q7bINF@~( zOt*;&3!h3l*e^mo9l-RYw?W7AWSJ$lV!=3|5D}Ya=%D943JtG6n2r9BadUxa>5c8L z_*}O zse8cl64jc&*|5Juw|#VZhMfc)OkUvZ108w(bko1~M6MxH#axxUe@whoe*x`?X>er6 ziixVZVbQH#W#JNX5yu5>5C6XNb4($+e&5v0S`QrM^Q2N|zqy;qLU6mYl!kTj`9l3X zk*hzVi$7oScg5R9;@2h@_b{!kg~#)We%*f%69U?BMwhY4+iUx8uL>HTq|OJU{KPui zK!*-r}tPE=EXSw<7sfbds2j5a`)w!j1v5%3Z#apx6Vm%INK3Rv|a$FS-s2wu7bo zA~pTBWJoPEP3LXU3-&;kb9bg&RHyVk0mr~8Shz`kP!UeQWOl|bPZ46A&0F)>xfrr* zo7CCdQ#T*xdY6^6FF2ZIZPN6keCYg(hl%j{EI1nZlAN z(X8(@`KL8)qx76up>GR}KTbIZ@c2ROyBf(R!=eSR5}gW##saKgYdRWnDKd8ag0Wk-^uuFUmupq{Rl5+5|-$ z-E!D6_qdAGM0XU(uox!q^z_RJ&DsKaYGsVxnHz>%M09-~KJp_~(Dg;xK0^THl1O;v zGOB8~DE7oJU%auw&{Wdn!xf!fj-{#Z60cxi%P#TxHH9|3JEfa+0xVOgZ&3>TDF7=L zP8uT>LA5E+QTz-<+GdWJk5<`SAFYR#^2hH8hKOnKMZEHVrx*EF?aV`*{7ZmXW0)4d2qH)dht- zw30WVFu;q$l>N*i6ryLantd9f1smxJ_u*E&d7nflJx;YikwvTE6-710b&)|Q_V3h? z*hmlVQX}9@ak(e#37AZTxMnNbLFf)dn!=AgBMlqxaG$0ORXiiv`R}QYMsOVYsz+ft z4n0=>IR7<=JY2*86IgHAuf7#NEV%#c6Tk_pn%AM}U-IfNK+x?_{J>ieUy2O8ktAF@Ft#at{C;af*XIWc8fWVRT1IE*cE*EYCq_$69%Uv& zBr|0WT6J7Uu21AoJay@o?yN&Usae%jqY?2!o$X?8YsEee+>v+h2#zxR95iVUGnSv) zm_kVD=Yu)Z>WXJad}!owkzWt(^Z6=}8R$elIJhe7C2}XHUGikN-$Tc<8@D(4_Pg^k zDWtcqIlI0=p0S}iuDt>)4QlC7S8{a}0Q8uAP^3D&bZ@P6|){%>F{XLd?xk zc9O%o+18-RI+2v0usW$0ZFT`KoB zd9rE?5a|e*_LkR5u3-J)n^}Y|ev!Xkof2M2Se>%An7pIhnY4ZuOD(=po)Dpz`Y}f| zUN*_}AVGY9F|sB;`C)99eHB?`qWATE=;f9VB2S7K0M@v)6D{BV?N&2jb(ZIk^puYPW@bL^+c& zw`w9DszjAoy;;fQ^#Q}PA^uga*3?uuGq)P|i2ZXQ&dfG5nBx+tcb2ok(NC@oUm8P1 zr5Da+8mq_OY`5rkD1*H>bJ&lap>0j*mV|SfR#0FSYpGYWmzINJ`R#Y`va4e?>Oq&s zRV=IZV!**L#8R{lMBUT)F=H3h7epPVmk6xwT;ZmMEyXuc3-#1qP40+LH05GFmw2-v zJ(t&yxag52FkPK@ajL!nE7d#Xn+E-eU=NS<0?m5)z!&rd(qB}dXIe#(u<$5xj`rJ& z3VG^9bbGUlA4AzSTkz~bA6r!G?YERix7Tq2l-ShFX{u29JgGdmzCVaHELNU)u15=d zDHh78AtQ8~=K3~L!ghgMBhL1ao5;AjX%8V+wKVDVsCB@%RB%w?{x(&1in1Ju`!b0) zW7iO>XY})SggEyLM0Ggp=4bg9#p?yuE>`<`)I(NBOJxr1EyV~d z_iK>VG9s&p>xdX}k{Zf&G&my&Z|B1?{ac^9NpBg-B)s;tY~BftvHgYIoyj;RI1Pk( z8+h)Bv5Vo))lbH^m7y7dR^Ny36i#sC++OF}!ULkw#j<*Wzx5Gc)tW;U6AspIsD9|W z%k57H6{=jzUYaZ*s0i`3DF#x(zNMbTXhLd>qTcG*L7RfiO)X| zYHGXXF`HK$EVNV4p$jIai)XQLk04+zN#|3$ZaDFN^pRWGRIGZN6ivc zpgULDi#?A*O(8{MD&=3atB;~n(*Crxd;>V=oF3C>gNd2C3*~5f=bCR4=t z9(I-o*t5{~Lx7s=$AfFRG+h|ZRkgP?udWLc=-PT*E0dhhI!nv!XY|(bagBI&mgb$b z5nOoGi{Ae*{8VsL=^pKJ##*O<4~N2{13kPUt`bjb4(9hmJp5~>-14Q@!m|; zz+R@Ae)C`u1EO2Do2U99X+wmat!T^%y|1>{pThePZNRa^%-0adWq4fl;(w373FWEnG zyceaVGc~Mah(?zU&yM3b!r0#_XEo^yw!Wj?m=frgtxCIbao^-zXXK%2UF4Z?pxI3W z+ixHgK8*^*VZeZYOZ??#%y(Ri=l<}1bDG&))2Q1{^ms!={l-EM>fP4Rq>HfG{MLQErU zCiGjlk5#)SJibJ9Wu12My3DNQ1-3LJHmw|IB!~{RsP0&qUh$AFgqmHBmi4~2a=K!F za-Ffr5H)g9nO}%T?ozTV7YiP?bI4FUC4xZjULlX}Jio~F({!l&KF+0*p)06$+M8no zEyU7p#CL;0gQw)(E)gBmpbGq(LQac>mNv>1kIs*rTCxdjlWF#1ms(X;I8g^2pHtBU zQX)1ExGh4!8`H|v4z_}Nn5$iV*{NR4#d%nqdQAuIRre{a341O9Pt0c~2VaG_mQ6`mk);-V6sC9|C)NehEhDTUUpQq`l*{ z0K5=m{LvK)*K^&l-c+wbuDzz?V;NO~%JB+hz5Pb4wHf@=U-{qP;gBn4Pzdf{|4?Xt zhJ&+5;A?xJ4=sOeL+W2W~FZ`jV# z6v1#??WVUUox#@7?o`ha&q7K?D$#~pKfC*Dt0I>vT~AH%6LhVL3yiJvX`2~)k&%yc z;5$3`ZaNICZxJ4TU?I1ND=s8~>JUfaSy1&>x}{IBU5zRl{_iNJYr9$o{hh>nJE6-@ zelE@R_g*eLWd|G`tqkvLN?a78>2$~4k??aqM^9Q$(}l1$DJJMn_WT}bX{CI2FWIo` z{IkbxagK%LF>jmVIV4k>;uLpI8kQ;?3b$@i0_thB)QT^*p6-rS2WqMo-JT4&o>1Zl zuOHM`bIVKFB{QAx3V>*h7=M;tV?-hF===!UmWm~Lx^_*v9^YG#h%T(iPH?r`ZykIL zf4yRKlNcF7v3>-DLC}wt(LQzA+Mdc8Ngx{oVam}iZP2z;!&Z4Vi)4XChi=t$v~B+u zgXAKB!6B4q!|(NJL(Aw>E6I}gNV8cI=5Jx(ab8f#jWbXrLH6kDRetB29fU*sjAOaN zo1UgdovW^lOEZ6MIF4qh)qe}u5BAFo@NS`4Ejq&>gn|=EaB(&%qmZTe>%OjhnTXm~ zw?G6Tx3n3ywslIZC_`G5j*I1o3G>?041BRez9U|;@HH19Qv@HuM$e{!k+_Ryv}be$^-BMgmzUifFSbpbJE23~=6 z?G_=Yi&*-4LY7LkC&#Z^c8;^ml`6jSy&{%R6X>9A`w>Y0@=T$ffLd8bt)zq38oOp* zBzv)bfj$SkcXZ#a&UH>YG{jzAW%0El%KLl<5J`*emOrW5$QTVXHB-!RSansyWXH2M zO*o^w)c2k%we1e>AG$%guFBM$2#pTQ_(_MSB)4NfEZid3_{|s;1UYBvUa%@LQr3)W z0(!?7SFp;O%*sIwR4JECNJJaeV?Y~;( z&%XwSjr)sUZRC=BKuy)CBqHw`>-`o#;N_H|qL9FqSkCe9xqOQee)$8G(kSVX@Z8ZV z@kfY5$In0-(e76Tv}vD+xt2u@%>rzX+%fQf+gC9BbO1eF@YrBZtC&-J6}<6c6^9g) ztc1qh^EaPn`TJdGWn_JrepU(l;TmP?eYWX-(iTDxRf*c&9}>Xp#79SZbqkNQs9 zcR%!4!s`)ys6w~!ZFD8xvZ?p03aisjG~ z9^s+fzQc&kFcy-g*M2vwsa=hNljOsZVIJKFi;Ae>sTsFEsUHnr4noe<7Q}PVOClJ?k~OHMNMdJ`3ox|Ky4B8n!};;H~|2KEvy?TL3!748C-7(Mm2p=j@4DH6!U8O z(#I6?t@epwBrRXR%n*DR4OZ8099wR)3lT$77mE9O)eFBdg`DhH8D9Cdl=dii1w(Hr zcKf74JzBqCqktop*IL>xyWEV@l9_f#-el|-ejlo~Q#6AE_i{N7h)OiK?6cwQiH-IQ z$GWFbijX)84ucV_N;`ko`<`icf|-yOz$nn73{cKH~&y$zMz`Vubev zTL&;ASE*&jy7CGc-;>VTduj!5k)hz!tkxW`t+ihx^|k$!E*R3Sapi0qWTs^7avlC0 zdY`DD<}XwUzQ;SfL5z?<8(sA0Vea#$5TG`$-iq|%a^{Yz3qMs_3@UBduxy-v&=D1( zzykKO&)q^Sfg#ev0Si@ShuJ~uAoz0033mj~Uu8jj#lN9m^?pH~tUCw(D^yzt#4Hurb^{M51(3;tp9W$t5>cL@y+{vq8&v9xzThtJwqgk6%jQOV3 zVuy>6t(#4>Ia`o^L5=$Rdd`ZU27=iMiP{w=bCr7)at&~v1+YJtzk6Rg%65d1&ZNb& z7j%r`fLQJk1bXRdVCa^i)9;{&6&$ZjC_58fmO0kvuZ%DhnmX;eR|!sGN9@EYkW%!E zwm~6uTd=lx6+OboP&B;??N?J$5#B@TbGjbyk}0DkK1beOOw$Jc z-f`#m+_}(oiNsu!;X69BVH2(>@}KhIPGGrJhS5)-73n^>I8E`h0)5xusYNFPmduof zqDvzL1=OB+zS?w`Q0TbYy_~>~N=}`SQV%{QTXny`ybjr+jp8d>zE#}szz)Wm6FjIs z5F)Kbyy`pq3z6SZ>8Pf}d&)Ub!kf)J=WJBYD6S`|V$K2zKr zuXVhda|FHq?NT!)sz#w-lo~bi?Iua>1ij9vP--6a#OrbbBnrUpJzye$+PDG4w5MAI zdl;znC)iGZ49V#);|?Se8pF`wBjLW3n};T`$BPVWFdC0jAi|!ry0f22EA71#ZoL)L z7gVI(l5M8SJ7g@J#5cp`wSu*PSId%hee07*vnljKw&as-^wUXO#8PF0X!7kWzZ!x< zt%V#9wS^9Bv0Y@ipuvDIFmURx@Kw|y_FqA<@NPo0xK>_Ba6#YL3KB5a>^D_dThh1@)$2*w++yud^Y{~XFg;TVjDZaD`waqjF>+y00zJ7RqDLBOi5USbBJ zS{O8tMqHxqT@RuvZQ!^{2~!1vp$~Jd0UPNfHvWNA>)GSiV7T?$hT#I|FU4mz5hB5X zC)<-erHBnh969OR-Z&;r<7!H5-~4vRoH02aP9u`OGZ22l)`Mk_uYlFS>TrmEWf5AS zu0e_fwwxTDkb@|CYjq#Uj3!>pHHcOTaG^`7Bh7}!(FUj}iTRZLDlS1-x_Ps}f;m5~ z0C~~2wv0&ogfX-c8>wLVY5&WD#Wftdf$$9g6-kttJViugqQH9_?ll?&iF_~TmfQdoTP;WJwGxN&xx7bVj-Ipa zv#BfLy?Co`<5|Z*tMBjuhx6=x!JNwpo?jWbo0q?dEu}%PQv6%`E+hoMo?D^t!;5$u z_I9dIO+x-foAi_cUfA+X*}xVxk_B0v3#_UnlLdi&+qZ*FgRCA8PDKADIej5Cc}tX6PxgGQ85G{Y83sL|8_D#fw9B zBN^1#G=nTkRFQs>YkK#`O{q!Yq4UJ*NH~5n`aM&A>U_nPe?SI9X(xhPZdu(U!H zJIqzoF~$2mXlG7Ds~FX`d^Z}PXl9K1t<1v?hW7n@0UFN^T&iF1KRTG{&kygJ;!J_Q zeq3gQ;U1toAjy)Ymw%*PnvT)l_7TcM`^D}34kr%oS3j}3{6h%M0f%2{S-8nkYtUn* zvyUHiRjqNKHmV%!E;phdbFdvqdjSq2U8a_P!O3-)Nt~a)+QlqTc!Hy)O8{wmw3a|MQ+@6)6R{1E z@N_+7*_UuJZwp{*s39aEwwlj~c^df?kx)bIFO|KSc)0|(&D-c)oyGKNc1ZRpQ1}?? zuBrQ9oq_StZ{o=Ih>8%z=H?V1QBbG zfLV`apc7?i5y2s>ozthvm3meHW~+D##3`Ilt+C|Y9^8gQX_T|nhQkPH5HzC8)RJ*4~qNYxU>gb@%lfF1?8B zaXPRqj(2VgZdU2$$=jUy2wTyHgCuIcho_)rl~FjyBTI*=wJNA%29<+GK0mS*3IDmD zJcrsOW+--9P=%&9So(>@AXQ|(?(;LJ>_rSg2udN<$q$l1I6C^0uSJZ)cfZS()X5GD zG=@X{&;~iPb%1CaU#5gw`7X0|jbGSHOXo@c6Rsa$%09nquw-~&5%77Z^=l^!+T2wY zk(}1T9e78f(avIrPxGU}nQX#wTB+aG%wCf{%!kIkz3F}QRb9VKNa=6Z7Yru(1}pnK z)o~dCLnHSQMIT`Udg;1g=FdozRTtZS8Jr;XVekTvs)iSj)S^hcFLv%#}#kxZxg$6W0bT- zx6V3)<0T>{px*W3fz;VO_Z%eC<*V3{HgM4S^cYNhy@0|p3zNVWk3qDxUFMd9nG$2y zv0u|1C|AK0%ZyhqVoWy?r%+m%g@Hk5)}Q}S zIgC-^mE&Kp!7F09eojwjpF*uoplF$iIKeoF{uX11r1HGd73D+x3%WdWHo*oSXE(rZ zy52s7-v-mZpx)*7imZnZF&l_o$3t`3b@hF}PPm)rh`sv$m8cl>3cb&?W_{&ef=+d} zzSG11;t1t9C2X8V_fgvH4dovsl})D`W1l0FbDt9JMB=6vd`vd|i&gD@tSdG=BZG>U z;1NhAD?-w@4MTR}vOst5>l(<9|J?>)_3=?t|i=IGv_FuQfvPHW){|#oq)yN5y{=Ac1pM{{8(MZa-(~6Js_4DNZrBw07=1-eL?={ zFW(qE(eadcHtyT{fw?c6So3#7+b_l;I>s_zDB`J5ky_wQ;t+6r;UjLhQ{X$xkRGCl zl1Q*fRUvBm`k#GU%I4HAF{Y$JaJoQL5Sx{W-0Ew{BjrL|1i%HvpCqdRX6)q*TvN(r z^5^^`Wz)Hd?!Gj1)4Xcx)2IrHj%akMrHXa-QD6B|J2Q3UoK zA%Hc7R*-Dm0$1vQhXEBZU7R|tCMc;JDySA|w-y{?;e{Ad{y_;tfuz;mZ4DhLvbSfy z*-c?zbl-JC9%+P)^VkFMi0LQtF`7a9mi8Ga<#B5(35T+o$B*<<`Y&xzZ)fr^BF$DM zOU`C^bB_vz{+uvHcXoW|EC+vT$^09P1dhq(06g-$rKu*{Bg_YQYybYVtjGeb&|d50 zV*POY|Mi)X0Dk@?-VgpmBKZFyonPS4O#smJ{XYoJ!x-TXE19-j)-Vdn$!>s}yDSQ(yM^)-KiP806PqB&Lc<&9zh5{!6Ua|<>}NDwih58gBOyIqqZMeov@VU{I%{by^r1jXGF|3jNdB9b#YD)eO?Q zUjN-b-pIkuK#cd}T#=WTn0cm|E zQG8xZw=yLAKK64rfh({6!MuAOY`qZ@9`@g8y-`#P*f%J|S8`6knn#n>3Z%D~dX~F3 zn0z-k7%j)jE{#WJ?)cVlYrHVEB`|aUmC4%ztQcmDa~Cnk{dwxAu1;v0X~AB0Wf{Bj z5ouxPlOQH)If7W7QIRWjcjZO5dqXpaeuwA%(6|3QM1Ta@ZE?J5uFE4%`lq`&Bq8r7 zq>nfB7>#y!u%Sax#!M0KA8UTN0~w#<4acHYH+DJ2yWc^FSYvhF(@M>~N2!upY@sVn z3O!Ypa~WR6EXw;GtKw2X4ud)DT+vd=2q?eBz!-pnztbvMX=d%E{WAeYJ|Yh*QwLoR4>n0;~xyyJG%c>_-E6uD_RGTMN=Z?de6t`a^yHyeGsh*pth~}_y zgiU8rKn9@Ma9Il_pCezne>#+O6VlJtt!lHiJTG{4{DwXOlFte6sx!7=n`~uwi_np1tkO6AQNBf_DXV_zgwD33# z#dAR^HGj`xJ%n$^i#6W4I_{X3-Bw+M+0SeYYGLxr%gIFpTv9AhB^7lvQu6t}K6M%) ztwzN4zNMwMZwfw-^zL!5ntdk3>rRt37r^h|92u+^+oXYydw&xU;`1^~vh-bRJY81) zXT>7Jg}sr*M&(}rYb6CVcHTflT49f8VmYDhVa?$&yj;97l&PL~mA!6PX56FEM*xKP zU5i;(I!2bmWwJmA4@EnXC2a^M#-u4-iqa7NWcI>I7IPMNiYq!5?}lN)6+KFZa3U6a z90dUdr{IZdntMY2NO9h-i~aCe9mnw2Xzr?x5cSE6e`e)ZT7d51%+v7CQYQs_IX;k8 z&cK*LDkv|}%-gZDpa{BrM^8W`^o9HuGpcUVeac+?%DI zbJ~qE{2nUrv_UD+NC7y(LBSqoH5nPZF(JK)Kl?-ig1)PPp)pS8w>F~3eI&PNa8L~2 z|L|p&dnm(`l0MCc*li3JGQzF1dqKW~EGG-NMNG2cK^oRq&!5R%vzZ*w0-gFh95{uk5d5EGIah=_#o zw?(s!X{j7wjg`PlPA!iv`@@BLJgW!x!G6KK!TqBI3_J*?fcI(`Bjv@9f6d|a=a6fK z^i%w~M`z&g<@K)vOgzALeG9VE|I7aWGaere5>^N>FTYJ1eq#NnQ~q^r?FUW{OPzPf z|FEoozDjZd&qwt>thDie-u2Ore}3R8)odd0fdA9t|8@zl}*>Q{U6%(|CoT1WFyGHJlGWMIs4la`DX$GI|Hl-7Z+={AnLzQqW{y$n(3lqi|9*%+$3{fn1;a{4^~&&s#Q765 z^-k7Rt@^G1^_oq98G*qrv~%iPYbv{th=hpwFWgAb{Ej;o;Rpk{`23lV zXK$t{SpPP5|6Y2(z;TE@;YZjcA)B5R&X;VR6f_z85Y$jKZ98wbe|HZvB_K8#eOX}h Q1o)GBEB~fQOdtIJ0XIye(EtDd diff --git a/docs/user/ml/images/ml-explain-log-rate.png b/docs/user/ml/images/ml-explain-log-rate.png index c814ec50d6774e81638e85e50fbcdfa8a39b9097..be007b22e1d4cc26da7303b7ecd62b5ee868a95e 100644 GIT binary patch literal 144957 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 literal 129559 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 B z(5?f19@YCEd5hpOh>Q4xbSVp?28z4>adj4IAe>& zroyW}@G7OW_>N*OX7HCNQW1w_I0jtL`&!upDx6Fk0||+{%iSJ6@edV1{%CvS>vBcw zH{R;|&HmcffEemGRFZf=5 zbCG-@&)h|O9DW}cZt@Am=D;1LWwVxSf}5=N$BzfXbzP4HR{)Lx13}%cTc`72%AE>O z!k^bHy?5gI{;i;)&hSce2QUfI5D9$={p4;La`?@_#?5oc;d%bqdQV(bmeiX-FxZ&x z`Qj@(MRam;s>;P&YI1SR(6hU}xm@1@rNwI2Tm^swEH+lj&0`7B`_3HUE_;-dAihE! z=pCK9PeRjb#UbAEFT z-`hpk4-~6ZrM9Y9)Hgl3T^-89rd4mtFSg*fj)lFu41N35-XZmdRDad#%^-{RbrcYY z4PiQtXy-^WnpwF=lF~VO+Tdh8A+XyX;=XK;<#JPUd2VyPbMfK?9>&ETh@1N(9zv7J z+~_bYrd_APGqK=0qmkDmKPRQtK@5gv^_GuhgDETxu2LV72r>*P68OO_B{OBRe9lZ# z5@IOjg$9$ETH@r##^np7#KZR$iKg9V4x1*j9t-43zv#M~&y9P7n>h`12?$@*RNu#P zgM${D>>^9mTV%0I98vWi5-jeq?lRLnt)I+9B%4`%{(hiF2=cA*5nhuh>QIdqH|Ys7DT)mA;XG+H zv?ty>^F?}Nt2aY$nrikxp0=)YYLg~$2mu05uV@luhFY~j@^I=W;bP?yqN1j$YPY>D*7=AKascF}Ky1&?o1qcQwfqoxd~tOS z2MA0dnxOrP^;pJA)G;Xv-0^53W2e4h9(y%=BZlJZ`&6DwX0(;vVZ(taDW?^sQjMJJ z?yWZm2QwBEi!F{P@l3`~@d`y>w|WLA!KnqH*_TCj3ed=+wy0;mkcO{R-s~K*Sw%~* zI~|otmSznEp`nut`KBol)K+j5BwcNQ?)`SSf2QnXTS;6#ezq3c(r zb3eDZtM}3~jfT2ush)OSFZ57@4-T)>q_ryK##QfD3X-^Li9r=4xsPj(1k&~Mo8c`wI%}mgP~Flr)b_F>^bke zpwp)NwIV1`S*3Nd+l02y)TxYvv>BZSc}+xG0(gAB}QWzDIO-p|xq=_&{FiO(v%|nrs3*FpkcQ$qbpLe$=hS zN3T#XNN8QnOx_P7m^o%KQ>ItMAd?opZ8({uEK~FNG78%(lt&ISQu(N3@VwqT1a9^^ z?AOL;6#5blr=#fX&v2q4Xq2^Q+lwBnL$mI#0|`N>*1yGQaHu+ zmM5HnnqMVEG?M)a!C@&^yw{J@r}2E&Psjh!^NIItYb1wbSY@@D+{7h8}k!}^p9|kJH;vs&*_a8S?8D*<&QFb&#$r zM!&p%m2A?fx-sPmbnD9vqD^6j5rl=_1u(GhK*48=!VK#&>W(8yl11_XkJRM)I z$&OtR?cwfbf|+`ccziGi_D-~qi{1HG(4pL_>Vst`o&y&94M!Sc*x}2AbPkhV%DQp9 z+k!gH5z%%ZIjPyLgPEVL%%g|o`> zMJtmMksjhA`IZE^@8&-&a5bC=M;8d(#*~MQlj%A~JBlWaD2J-doAFXP4Fl59me4i9 zX_bVm_Se%At%|*V@U36lXi~<^C^w@I(eIHDH?T`SF3lS#SxoY}jTXTf?j^&?afR;9 ze~FL6v6Sv4Mkfb6IXdp-qMzN7i%ER?kVwSI^(bkz&P@!EWRBw>5pgWBH3gciFBt%= z#k`N|kDDM1nfcMXQ-NTtE_0Dj4GS+V)GPkg8Q*vpD1#?M?rZ8~2&zinJD+Gb3VxwT zSL{Z#knk(9B6x2fFc7>7!3#K+!ne_D-B8^(2b8GD?JEc|9wmU2_IB(%7}m%Iy~ShX z<(5}^JJ(?OD3r|TQYsawg87U5WG<^rqxq}q>$f**E$^n4(`>@NcTM*zWxI~z>_y^n zWNCf|mXUggG54kbe`@=A@1}QWVFLL`_{hn0cl13P`6%R$MZSi`TbF~fhrVJ*sIEd1 z$SqzQTRGK98ufOu4(AlqVsw=%6%b%Q8?5Kjy~Utb!@`9`_=d!MNA`H#Xvg&i!8eFk+}8pt!-h?~n(L4KkhYa@xjhxqxB*?zpq=&HAqU zz>ml0-5jzr$yIN;VhP1ZO|$8Jeacd_1f-$Wk`?4$9s!e(Rc6Qp9i)eHT~UGeVA4dD zo~z7URggA17qUjuI0m}(*H78^`hp@M{|(a0A%!}RJ8w;r>)=k-;#oP;73 z7-IVS#QE}c>`n4&>i2|XA@8B4*CsAyxDny;)9WupdV|5R%Gr@xS&cn5;Po3^O+vn^ zmgj!vbEfo}4mphpa@V>LhIkE($(?2ruZ}S*Q9i^$Kr0#32lPHcym2s|k*V&)dt;LY z%T;9r_MHk;rgt!NWGm4tnfy^VtS9oMjFt{b1_Kren!U@xbXLJe5Ce_|n&De`#PbDK zjYC*utBdV{y>-nLn1G@VcU+3J>Nw$}kH7duJwr%2D$gxu+72i9t?pHn_o_RwK%fV? zsA55rN^r=w9=Fw^7}E7d)c%L=N2n0kuvQM#R7|GhcYL;8s5x1f6z<#pJ0>_o2<;m|!xz+cA-q zzSR3|SJ1xumLtSa%2<3xTbYI&ED8m#4wNYcdK8)NcSx};+wN3cy3aDrVb~0Us`>^q z*Jlqd^8GwE>w*jHg|o_nV(RP5OFtJ$g_!%$Z+n9<;unLEzyKTf)Y0 z0MP=NFP#u>BOa+3&*f)HDDhkAQyJA1AsyPXL`zOJB;4e@6aNXAQe?oQdR{WkW` z40n(BrIcdc4t(kd-+N8Y`_R=WP4C@4?e~+y^eBN_x6HR0SD;avSJ(T=wfwOhH$_5F zIS&ZirP2IU0z=J2ercBOW9i1Edn0^@y`Y!b(rr#ZLwZ*Vr1;Nl__#fzRl z6bl*wJWq>goGrZ$Z5Db{Bwb=f%tDTcc&C1d%)iotQuV8Z@1=13v?yOZw_wu+VWW8+ zjdU4}#kuvO9n8y`S$){q#Lwk=sR{0KXo-01dAUrO;IaCW(J zo4lmc)y_P0>vsmb2OE5F3VJ>n2tg>pLXQSxGN>?S%ENXsv#%soBhx|cYP4xqdT~d* zgA;+{qX{_M5<75s5crA$8S$C?2NG_eApxWfU#5tcArv@BZxPA6ev0- z#JGdk8lf`A6lR1v*C!oMrW`#YmRdwoufao!f@smiGTfhdk~w>;P;$axH4u2*Ah)4- z8qW#S->#Rc!0H7Pc9I+Qco#JwpF>?A`jXK)cxb#i#$31KJzUn$kr);VTuWyq06iHV zLYmy)CieXl5vQogWL0a|i^uQeEsbW*@X+0w@Rj%pqUX$!!}rDne|Ty$k8h&+4jIxA)si0(baXvA;CId+c0y`Y?*#>=;V^E)_ZHngC^b*uEd-=%&&8rhXmw`L zP&5}#NJM>STB$+s`u0Uc`I~EKB{AqZIBLA4dz|&KmYkD_n(Oz**94^uX{HG@R$rVx zOud(YimSbLbLd$uWJx4h+k^b@3)U$mn#!6fUGg0TuX)aQe+i7xgfUbNY9ISZJQi7M zO?pb|8&S}Dh2G~_aiMj=;7dDfu!0|2MAj_n*FtV+X;=N|>DJS!EXDzZytLd72dz1p z2ppb+mEh&p_Ma^F-WHJ-g}7gxf-D%H)z>%1REcBg^7&AHd^yl8}lk&JbsZEBLvK;6BWkgl!ErO1-SY zEQJV*`!R?f^=FVcuL-R`d)EmcHHRzk&V;*azpUS4S=Xk|cNBX`dB>E}twd6EYhYNs-}DlXK$oD0xj*Wk3P?a}e5^Bqbs zn$7i<(1*Xif@(EPIW2)d1_;qHnzg^7Ku3xDY^EO|LPD=V>s!lCW;`}#F5gO2CxzIRV9TMZK4c0q zl;{B%!pi{~g$0(Gm3Ac=OYQpH#g^TXs=ANRUmML@`uLZzjFrP+mKF^fhFLPS+PZ^+7j zop&Q%DZU0gK(RpEyQ9ie`0t zr?j6!5hUWn5$GG&ZX-uIg|>=kze-;n&1Z9@vtDUE8ZmALKCwSR)a#2`yH^TT#Q`JO z56e!Jt{_d_WP&5SeD{xf<|_EzUpjKGAhzCDEKz=)2O80HgDiV7Qbq-Uao9q z5%OsCdsoFyGsJRSMT?UQ#*{j{Qm3Av+Z18K)YV;&AcU;}hXzkEnT|89X=v#4Sb0~8 z=C&$5w83YZfR{RZ#vXQJsIX^^yS4Z_zHWHO94~~F0>3{33!gH%<^T+?`*MUahv|5< zog-q!#u{Jvnt;xvvXHTn?XFFzceVPd%BJn8na!5**SGdsPD;tiQoBWl$iZnmYQN>j zdvD|HMCB!sM_9KpRN)S`4QyQ#@B=nC6kq_+;y!kJ4Zf_-EkL%TiZ8^OfWAW~dMhC& zo3|wAtJrePg zbx085wO;O7W!{#!hk~LLDXrGhVcXPa2L$}z;eTlouh%_SSi#7j)EU5+RF7G(aqJz9 zN0YvIIA(Xx08%vc!_dFmTfbvhxeFV3e`c`y;e1&<7%pA(PJI_&FKPPkECl`=)~v^C~! z_L?onABQiemggQ#N3gl5y;X8pU6fu8|ISB}AaQ|1t$;Agq)6G*6DC=*y8{~G(NKa$ zAlI(YaQr%E=d3Z8H?RYaHH{6kHU=>$jsdyKngyI2+H^HHzx1ku=8Yw!SYq~Vu4RNo z3~4gum(rH$#7h@$z?|eH;Msn`M!aVOUKy=*2L2Yz{@7;tp9#II)8RX=zn7%)OA<|d zlxBW($@0&6@zZsVc8`=4_5aaPXM;gw8F9Wy&1-EwOjlY}7AET(6%37iCoqN@`(H+K zt35b84?~*X$yK7B%h~sRL~&FK$*{ZjN*~qnbHLf%bb(>~Z{OF;4b_X$2NveKUD#5C zqj|sabVPUh9~^F=S}1`R_mkwN{{JUa{TKbrEtno%ecc+ROi>>HGTYM3Zx zk2lWz{}d$vYar!S#{1teo6L2R{F7H>{~cEV{+G4-7Zdk?BYYYnY)~exodJIAZv5*C~+ z%@_()5h6#Hj%}dNx-J?WBoe!Q5udyLR~NwM#nFN5NeblzNMA8MFZ(;0OI!*7?x<}c zx=|=CI>JG>m@L5eilQ-Y%+Zyc6|x3{ze5CW+a9VHC%<@cF!b-{Zx9Ul(d<}s4IkNO z!O_hkL;g!6rD;}l>uJ+_o7BcL5ecRDDh=`8ElO%f`^v@j)Ac1di}d)3{gDI*<~Hj+ z(YDM`<`+CPC_95v@{B2HGbsn78I=pNT;f_K7M4+7i^wV;IA`e{P|*E=YXJE#Vtfe~1~5@)X*i$e=?3QSb`qvky{V z*?=vWNm*zVhSgxxNG3Yqx*E!8IM>)wtxw9Oc2YhBOO&s0%HbPx7^TlyIXr!W5g&TI z=(SI{Ic?nnC3h?J=M=BD%HNmm2Oj+*FBgZ2JBTT{v{Q1zC-&YU`vU@L4vW*j`pb#8 zUn)-p?snxb47C68C>Gt2HBIn5S+ zuJ>r$Dq+ibWAYXi&D>>47B3ap{tI?Iupk3Uz`$gp0-xml-(%8iB>+&%KD+15X+bq$Vr(G23_n$= zorRA$d5-~2cfJl{hr~#VI3_N=KsV^bOZG5NO>@~OQ?m*v_pC@-gsXJ`B-<*^2Z@7! zBR|V8$PZS7uTSoLVA<9zjQkP)j#NLSrQdQa=VT(N`5f4se1z?1#Wj!I3F5(+c091D z!9kuP5eJUH5pC>k!BdT$UkhinmoTLiEZP8lELlXf{oaHtk=ac0OH@fOwG%**LOY&a zULc>n$&wU_WOn(Pa<>Jr-G#PDXBU@2f|>$RAo{(TgOLHF_5E=01@7_a-bMkmeW3d% zD9+$MBJIToV>I98ecYSR31u6(g~PmrGpxxEHw5OMFNn(Cd`re{;}Hlzd&KV%(zd+i z^p+ZRAFFo(Ou+F;j7&P2QU=A}FA1C$dq=%puTF{V@-IJ}*?cLx-uR$frm^<+5N5avd$?<-EmW=LcLiCh|QX ztN!8(8%bqQoV3adEYzLgZoTqmt4TvoEdl&=+udIbwRsXdh{%hKog*#0NnvsH|Wi%TQ^ ztVWk7hLPy*@#aF{y{-?iSpDF1%(CU%clm-G;rpadza*Kxm8Jj7Z2ZID(0(dbj-D(S z3&~jJQ>`%#R+2IPAN)2DYg3ahb z2U%HJ6ZsBsCR4w-POq*KhOG=HFesm&4y66tX+8XNpfmk9@#Ks8hj`kM zI9`HDaI{bt?+w|?{o4D@F_zz^#&F2ddQN>NZ=S(N0ue>I)Jj7>t;6j{srI!il)ls#aFDxB@l2qX#iBOGBNJ{ z&+IcDsZb#=0%*VLNatk(hf$zovBLZ+UV-y$yE#Di1`&^eIj7BU8d{4N01Cp36{+_V z`y-wY$Z9-NN{74#8P-cWTe0X9gVb$*ekZ;C>DGVD9wGIV4T6RK(5sUC!KV0PcSRIP zht-mf5MNe9G~fzE;B#cf^UXb#KhHM9Ge-Q0k&~?5LLSydCn)>33%eLrv00DH>^&I1 z@gCZ3JdND~(m>y0-RB-4j?!!Nwy@g}F+zh;$tMn8Kp|`G&p2c04UPYi((Jsmm129S6m{dSp&XKX8E@Hp zCVmHVUM5zN!I3gttSNOe#O9Di!)3=;Y&@tFAApn2*O`M(etWjX&{5eJiYa}zGgcrh zRK$83Mo(Y{On#B<{;)7{;A{Q5Ign4|GH5q9Hv@osQby&kQ#d&7p-d{i&0?_Tw3<|d zPAjKErBIxwO=m;n@c;=r+R`_<9291UU-H>!`9imPbwmktC4Jlp9R-C_QF}bx+}T6C z`AUpV6*qkl)CTm~7%GLtHpIt|lzTEm50|=K-6?&Y8o)2L`YZ5WVp=BiP#K>&&nv++4Ie&$xjcwie!jierv(hF;tTgm(5D0DEre{mE5Nbn%*BI1Ly^TGsh6`_T`>>)aT6 z05RcT#n7ElhS%wBa=F&;k7CXN7$*KeR3D2+w^}LH0F=b{h8_NGD=npb{`fR|Vd;(O zZ23=HbcXx+cxvT5pjwaJ3dk*8oE^vNl*+{2+k47MiN-vp+Msx{n+Y!}V1gsC3B z05_n*8$)a2>{d?jJf_@)T${Gdjrc`_hpyO(o0Adx69XEyzL#&MV2ckVNi7y~MwZS$ z`$XP9J{k;NiB=%+{g88nfX?BRafHgmM~Zli_IMmfT;+O{sJJDQh60DNYEaWuy!;rhsQD( zeDRmr2M03xO<5Fb->hETij9@~4*7}iM}j2Z99L>zKT0)VN^*apIGJ%1mhU`tlqvma zZf>jm83#JAzXrBcod%+%Ks-?h6Dm|9 zL}d+hvz|rE^|du5bO9>S+#Ra)6D_SDEJ}iI-X>oeh{L(O(S;jBB&?FyaZEJ05YO1C z;ErP2C?mq{=GDK8ky$P|Bi!ovA%E4-)ji={0`#agw%=78!oehQwmwPHdcoKdzvL=gES5%=TF==Fmum z!BuKvpJy!|@BB8fqP*O}WqXlD6Nb_3dYBtZLcl*VN5qj);B1fH%!QQf*eE4f5Pxx_ zb6X5XA+2s$Y^5*eb>H^;-P7Pb8`s&(FhA4lTB^t3R$HNr z-!G_3-bxGpCz9~X^J)}=J0u%^Lz>-h#Vvj%?;54qE0aP@8HqC6%UZ$68uN;8>{+q1XnMQ-1Z}vCXROY1 zLW{kCs8e>h$OD1-@0})pfi+Di6zW?|7}ww7LamP6fAX%k`#77~pj_|Hf&YD_{pYxV z{FjlNIO_BKEkBKPy83hPgrFcQVEdQpV4$gkqeaPX*RfMcY0P?lR)R~H%qL1>}YL|^XXN^tWe{9zw1mgggdQ?hl6CPdsl&JOJmkL;v^@wFkMB~!89Z1op_CQ4?KEYM~ zvkF*1+L^~Lbw63D`}a@x-^VtRUf)GEp215q{^=|_O<-hLZ5A>D;Qwb^^>58D$P8Sn ztzT55TlYWre^?9hI=RxdcEc^r;n(Dpsa*IVJV=DVQ8S3!;E94{yNa@X4F6HxJR%Zw zea}nC%GnXf!XKOKBR;N~c2K1Z+orRPofq}Up{O& zPvdGHN2}&A;fsCNjHNe~?g*T>xf+E}`=AWEfJQj`9_;nuXe^PPtB;Lp-J6t4khRJV zLX)cN`Z)Fpo`YH6&2AHnCqi3gTa!+++Q1>{F(UwdDjB>E_;?>nqHT`m5(Ku zMNEFscD+gR!wjxP*DJ#_GngO9y}_s62s-g5f2(+|A&zOlJN&HKc7hM^zKi&h=wmr^1Hyh%)G zboakjuj0#dF2SWdI<~uba7etT9eXs=x|6pHqfEy~36cjV`gXX4QXmTe&9g)`DeSH%Qy^+R{t(X$Q>b_md#2jux1oU{xfsg5b<+8nahtFMW-bkizwpHv< z2`FPbD;skWLo8Nz8^g(VGmZ|=xrjpHPow*uTI3tg*Gvht+Lyz<^V%66$;@z8bzkm> zw-|_FqIeIX!*0yb10L)6JvUS7ej+owa|C18bcV|J=}V+$074w81BNs5w9c>uL8aaR z;cR;Zf}WmU;(kjQjVkH6$v60@vDM_<>gIYC;>Ps?dbu9#ky}v-cWkxvA-{u1E??qw z__3jbyY05`pirY}ohh+D3>aamh^<$s8%(4l=i>X8Mn%>NG78pLAD?xXoN{cgM>T^g z(*dGFp;YF$X#0xb0~#Po-I%PiYAD6F`10UH3@0;YX*5l+TZ~D+AzY<)VQ^m(Lf zb?(qtHh*^SX41yYE$^RX{1U~tM@Rw{5<;jt7q2X-YP`2bk-l+#}*nu^fzi zV;0Jnz;e*w<$Yx|`YjZY@BmI^{mZE%6Xffa?weB{zTv?)2-pFDs+Dd1(?{r&G@fCA z?b+1c?wRhJ&EaH-=fg)#K(g*TT5OPQC`a5ciX3hP7&chnH<#X_p`mp8peZbhD4q=b zAhVgm5V<_DUDf%Y#6me1i%zn@YILa?-HT!MYh;$dYeGPKkK!(0t%L%~fOvsmxh$|q z(oCRO1-eK&Jw6q-xH)Hz6%cGRuELb6RJ{hIZ2ohW6z*xu*Dueo7awomVBU~YQF6uO zK)L1X#S$BOfq)C4+RH{DCJty_U`~p6RPoenX&56v_xFpfPKqZ%K?BFW=fg@a_RKG*4t2<+cWgdv1eHJ*3}tT`DTZM6QpQC!RP?^ z{k@d=<(6xm+mPu-*UNAC*MVPG2=1SjBg3#534x_#WtnmU)+ei#VcoWRcpH1#%J4+H zrq?6MEzrV|xBPd@QsIw8AFynGG;uF0&-y~_-x*nd*awCkI@1y}KMh~prl4|ix9MkZ zV&MqNEH22F=Lfi0PyC9C&$el7&b!c5arAJA4rznY#3^??yj^|B>H&cEMnVJ5czQF~ zuPIY(V6$A6U%@i5QQl@vH2bkhs$9DT4OrF-W${CeR|#;?C~Oo!lk2%B17$v%O0Eug zG%ADy`6Eg2+S)uNm3m=6>&K9he}omc2c0oI+@dy~5<-hVj%Iz`z8Hv~z{7+%(O>t_ zesJ2rSQ$t}RX*Vo6gnZf$#mw{ygka)dAoEMXW{Odi(%YhL%XDI6?G{LU$t;-#waMTMLa= z?HzC*OtIWH*=|o6xeG_!?c3%(!Jv{8i_Z*0!@zU_NS?z@$MaLc7>m_P{-fv7?Hh8b z)QRliRL_YT0^6B;0hs+9DIAFefz+v>g*?ofZb2WpGuTp*72w5jL)%`w*Zea zvdge)@?L~|8}nsiIENHvQ*HG;R`*4&!vims!wJ9okW^$Oca9y)mwSIj9c~clGVk4_ zWGW>asMat5GCa<0gJ$fZVTz3PpT5Wl-n`vv)8cN&o~B6M6!;&zK-qa7N8u^f8{CvT-{<0(+DH-v(Z5+Zly9FuOJ z5zjrC;^(fKPDZ_O1sJRIugY!Ur?@FpgqW^*wqPi+oTAILWAyxb^?v-+H?o#Oq5iPs z4tw*9s)E5RD&@&y)ka+s@eIvb=eWRQdSHAK(d>`1j>qzZ58=JH=g8OEECJdtle#Eg z=!?C_;OS<;@^H87M>F&$JjWkfgAkP(`eTJKYBr28?79yPNIwKqCE7usfCez!1%hR> zKq>QkbUycbQD=NNaPNIriUgv*o%C-yAC@FZQ-`m)d>5&n+MAz?8Vr~`xYh%+_vG}) zPo8ytje1s{EJzZw1yDcxw_Kl6e0)o*^z3bcS+26-jM4$!BOV(2^yq2|7qP(oNhVK? z%UvF)5HjQ$0snh~WJzryA(K`0Y=60?CqF(?xkgiV8S^Gtt6cBdU4SO@9I7tA5jt^- zB!}m*PkZv=L=*9fYf18xzwwx=mxsISeu@K3RLV)Oc;bPol1t`Xt4m2b`ol(KT63A6 z4H41EjzD`)rnh^g*|qjUhx!a1}1x+4qW3;XoEs)xZ}%vlFhGB+hMiE~=v7U06Y5e>SRhwxooNONYPM@_%-H3#^1>>E`*3EJQ z@nxNmWxnC<#5yT;?X9+`Kr#uPnjvdx44$E`Lp3C| zRH|@Vs;Y#^ZZHAldY&~Aksm8o?dJBSW2Z$brvoV+bl6+rdIY*!IvAS+{!t8i!tWO%XR$5V$m_|_R1|yGvQuDy=RbS+sj+v z)aIJbHK5MLZU|^45z9qB|0Q2Aw&p}y7>57pEkWVD7R+Mn7K?ig)otD(0%&Q>8qnXS zF+MW>3K;^RMQ%`H#;RzX%xM6VL?b*;T8{ZQG%(;J;-vZ86I1p zPx4cWbt!c=5E=qUwACivux<6$eZy=Z^A?`%vASW2Z;Wie-V!jYz~FI=7p&??Bwz4w zwNM>k8E)77Fq6jT?a|Okg=Su7wwlkM<%xL5t#ZGm%Qy2xuhA$m<_LP56~sDeJUqiv z><^1EzE@o`FRz}bDsjK*-HGIHpZ$w|K4ooN($g%;T%IuwXIU!$JG$vK=@iYGP~9sbbw{3~3| zLtZ5qwcT`nh%jwsk%O}R_73jiWD(W#@e;8e`w||g5zV1}EQMM~%N0*i3Jem_gTAnx zq!u@`Eq>JL^W^EHdvmdH6;uu-q*qlO4gY#e?St!uHHorYdmN?ma!_B5M#d&KN&ad; zUSuV_qERQ2<6Lu+hIDl?W3TPxO`2d*OvC8(RgsB0$=FLX2_YY9Qil!<2Ax_+G85T* zN$k+PZ1+IJ;9{B$tnp`g_ei?a>e<9YLp@e3fj6Gq{Ir4a->)}>QXrEC(usQ*dsjXe zaNl!Y@Njsy7RhC*+>v)YMu@K}O5x0G=wQ>5U&nGbUIZ1o3bQ9V96T~{&tSec3cZ{E zz{onl`d_$uG^sMDsyKhmvUIjuY4tzxypeq~L{`CgPf>w=esR_l$s;M7GB!GCbEZQ$ zWNNUA>Ov@zIBLs87j5gyY4t>OGgVwppwV+E#mpRcxv57=T;9CUvRROkZ+a>?+)e(# zs(J(`GlE@#>hC#dzE)vsq;f}=f(Uwo_$^ni1@R&qlD@BK)U0uAtG=_IbqlxOof{#U z5^E={vsA{6-7D7T-rF&#p6f zrd1-+t0Ka&=ddM0OH|aqez+C?B~r$K2oKj=;QrbatcSTx#XM*$D`=buazwpy4x1Jy zRZLwzU!v&RGsfQgr;;1vaj1iT)tiLq!9ry};wFqBFS*HrtQC$S5q;0FLp7b;c(WMR zrl(wm6t~6p6-KgI@*GaK5Yk})zOgx+vuQg$ena5cA6Jwx_-bB3d1fp$bnr6w%MX6F zp2QT-rho_qqy2!OJh+YDGe;6@a2#gy88;61`w?Z4G%EB>?uVzxH_fy4W6;$NnKVrg zx(|`;;jKVjaX#&g;bjb8sjLChTt)l4>~g~{_Oz-375j3$`obLf3=7xv4qR~bnp|Pq zPfZg>%Lot7otRc-caK{@PHf$ew-rUo{7S$THX*6)NKy}7E)48ZWM*j94+D=R@&H2E_cbyPt3w-R?zk4dY-Ja)X#KWCR@nWf=ugzxZk&@EB;i^)XTU?ai3;?coDr&vi8Z3B5zWKF_-CA=!-h@ z9VS;SUhZg>K`OXTyw>_ho*CjtlL;Ah$+?J%lVX;+0hDhOh9y~hI47paz3-ezq}z)y+7rKC#hxS-LUE^a71i~RS;fn5gDxs7iPOf z%g$IH>P5fQ1Kwv%G$VL@XYlYkra?cjoo1*!&&_R~VyeZifU=1MuSl%G?RQaYEL6p#KpLt3?3iGE?nqj4DAub-7Nd^g{Q zK!LRk<#=G&D`>p_gnTYM6yW?>weX?xC5ZHN<@YZGi?W$+BOD*Xe^R+uwZ!)80LAgb_jz3WiKlv&1@tQrg|96AfjbwNVr zTz+DE5L9^1R#-JlTT8Z0*L;PR6OB*ULr2s>lLXa(IvJ7cbd|f?F1fd#MCRnS%da*= zRTRw+l4Q$@cf{Kac@dw7B}Jae4K!*!g`y7pX%NGAU9nZ4bL@^P#|TpH4u`}Po>ru< zBEM=qBEYzX)fLcZn=;p-snNQ%my{1uk`MP|DvJHAflW|W>n|>^(hxMoKVz|Y(8LiYE&<*>7o}I>af;SYe?)&FT8@_DK#?RFRZ6XVLw1VH*7Ux?vk>W% z+VJ(JB+D4pHxc)Qy8Q?O?!!f5i_9;2(*7@dM+89&ew4!AGiODNy`!Q@AgGK)3l3H=JSeyG>3$<1IS zLQs|H*;HRe?Iqp^=>2{mcO;D!lIU?Vq&D-eA$O3*c=T=8J&s`^xS08?V+^BwI4jpn=XGb4df zG-T<8o_i_sbp#n!7cd@=*gkk|-XfZqzYG^G8ZcEM!~6P1Om!S_0D2G^fGlq|4mer< zmB+b~kS7V#)Nz;+i~37Wod8nRuXSgBVrrlC{T~OeMnlAHFExa>bpdy#XrPMWkNNTU z_fhFgbMzgn91FM&bvKK}blx!&n;2eC702JB;~&f7uXkQ#=bARCZXOQppshhWeVPO^ zqHphx+%2JMGUre-tx?qfvDt13QZOu&@aIxTG-^YHxI^kqzwYFJ{MtWWpcmwNg4dA# zmfi%UsAb0I6%#tCh%*>CxXFqS5-H3U5+O#vdl>(oCI55mtPA<@_y`nTfhj915193Z zD~IC<=jdT#Vh#x7(n`Ih;{0dd&I=E4XB>HV|8YB5LNMP~{y+-<_j2Sveb3(u6yeUI z)#94#0hgBTiGOU|i&BA!qm0?eb6PI)k8ON)HsJ}TB=R5r>0ckhS}kOwLcfV8HgniN z8Ek~*fWa1gpzU?}cdzE(_5>>}a1#HUdDmHV%^GaR`aj$|Tojcj4C|9(QYuxl%z3@Q zL87;uEz`J{Cy~4Z?&3);PQyd$lcO5xDFySZI>qw@pYOY8Y6H#INYlt^T$CCy%&bN; zhWZZ+ewVMKe0Z_BZu$*p|NgORz4cy=*#_T4JvQ~{{wPH&+(2T~k#=&rauP3tVgTcC z?Gsvp!VWH_{;(IikQcGgvP7IhDLcIeN9O4oOTTo!7O*AgN5C;VUjp{^MBOjTM=SY* z%L$^ji@kDz>tQlD9h%f(&=26+M@0cwNOYis?*8xPe!uvkhaITlR@Hxg=l>>ASoZ|6 zcI6_jSu|C`c<^Liew~mp_^b;`kUlFIhRmq!<{jmq`AFMvS(kng`)xG|aI8L+lcvWN zEY$Q39cI|th651f$*G|un9)ff<*K_}yXlGiR@=ltsyE=ZF@ht~)ACz);&URvVbY|P zx{tN6(Uoic64AsLt!{s84V8-9l4TW*~)#pZ&^wd)sql$iY>|L%vv9Rhjuu{UvP9K8{TZa7!wyToIL#Q&-7 zEraS>)^*`vNeC`MgS%UBC%C)2yA#|31b26LcXxM!LvVMO;CGO<*4f$noby$Eb?fqj z8dY=5Ijp-!_haw5jC0pbvfn2qW*WJ;4m~Jw4<}~EhhsOXSVwa__)o?n+mWA)KTlD= zYkg(9_&+;uwR4_ez`tV*=Fz`O+z>hPeDi^%(rDm!*xWxoQMiL&`&TwTF&;QsEca)1 zWf>GqnMO!U1@SvhoOhixl;LA>tBeH1C)fr`{FVUc_LEhCLe5!*k9tiekDe_u-=Cej z*@(F}*^c|Tnuf-G&td69<$D2>rRdH!2dVfDctj`XSJJJLZJ*sQdj91e;O@sGi2kcl zzixCu5uFY6LcwWJVzv$4HK@UjTrV6$n1#75=KDo8uk!&FP5n~x#c2JPtcTyM3hA&_ zXjeh+2;U3ihCvbnmFvT3Np{-UH_l6RkR{V%KVAN%B>n3UgxH|*sb+om0Y>X+DglIP zI6<65AiKoY`>MF~IoIF)n~Uw3V@eqi*2)dK5bD#;UmnnhuZu@V`fthz!USR$7?4bnxW`{>4V1>g^-#v(R+Wvar@BkO_o@7g#VU=)egObO~)^ zL)Udmr`~6`aH}uGEqy=`-)87ese@Xd$1S(8dmVMrFCf$IplzV`zHc9tvk#0f|gW1 zzS*Q-WvLk_q^mZ6^XFh#qENkfp6eZ;Luhf^L6~)#TEzk4gaT<-&7Kx-`q;rT)jRI9zLS8SXY>uW;Nlz$isyDVR7??`*$8mEU-`aHysg~S^}ix{IN_` zhxU@uche;@3R+eGWBLtSbbxkg)$_D_ZCofrDcrJ&iv8U~on-B=t%YK(sWgxaW%BsP@6C~l1J~*%Nrm+~;*yLm9}u_qqr`*&i`tVCp_VS|1?~2f zyQAThBnzmiP>}g{#%`BpkL^h^g@0d3ENi>jifo$|TFdQ@(WQu&Q7$i}sQ|#%y%~z6 zwufUoo34{5>ZRbY+JJ1j6c(EgoLn;ORTTA3gC7QPm-lM#?>ot=o)<4Xh^(+FRhmEn zRta-K{$+|h>~-~h9^6r?27<adFX!yFEH$Avg3e{*aEy@g&8iM7iEF z8rv?!m%(sEu+Cg10`H3pL4eTTik5&m@UE_|E4%K9@ppj50JMq5w!Kw*T^1lt$ENFl zcM*+tooEjar`Tyf{__6v^xQKF)E#C?X-hRMw9AFPc}eg@cE*5!)X z6iYSz%lqBRH-UmenWH=W4QDddrB%oV^A(Y7V+Ec7s#c&}`H8;=jcp0h@pQ$##wj0* z-f+ar#lf9cqE@5_(I&E1hNR*FajGfY^{UsMF&ZdwO0?8qgLJ%l7*bIo{cF0UY#592 zp54inq&K!$snTXj(F}4*p>;5dXew*$h!rY^aR3I3+319CIj>oC8iCopuUxonQXs#* zuH^+NJ+(8cmG#lKG7P~^@KyKlOMs`Zs}IQh{xM&-Z4?6`Ql-D5h^M$A8cP`#O(LZh zoyz7exT*|`J+Gva*Pz_({EtcXJkg6XHuB+)4}vNy@G2Kzt64mjP75ssVws8#3j>ge zX0B(f0V%3nbfgLHUC*Gt`H!r)K<#r>$^@-?i8RO_fsg3`1Nhlg9)}v1dMYgq+eKE9 zI6fTvdS=dk-|s0&=hJ$j@J6=3Qfm_7)Jru!6KK=1pZeak3 z2^2wwMk1E%3o^LGW5}lGQJ2;o_#T@4N+9)4T2K)g&+QoD<$K7)eSQS}QgI0wBDv@R7MmG?B z!I9bJCI={@pkyNfK++Kk_JTDzsLz2!QBR%9u1a-metDVl_jG%M0;IAJIi8?D8vT(2 zNWO73gsgXv$qhYlAy>Tmt`IC^8QJBh9pk#$2eUPpIvl`vV~%q8H4v5JvS6bWoq)vz zK<8UIjDVa9HUa$SdJnyi&#NEJtv* zJ~=9+-SroIuQ*(4tB{yODQByFw3fu;(uMPJHNmGnwn4U)?`8l>=g1BZ9#AtONc3nl zIEmn>)$V76Ul0WqDys(^&gJK8`g1!E*-sZ}e$;5TmmijkI$%*5(q$o&GF0i6?VX#0 zGZ2lZ&#Jkn;PXkS*&Z`M@8~I!NYTlo-mzx2+nE3+GUrhgN|LQ9`P~l|)(WL`$fz=y z4mqQ9}Z4igrzbbnha zU@me>CHq!BT;y4mKbY`?;L6U2a{F}lNscp;9BHg&7OYUtX@8qBdKa5VFTEw9_Ub)x zXi2b`5>?#8x34dehc2s8_PNAK!Z?bG#P7nFrTN4Zsgi{CRfvi>iYXKbed<14Tv>mq z%CQ`X?7evTEazgSK}ZEmSItK*djTS5FYibW-|`>^atL%gaB^o|XFo0gESaffVxuD@ z(QYDJ$#W!~U1K-Wod=o(4hg>@AW9bsQweANT zWMp4SoR<7*foZ`9`re=~l%iY;Vu5i~iN){C5R3tMKNK(hnwbc-Qi#b0Su7bS=vEYp zU7w{^FFE_UYDCBv&C$_OUM`N7NbKVr3PC)zmN(@c0&4Vgo*c371}Lbd8L!CLcp4|o zyVnuhiHC1-OmpE6Prmf$O=Z zj6b@dk!13Z#iSmbYSW;=>ZAE*9uN*5^2Di+9)g!Lu%*4i(U^W9DQ{wc(=kw%uRDYP z0EHn*th0TeLglu~pIE}_GNQD)DTa}_ha4}-SsV~du1ONKb{J5_he}uA@x;dFM=4Zv zEQjQJ^O#Md>Rejy<@!>pn^1QK?-KS)0utBKSd|&aBdK*&lu>PG%M?9~*(3S3j8R;2 zGDq|qql%QyVVT|R83QWiux$wl6N&82sMovM2r(t1W29mdGjOSm6fd)sdR!D3_;sEV z(w$;XX6(Xx4&Ne99G*4(PUa03LlUyP9{%c z_=zNMuN!R_)fQw7(TYD4dVZ|kFKI})QlfO`zk5Emk_YNd=DBTehts~bk0q8f2gk-M@RPhgWQulGOPZ`O z4xfR`N#5EK&*LT-QrVuWe#r7`6l8sdu%as(zn>UQ>BK*AaH!yewvP{Vy6yvv3H@dfNVrZF6ZlME=g{g21 zC^$Vs5~imkHb7jP*&AF!6#OtkbG~=4<4b&7vukz34AbKyh6$skd+kK9Z^2vpyo;k9V{V7vLIc z+4l~_AMva%BBerA%lC1eGk$#?QM%{IViMhYgb0o`QAeP9)5!A#RlarE`7}}HZshiG z?6iz+BKP9`#opC`Yy!8oJ@BZAs?6<torfC5dORp@0$KDv|) zK_;F;;TU0>>99P0qFk!TrWw1)|n1dzcN0& zf@4cVB^h@-{L?7uvq`~eF@YGx?Pa8fRBx0!Adx&zblI*5K()1c;jR_RRE`RcCSs@} zD-{O~E>BwR4-Q7R$5Cn><1NIMXTE;#E}a8*TM=rXwNUar3g0J(5Pr)NP^pgKYlQL8VaAYCLl^z1j*19KqD%C>f{Q*sK1TMQG&=4m6xIP(9=wMC|RD)V= zI<){pm8d1IU~>#|0JeA9j7Q%7wZ^jtsqo3oK9F!v8+c#i$ABr{VdWN z-TH9W6H6|pL$4)BrAu!^cTsCSj>EaixSo^PLI(gyy&Fhy^+F#*F;Vv#tPs?GBbPQ} ze{%>6XjR%6!@kH*2$u=6`36hR+LZ+wCkvb$99KPs7IYUWdgAIB>j=4w8wAa1L#?eG zRxB=-5s!f3e-TiSjbSwwY+!9y!ib6AUOK|M>;Amnb-}hK5r!hZ@f-SS#mCoG;+i_& z|MT7l+fP-?z#Q|rWlRnQ^Q9$76n^{H!^2^_jWcX~yUFJ1A`3=p%!Br(Cg3qkLBq1P z|IFlG8y+3ThA2pw>J>;TiMt4ed}F|VF^o%rBQz$1nN5)->^zD3z!aFcoZ<`>8!M4( zgd&l1lyEcGh9&zJ3qTRN@Zf()sCVt-x&AftKjVX3Vl|@XGLWoZ4RjAXS;%d?fm1+4 zkx>mqLS49)KRG4{Mul>@?;)BBm` zJ5P^iAWa@uKB+=nO^&$ELgYLd26C`qj#xU1#!NAzke5fAc%tupAp9ry2}V}XQEZ>N??&=m6q zHlB`0+ho`Pa2KHU>Q%dlErn^6BX_tI7M)!;Ub7Qn@CCp+@+kGkM}O{&0BF$q-yr=j*4DI>dE0{0 zuz2(l{}brFmWyVh^&Z&wt$&`y zzqYmEGpuzZ*8W#F4$HNg!woj8)ttJ^zmQihsYxHDvIpax=)Kc2kpJM`CcM6x8gm&g%1qqNfhlfBR{$ zHZP*APPED4%F>8EGsee>J>`$*&Yy)SohMOvrO(Im9y=Gzk{i2=0quLHVKW`@dGf;wbHr-;(H^GW6DF)d;%dFXJ8%jX|1cgfpy1@@D`Z* ztC}B3>g=6>w@1XpD@woDPW$j%&GYwDIqQNX)LLC6RG(MNXwc$@&t@WAWt@oNs<yxHa)TAtv7d?H+v2ghDj4(fNj1=Zn|oGC+{MN^__$RP!b zzp`qpAV-wz1nezS<)dwXKAje1P?y4Boga~eskxHT0>a3n4eot}J@fHKG$Z^n7#!ha z^sz?iE8R*|j6u8)N5fOk6KC&anaj~=7^|${o(KW7-uTDXP1&wW&SiWqcvkKYOZ|J1NEC6PXQ)x|Yrk28K(KDN znUJqa7vlQ042y~)YtZ9?O5~7=Z|kYPI=rkcCsXLrnV z=mSYe32gYSM)bPv04G+wdg`hW{VxcNE}^&n&gNh^+^~MZMxt1RyEm3~W-4;7!wqTg zCQ+-2#R|)?Uhzg5qy~E`c=Sn^?rzQtn4E0tKr&5YfSO{eDc5NIF6DC7_juR7=&LIE z!fp+((d-doFpPq)mq&uyn~&JmM%7uBlsES$xpt7mRjsXDy!0#rhS3 zj`@|7AUHcLVO4H*!9t-*d+0jQ?tE>>@T>0$?_6^RyTAsMlbg=CZ%v7HGF_vNiSZ0- z%|zr{$g07@-S4kNa6lKT)Z`Rhtvg+?Q=?5ppo$-Xd$8i}1TJj!3ukk4i)sxOg}Npu z;9j#n{uVRuIS0BqG`S2VINn|)Y8@&&%gG)Z2BvpQq+NS7$w4>`pLMa;B6JRe(R$ve zU~&bvA=IiJ%OB7K`T&(gH#ViX_#*M&T6Nsc+qk_vIlaQS+e5Lus~+k25=ozDn*d*W zfR<+}6j?s6kIUZT@t20iMgaz~wumEZR1?99K&ot|*N z7c7l~iX_sbr%YcOK}L<;)sZGG`kWs81FR_9cE5yF-IeXFJyp2(GJx{Oo=ft3bp?)w zBOqdYyWAc7>C3@NrJe)tf%bw$uOFgX=^1s{n-&N$QhPY3Wll8Sc(t~s{p%jvb1b)t z1(*QsiewBPhRS5>-tDRo4g-r8TyK6M?Qf|Oh-z;bmdF!)gS4V!d-p4fn&vqMvpfox z_Z53$JdNn9x$BObH3 z%p2;W8nAaBWqtu#c@kY?sm&AnK4r?ymPCM)B@kHbW_|I8`%$W91pR3mhaqpA@5RH1 z&Uq-jDarlexfhi{P&u2L~ z^fwjdFI20qW2AI29k%-V>kI)J<1@I=J2)QiZ+CP`kfdL@aJ+FmF{~t#rKNxgnDvIa z*YhX#{cyhWoZ7Dr3w=lt73|)k9U+;nkH0FZFIS$l3FYGSp@={82J*?gjP_Mv5PNol zZ^T+}oO(hKUc4SiVx(BCwF=D@Q(Bvs(ULEeg@nPF^(ii<04!D&w%evh zcZXI0Ns%Fw{auyrW7w524wPsGb zs0=epf`XmyGhwqiy}!HM{gT~Rj;Gf^OK@-j1Q=Tb^anD9CNfZgyf)5itDZZE{CESj z#$@V)>l_v=ue#rY4aHLgQ>l4OwH(fs2Wt$G8xHT3 zT07VY07YgJ-#^s7%1_QVAWPKhLGU{9j4xaWG!}A1UzDz= zS`SFW9t&JiTUK%!+h#?Vho`G0s+l$C#+jnleBf642g=*}9Jlq55&A&Cx>&s#u5H?t|`Oki$M;m6YDuG^D${mf7Fky(zc?{bHl|N3Ai=1f|gqA#m02+7Z>>&0Vo$96wfM719_)#iMI z2#Z9kT|7AxJc=H`*~z(H%oAYan*_`eNY*z!6TEz0u=rw&Vk_+zK2U15$oDU|I3sDW zISMHoCloaoja@D~N>SA4uG}sdeW`Rj<@z;U2Jko3#qUC-Vo4DShS5tls5RO``b5R= zq-Gdwx}?}RvdYsvQlRPfqpxIdBF6nqe&l?`!WmebZ*`^NaJdqOVhKi}szj-lxhC6N z|B@rU6VU%8xpyPHWd*2yf$A-K?HE_R7V`}v+|~j!C#7n2IwgqO`~iq`#=B$7Xl(kv zhN*zJgLCf?^i>6THVH{676)y&Gd6b})IhGcp5+&JzP4C<7*UB=ofH{GCkYOCPreR} zLrMvNTh4X$p@3#i^4lqS2TiSGO#$NV}00)Sl%F zRAUdzRGX8c&3Ms1lGY6yVPBG{tVxz^X9_d z$XQM$%!MnPv7l@ghm#w*UBn85U6oH4t(luQNA2HMv@E8w0>SNZsvuw%X*#plq<^JC z@?^t`o#T@7=WovilfVOZR_ISp_qT$8kp-c|*GtPI(L0>`B#)9x-TG_-;qmfTlM%@4 zIGjD*7-ddA;N8nae2YS(TBNXav{0>cv86?O(@a-@W*MX@P1X#+5ocHO$<}0Z)w}(s zR2vipn%Ni!b7nbKHwx#(BtGjIoln=@{6L@&on2qK(`jqn;$#+|pREg4mVShHS@#1D z`Ffr|`RbJFcW7yU1y_LnDWYO?b2HuW3DY>6OLxW9?Vq8Ti)m5=i;ev#(Rg8S&T>@A zSpGDKJd=(!1a95sYm*dA=@-cu7#u$`cO1R2K8L{sP;aG5?|`aQ{l`BYBLM!A)A(lp zp^$pAKR>TbE37$YO{URS;IY&&B$vD0>Sq{D8(Pt8;K#+(dZD#kN^r*H z#$z1z2vNHmKhf`aKhUQH-L!*Nu_jB;g5tk;ZF z81Np53X5K9Af&1#0c2``J;7!#!UZYHwm#-#Ybg(b4g}Q4i8(#icIQoE+Z~sS@40|4 zRhSmglGLCfDYS@d=SjpXstm>Sk{LWrY6X&Pw!OUF9**~Uk5|P{5=<_aCa2FGU8cbW z_)Dv69GaBRh6$~09I#M}KQ7#gFSVWxY8;EKX_Y2_>}#^fue9%mtdZHBLdD|S*G-ge z(>ElFQJ-nms<=m!%{}Yu3Y1tYD>)dB9SA|eDeWr#30J93bvPI?i!@Bk=;tU4CoiXn zXW>%nPHfs(o!^y$gMr6Fh}>8tE*nS2O8eDX;uGh3c#zdd=c=fBq2~JFiqN<`B!fUO zPYbdn|7V2VQbQ>Qqp=)-Aj+4F{Q!sac94wUB(-c73P@%wuM>`>br$o@j05;czHc=Q zOrlZ#kT&>90nxe4RU%V>mpB$z$0GrLW_~_HLhBa22Vr*xQUG%wq6_==|fyA5QD1EMjTN z)C|Khr>*cckNI=k3hqhZL@#)%0nN_VV6+-dGg-MWx=pP9WxkZl;dOME$y$a78q<+j z>j)VssW4myCbM~1&9ZEm1$TH6k^E_49eNqR%`kM$`YwPotZgH}cPfF)R6-*l$j2?` zh)06D&d?_>dp_rme#NTo`%0$ARLd_Lcg$i-B#JV}Y@o|W*;QIfp|PV-tYj&g3&ifF ze(C%MQL@hQccQF!1AYXb23+spFh0LLJc*d5d8wd%#(faE#Ro=K=bI4~f<~?(cc-A3 zxO$Xa`G*wsipsC?;JagKLaiupV9s)gz%hd-j8{*)?0;LXvU z+B>lY`VK0Mx{m3$dN^PUrvl*c3*kIBY-eW`k21sEkw?Ast~ctfBf>Ff9nIc=79;nj zxw)C3=qu(ieHgwux=*X`f-Upp86frq5@82q(JM)RKKH|NA}JKg3LGs}ia}N2r?J`U z{y@bdVOFMx9hBJF8C8=|(YHeC4*ZxA(6~Qsj`k0n$N~nkiOw6>i6&XnV7Kj|d#B?o z6w725N9lqnN68QED13}%$N{H695-s}j(=XIQX;;F5l6&ow@uqB&g%wHMUk$RBY!twHRjF6_dJKo#HM5_JKI|5e#|yC_5?0n=O}_=#4+lX$~ zsw(n$bx2(EB9{88$RopewJdw(T-8tynDFSTyfRn1oN)^mbF;A0FBGe|(nmJexX?Z}HOHv}OAwdVr)Iw8Bp6E*onWgGV}CIT z)wqjF;)*i#)V76S771~Qx<9HLYVab{TP_`)rq}kYxav7v>-3{5*L1&i+rk;!)a=_h zH%^#}DP)+qZa@J3oU!v;1d?%hoZ?mlgYars(+kBk4b$m@orw!UBjF6K|0K+uGX+zN z8e<@a+$q&Ji*NWKJI75g=kJf>faMIlJXx|tyZ7#ciEE|nDp80uW}Dzv()5@=dN5oO zjGmP4UV}!%$qQ*#4s^I4=(#A14eym9r=Ll^Wh&jx&r_LNQL0*#qq%`pl6r76X18DP ztzRql53LGE4b%?3g_(RpOWc04JS-^vWI-^vzuM1b;(r32DV~}2kvN>Cx~{@@mTEo{ z+BiKempIl>k6p0a$rik3L*qIU3qhj;cfQz~-3WtTdb)?d!zi5V-r|ey6Q1PAqnqg*U!OR7I(>Ax zY;KjLp7I{rLr07poRZ*5z#`Q-Huec|81RPrVRdaX`3t7Taz-;)5nuBMFd6BA0jYe8 zz^fRy9}ulV)Yur^8Uby@UT6Futrm>ra5Atlrp)w9=C;hGF}sCKyGGU0m<1<2$pwrJ zJz8I7A_2%>BgOt3knSLRKk$>l0Ip+B(=3RobX5*i@XN1X)6*8!t>N)r1Cv7z@@00m ztyHC}p-QSKDP=uFL%LPOY9iLPT}} zRC}UhT&CQTK)wAd%!OfU&sxX>4yw{HgVC;HTq)KfBTZ4WRZnn!8KPtxx;)rs{!6G5 z=4e;ZD9O3ODYWPHl#K{(0P(r&kC79eB|V^3f|Fq@L&wY&v5JQInFu6qrsI=K&BI zAFQp25aH?|Bv~@KohVu||H`!GTIlNNz8vYq5LpBlSURu3 zA4UfpFbxIJ^jAc?Ybwiuoq(Hk_OyXIKS&4*CpeTNJvga(PGn0T7Kd1Lr_VJWQmk^7 zXQgDNY>A||*l(*~5PpZw0vTYaeRN0jB@_wl z(8nvpGpw(s=ZEXfZ`%qYDoDN8W*)46UKn?>w~+nn!C%+BOMpmBsCjY?aBu5Sx_mEgd~~lW2Nj<;*G8VJs@SCGaWc$jrE0YMDMAr!KIRl z602}4oxhLH<1^KQ3t|8b_!i?HnJi11L@E9Y%N5yE1A#oOb zjA&>YUtz-pQ8M_5h_Yo~>cV;)**4Xi#B&8a5eG)fe<-4VGeB^G#3RR{YP38iZMOCG zEZy#kq@$3GM-%@BCI2Xi@Oo0@pw#=T)5p$kj#e9$95TP1HSUf@IE2_t-@8OO9)Ha1 z{~N>bN_=_mA;E)q%okOc-FU62I+p+y#AByeBI{xMgkB71qMq zuW55G~OLS zjw4-utq?;qo_ezZ7Ve|_W*&Ms{nL)N5?iccG{GDzT(fO0N*D|I8R_6DK^@&Jj{=}i57fS*Xz=eVq`rIjxJxF$3dERiX- z$puwk{+aicT$K`5T4|}YNEjI4bMlS$g*pcu1EWwCmFnkQEX(R??oUEH{Mc6MD{UO- z#V)ncO~;Ey>8T!wPKkdxRh|qK(RUpJ|8c6o{&%MeBD%LEnQ8|!pz#suL{6k7vL2iQ z58;%CUhg696&Oe6nGKqaFeq#EKI$!fK7oT%9WN!R+dlqe2oo1gU8vf5tLWq^TbTQ0 zNae`{-#A@z``2N7j%lNG7>U?-+s1-i9@a}`q`Ag&Uo2P0LtmmE!HP;LK5ob!2$0Ip zA|;adlIw&w?OcF~g+U+k&$}O(!jqoEbvCYzz&A;J-d7JdlH6_@95Icu&P&Pn-I<9Q z67$=*;$Fj!vnV9RcBwoASCbLv90`yHNW~w8`nkV<`j!PeqE)r0@RED^L*n9P{)ajX zEi4vzNqa+&NUuu-Vaj2pfHKdypet0^BpZlHBpwoXHb4v9K zKKH_2s**}bfmDN-zyDDB%-M#~oG39Ah8aIN30SmZe`*Md4oR*O;AA(B#4d(&9dl$r1{!a&d}Ny@t8DEww_4B75p)S%~t$ zz4l*1LC|Kwc@?M6;W6JtNM*W&%$Ms=7{&QS39N{=wnlJ{bx|AJOowRDEvSUEG^Cxn zFfGy7Fp=9n53qxw@ZN>y@)fn8%eq(y-}pC;l}i-M1q$g(y^--+>An zUxrMi+hMtmXRxrbvDseM#s$~bG6`m@wg?r5kbgPMBAd;3`@_+hTzq~tyW~C5BkWJ* zR`;Fv(0OClV`q5$>?KvCK2pRhDhY9XeaB^;>jCwMQ2^xchwwh2ld9gugTrtBYW_9FEAzFf zo<+S+;dC8iOVenxg`iM85m>0ol_@r4G=mx|qC4#Ld8f!N_1F6>CArNHz zMfLM_e4?uHYh2w@gEJD2!)YkMR%K-&G978io48(M2LOp>+9yXQzw{m?Yb+l?JXY&q z3*~aV{LuM)7WW!=oH>L_J%-8%HYpDgUQYw7&hL;gFp2} z@_bQK_5K)J%Xe3$>O2}rfLSD8_Wn+)(Qx#w`D!JUrlzLTZt4!HYEDERl}+(nNq-nt zb0n8LTgz;PrY{O^f9ypwAKB>N;d4nIr2_}>0#5&7_R(JB48eIpI$3TG_xAaosqr(8 zRGlTxOj?2}>vv9MTB?_F7tFIci(;8_$3lTo|3C`xoC3W&HfcM$e@+6f5ix1-9&)*p zO@BA8Hvq*p;cj+!qNZG7y)V}#B5(5aD5<;J1~%W|(TJjHyE_)xE2gNu+$0e}KW8=X z3xL8KPq&MEE?mb8K)?-CXQf`h!!nTcm~9phC!H;*V8#xZjV!jQw$UZQV@B0Hx&w54 zLUE}^>`$(^ij>N~70qmBABWdc*nFk`ZH9T!mo)**FjBR>|K){|{@V)!K_kVSYI)jO zoY4CCzHHUa3zjM<@uF-Ktgb4Oc8x`~Lqg_9k&CZ?_jAKnbe2 z=itlqd^dpRd$caj-~T*CV|1Ye)Z7J-ffo;dXPM>5@0gaVI(8&7?AkBI6f)2n9Ei)8 zse=^8Oj4lW(z7fyi^WrKw%#^(EH7*1V{z`VQ@Nn+;}>T;u8v!;Zy0J{I{FeMv|vz9f)Yq>p|5rJ7*ok?D;EpFdA_$X2U}M*0Pw} zRx-Zg{lHdSgsC`ZA#nT#o7I3}M;yo>|Gx@>4(FC{f?d@^=nv6B+ z;~02`jDM~ZJTktFJ&iX{OBD-ik#88(&ySCCMRheBmfGl+jsch>f({p4OPHf^yHd)?X2%$ z|6Bo9Mp}K#R%>Ruo(Gs$BCbTDiF=F7iy z@?(>6n^JOT*98cogqfnc0`FB2k9yArU&~BSe~vwETk8j8wR0!I}xP>uu+&6Q+6Zl?(chFY!C0*A;|aC znojZJY>UZn0?3|8rNCpIm_GmZ$3p~Hl01hxOneM6cR~$)2Vu8%E>1f09@5&kHf*Ny zQI#gbBQ4k5*KLt@QyBq+1!P->w-?=it4Q(L>)h(qy8Hz0)h#S4A z!>i;+HG_3URalH6liQfyXUH?h@5qr|-{`qtu1H`;Ol5Udv?9{}wcX%)iw*tk25vZ( zkaJ5>85(^l5FB3&xv5TUhV=0Hsy~J209n(;d33As-NZZz4ZstB6CpUYQper4USvsHhl7K7JtjaWI3*pM!HLg0c|PR=@I*do*UH z$~*#CbBQwT+yNSgC`K{EN5?aGeN;1MW@d{YHowkfrf&)Z?Mv0Jg)%XHWnG;~2Jz#(b^OelNyETF#OEqlo2l;~&#te#|7FHl z9{5Y}%tGZY8aq_%FlV)SiKnH?9PY5#SM^W6_E`#Kj+l{i+!?1w7kSDj&Vyi};5N5{ zoV-c3!RWVQrE(J}#Lb1xzr7LEVkN3uqnzI#Jb{~sDS*%q@;FyKhpmc`1P>4XjCal} z2Nu8=RLBF82`^3BrVC^i9A@LfYXy2MPNKj&qapAPK`LO#3*$zRLLkC}Q-DKA1V~Fr zBl4Rq=rO!DZFq>C*qElOo^-nX`DkxfRhRZv3Se-0sj30C* zpaWI`J*CM*Ooy&-wg?v5^x}ai-zSZRGyk-Oyte10F+a3I>O3qUlQ2D|Xen5DrAa6k zv||ft69@LKWJO8Qy-M3stCH2~+GN%QW$H&L~ah`(SmUBFGeK#4<`&&+IM)3(i*4ovE`0cJmL_Nv`2aN zK)EPzP&VUlP$>={Mu~|0E|Nb;h72WTO4oMPJo{nFi6m2&M1sCRmz(^++2@xcjCbmV)bT=3T)$lX~NwF|>K0n_M0>2a7?^ zC;DXI;zIX%vHTRP>2UeiQK76%rPQha3vjEE_b5RaVA*~|qs6g|?OqlZ!lCYUi^7M+ zo|KIHKjZ?poyU6&!D+vD_sSY$35%;bPtXS_R{5ytzKkWO_1Dr?rkU*NWao4z3320GF%F)|waH%u)i4u}2hvG)LcL%u(VX<`N z)>T)b;wrV7vTqHnVz53M>Hlbf-k)Vufjf0Jn3cwQ&r7egC1gXM5SXtNuC~43*t~Tc zT-#)sW6!vQhCgGoh^iGXiOVZd?%K*Ik1&<#9p)=2R#vr>7^`9v0cvbq{^xlISp#Yu19r(5|xU@ckGrUrJPz zZYhe(Ne$fm^z`FL3`ArXAD3@8QBhG{H+susyT6+;56Ej1KS54VsZ^1CLjTm|ZgjgA z3O|?1IcvbVJ_c6>A>?;@r&+FaOIfMd-}-J6LOEDYLvHtCo8rJ@BhC=)Q-c*CaIs>9 zGP(p*iZImKs15e?-1mZ?R0|sA^TCL3MiZWh;fw++Ex_Dn}Oiu z;ylZMuSE)PkUcjWUiw#S?wXmz?4sVwCu%D=r4z_?=ZdK(eE1-ilOHq*i^Zl)P7%KU zCR7C83>K4Nf#u^Bv`Lw=5Al513Z*13lDXsJJMB?r!Rcz0$E0Dt-`DlmC3<6Ou02+s z$sMt>xGndZNv>WVGb^w_mufm%&oA`)1LS@8@*g-&QoEwXXNSdm&#?|z) z9TULIc_XPOFcp(pbT?M>)4SS|k)ctXszc$Ya*N(q>a->?$H}+jN`t$NPBHD3EW^rh>rT#TS z{p%YW!X0z$Lg~k~Nmd(qyO1tPxW>9;oMBuiUs)C2N-p}vhROnc?{!rB=R00%;P5=! z@SRlYf=5{I{119ojQR-j{@CH~%?uxK#OcTNIkjpU`TBMUyQFOGKp{Q7>@;E)M#fr3 ziE8S9{pP>EZOrU_aA11w(zv`Ly@IQVAj>bZVsQ#Z9@%w;M1& diff --git a/docs/user/ml/images/outliers.png b/docs/user/ml/images/outliers.png deleted file mode 100644 index 874ebbc79201cc1282f0763c93d95dd953c1c65a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178520 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

    a{to!uPaqv+WZ?Dd?)1$y}`2R-&r3Gb-S6RH?_z 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­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 diff --git a/docs/user/ml/index.asciidoc b/docs/user/ml/index.asciidoc index fd86906f4b989..c58408d85d37b 100644 --- a/docs/user/ml/index.asciidoc +++ b/docs/user/ml/index.asciidoc @@ -94,16 +94,16 @@ If you have a license that includes the {ml-features}, you can create {kib}. For example: [role="screenshot"] -image::user/ml/images/outliers.png[{oldetection-cap} results in {kib}] +image::user/ml/images/classification.png[{classification-cap} results in {kib}] For more information about the {dfanalytics} feature, see {ml-docs}/ml-dfanalytics.html[{ml-cap} {dfanalytics}]. [[xpack-ml-aiops]] -== AIOps +== AIOps Labs -AIOps is a part of {ml-app} in {kib} which provides features that use advanced -statistical methods to help you interpret your data and its behavior. +AIOps Labs is a part of {ml-app} in {kib} which provides features that use +advanced statistical methods to help you interpret your data and its behavior. [discrete] [[explain-log-rate-spikes]] @@ -126,12 +126,14 @@ image::user/ml/images/ml-explain-log-rate-before.png[Log event histogram chart] Select a spike in the log event histogram chart to start the analysis. It identifies statistically significant field-value combinations that contribute to -the spike and displays them in a table. The table also shows an indicator of the -level of impact and a sparkline showing the shape of the impact in the chart. -Hovering over a row displays the impact on the histogram chart in more detail. -You can also pin a table row by clicking on it then move the cursor to the -histogram chart. It displays a tooltip with exact count values for the pinned -field which enables closer investigation. +the spike and displays them in a table. You can optionally choose to summarize +the results into groups. The table also shows an indicator of the level of +impact and a sparkline showing the shape of the impact in the chart. Hovering +over a row displays the impact on the histogram chart in more detail. You can +inspect a field in **Discover** by selecting this option under the **Actions** +column. You can also pin a table row by clicking on it then move the cursor to +the histogram chart. It displays a tooltip with exact count values for the +pinned field which enables closer investigation. Brushes in the chart show the baseline time range and the deviation in the analyzed data. You can move the brushes to redefine both the baseline and the @@ -140,6 +142,3 @@ deviation and rerun the analysis with the modified values. [role="screenshot"] image::user/ml/images/ml-explain-log-rate.png[Log rate spike explained] - - - From 477d97e6855523c9853628adc4936578ff71adbf Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Mon, 26 Sep 2022 10:37:08 -0400 Subject: [PATCH 14/51] Use monitor instead of monitor/main cluster permission for API keys (#141771) --- .../server/lib/indices/generate_api_key.test.ts | 6 +++--- .../server/lib/indices/generate_api_key.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.test.ts b/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.test.ts index 6d49e2e53cfba..18a4b28650769 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.test.ts @@ -56,7 +56,7 @@ describe('generateApiKey lib function', () => { name: 'index_name-connector', role_descriptors: { ['index-name-connector-role']: { - cluster: ['monitor/main'], + cluster: ['monitor'], index: [ { names: ['index_name', `${CONNECTORS_INDEX}*`], @@ -91,7 +91,7 @@ describe('generateApiKey lib function', () => { name: 'index_name-connector', role_descriptors: { ['index-name-connector-role']: { - cluster: ['monitor/main'], + cluster: ['monitor'], index: [ { names: ['index_name', `${CONNECTORS_INDEX}*`], @@ -138,7 +138,7 @@ describe('generateApiKey lib function', () => { name: 'index_name-connector', role_descriptors: { ['index-name-connector-role']: { - cluster: ['monitor/main'], + cluster: ['monitor'], index: [ { names: ['index_name', `${CONNECTORS_INDEX}*`], diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.ts b/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.ts index f76fcf41fa245..74559dbe84995 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/generate_api_key.ts @@ -16,7 +16,7 @@ export const generateApiKey = async (client: IScopedClusterClient, indexName: st name: `${indexName}-connector`, role_descriptors: { [`${toAlphanumeric(indexName)}-connector-role`]: { - cluster: ['monitor/main'], + cluster: ['monitor'], index: [ { names: [indexName, `${CONNECTORS_INDEX}*`], From b74941c4f97769e76d58aaf13a667dc621c3e865 Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Mon, 26 Sep 2022 16:38:00 +0200 Subject: [PATCH 15/51] Fix Entity analytics inconsistencies (#141249) * Add doc link to uninstalled jobs * Update empty state to display a dash instead of 0 when there is no data * Update empty state to display a dash instead of 0 when there is no data * Fix risk componenets on user/host details page not respecting timerange filter * Fix entity analytics page refresh button * Fix Entity Analytics Paywall and Callout shows up and disappears during load * Add restart button to risk score empty space * Fix donut chart tooltip background * Update how dash is displayed for anomalies --- .../security_solution/risk_score/all/index.ts | 8 ++ .../risk_score_no_data_detected.tsx | 22 ++- .../risk_score_restart_button.test.tsx | 67 +++++++++ .../risk_score_restart_button.tsx | 65 +++++++++ .../risk_score_onboarding/translations.ts | 8 ++ .../common/hooks/use_fetch/request_names.ts | 1 + .../common/hooks/use_refetch_queries.ts | 25 ++++ .../hosts/components/kpi_hosts/index.tsx | 14 +- .../navigation/host_risk_score_tab_body.tsx | 21 +-- .../pages/navigation/host_risk_tab_body.tsx | 5 +- .../entity_analytics/anomalies/columns.tsx | 13 +- .../common/risk_score_donut_chart.test.tsx | 14 +- .../common/risk_score_donut_chart.tsx | 12 +- .../entity_analytics/header/index.tsx | 68 ++++++++- .../host_risk_score/index.tsx | 48 ++++--- .../user_risk_score/index.tsx | 49 ++++--- .../components/host_overview/index.tsx | 9 +- .../components/user_overview/index.tsx | 10 +- .../overview/pages/entity_analytics.tsx | 44 +++--- .../risk_score/containers/all/index.tsx | 57 +++++++- .../containers/feature_status/index.test.ts | 2 +- .../containers/feature_status/index.ts | 4 +- .../risk_score/containers/kpi/index.tsx | 133 ++++++++---------- .../risk_score/containers/kpi/translations.ts | 15 ++ .../users/components/kpi_users/index.tsx | 14 +- .../navigation/user_risk_score_tab_body.tsx | 8 +- .../pages/navigation/user_risk_tab_body.tsx | 4 +- 27 files changed, 542 insertions(+), 198 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_restart_button.test.tsx create mode 100644 x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_restart_button.tsx create mode 100644 x-pack/plugins/security_solution/public/common/hooks/use_refetch_queries.ts create mode 100644 x-pack/plugins/security_solution/public/risk_score/containers/kpi/translations.ts diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/all/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/all/index.ts index bbb2991551f26..5a773d49134da 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/all/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/all/index.ts @@ -97,3 +97,11 @@ export const enum RiskSeverity { export const isUserRiskScore = (risk: HostRiskScore | UserRiskScore): risk is UserRiskScore => 'user' in risk; + +export const EMPTY_SEVERITY_COUNT = { + [RiskSeverity.critical]: 0, + [RiskSeverity.high]: 0, + [RiskSeverity.low]: 0, + [RiskSeverity.moderate]: 0, + [RiskSeverity.unknown]: 0, +}; diff --git a/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_no_data_detected.tsx b/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_no_data_detected.tsx index 3f406afeebf40..b492ee51e42af 100644 --- a/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_no_data_detected.tsx +++ b/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_no_data_detected.tsx @@ -5,15 +5,23 @@ * 2.0. */ -import { EuiEmptyPrompt, EuiPanel } from '@elastic/eui'; +import { EuiEmptyPrompt, EuiPanel, EuiToolTip } from '@elastic/eui'; import React, { useMemo } from 'react'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; import { HeaderSection } from '../../header_section'; import * as i18n from './translations'; import { RiskScoreHeaderTitle } from './risk_score_header_title'; +import { RiskScoreRestartButton } from './risk_score_restart_button'; +import type { inputsModel } from '../../../store'; -const RiskScoresNoDataDetectedComponent = ({ entityType }: { entityType: RiskScoreEntity }) => { +const RiskScoresNoDataDetectedComponent = ({ + entityType, + refetch, +}: { + entityType: RiskScoreEntity; + refetch: inputsModel.Refetch; +}) => { const translations = useMemo( () => ({ title: @@ -26,7 +34,15 @@ const RiskScoresNoDataDetectedComponent = ({ entityType }: { entityType: RiskSco return ( } titleSize="s" /> - {translations.title}} body={translations.body} /> + {translations.title}} + body={translations.body} + actions={ + + + + } + /> ); }; diff --git a/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_restart_button.test.tsx b/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_restart_button.test.tsx new file mode 100644 index 0000000000000..16269911f6632 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_restart_button.test.tsx @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { act, render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { RiskScoreEntity } from '../../../../../common/search_strategy'; +import { TestProviders } from '../../../mock/test_providers'; +import { RiskScoreRestartButton } from './risk_score_restart_button'; + +import { restartRiskScoreTransforms } from './utils'; + +jest.mock('./utils'); + +describe('RiskScoreRestartButton', () => { + const mockRefetch = jest.fn(); + beforeEach(() => { + jest.clearAllMocks(); + }); + describe.each([[RiskScoreEntity.host], [RiskScoreEntity.user]])('%s', (riskScoreEntity) => { + it('Renders expected children', () => { + render( + + + + ); + + expect(screen.getByTestId(`restart_${riskScoreEntity}_risk_score`)).toHaveTextContent( + 'Restart' + ); + }); + + it('calls restartRiskScoreTransforms', async () => { + render( + + + + ); + + await act(async () => { + await userEvent.click(screen.getByTestId(`restart_${riskScoreEntity}_risk_score`)); + }); + + expect(restartRiskScoreTransforms).toHaveBeenCalled(); + }); + + it('Update button state while installing', async () => { + render( + + + + ); + + userEvent.click(screen.getByTestId(`restart_${riskScoreEntity}_risk_score`)); + + await waitFor(() => { + expect(screen.getByTestId(`restart_${riskScoreEntity}_risk_score`)).toHaveProperty( + 'disabled', + true + ); + }); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_restart_button.tsx b/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_restart_button.tsx new file mode 100644 index 0000000000000..679bbe38c8181 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/risk_score_restart_button.tsx @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiButton } from '@elastic/eui'; +import React, { useCallback } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { RiskScoreEntity } from '../../../../../common/search_strategy'; +import { useSpaceId } from '../../../hooks/use_space_id'; +import { useKibana } from '../../../lib/kibana'; +import type { inputsModel } from '../../../store'; +import { REQUEST_NAMES, useFetch } from '../../../hooks/use_fetch'; +import { useRiskScoreToastContent } from './use_risk_score_toast_content'; +import { restartRiskScoreTransforms } from './utils'; + +const RiskScoreRestartButtonComponent = ({ + refetch, + riskScoreEntity, +}: { + refetch: inputsModel.Refetch; + riskScoreEntity: RiskScoreEntity; +}) => { + const { fetch, isLoading } = useFetch( + REQUEST_NAMES.REFRESH_RISK_SCORE, + restartRiskScoreTransforms + ); + + const spaceId = useSpaceId(); + const { renderDocLink } = useRiskScoreToastContent(riskScoreEntity); + const { http, notifications, theme } = useKibana().services; + + const onClick = useCallback(async () => { + fetch({ + http, + notifications, + refetch, + renderDocLink, + riskScoreEntity: RiskScoreEntity.host, + spaceId, + theme, + }); + }, [fetch, http, notifications, refetch, renderDocLink, spaceId, theme]); + + return ( + + + + ); +}; + +export const RiskScoreRestartButton = React.memo(RiskScoreRestartButtonComponent); +RiskScoreRestartButton.displayName = 'RiskScoreRestartButton'; diff --git a/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/translations.ts b/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/translations.ts index 4f389a4b2511e..dbb5cdfa87950 100644 --- a/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/risk_score/risk_score_onboarding/translations.ts @@ -40,3 +40,11 @@ export const USER_WARNING_BODY = i18n.translate( defaultMessage: `We haven't detected any user risk score data from the users in your environment.`, } ); + +export const RESTART_TOOLTIP = i18n.translate( + 'xpack.securitySolution.riskScore.usersDashboardRestartTooltip', + { + defaultMessage: + 'The risk score calculation might take a while to run. However, by pressing restart, you can force it to run immediately.', + } +); diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_fetch/request_names.ts b/x-pack/plugins/security_solution/public/common/hooks/use_fetch/request_names.ts index 523578777f282..2d6c414090367 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_fetch/request_names.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/use_fetch/request_names.ts @@ -12,6 +12,7 @@ export const REQUEST_NAMES = { GET_RISK_SCORE_DEPRECATED: `${APP_UI_ID} fetch is risk score deprecated`, GET_SAVED_QUERY: `${APP_UI_ID} fetch saved query`, ENABLE_RISK_SCORE: `${APP_UI_ID} fetch enable risk score`, + REFRESH_RISK_SCORE: `${APP_UI_ID} fetch refresh risk score`, UPGRADE_RISK_SCORE: `${APP_UI_ID} fetch upgrade risk score`, } as const; diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_refetch_queries.ts b/x-pack/plugins/security_solution/public/common/hooks/use_refetch_queries.ts new file mode 100644 index 0000000000000..64e8d10ec2c21 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/hooks/use_refetch_queries.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback, useMemo } from 'react'; +import { queriesSelector } from '../components/super_date_picker/selectors'; +import type { State, inputsModel } from '../store'; +import { InputsModelId } from '../store/inputs/constants'; +import { useDeepEqualSelector } from './use_selector'; + +export const useRefetchQueries = () => { + const getQueriesSelector = useMemo(() => queriesSelector(), []); + const queries = useDeepEqualSelector((state: State) => + getQueriesSelector(state, InputsModelId.global) + ); + + const refetchPage = useCallback(() => { + queries.forEach((q) => q.refetch && (q.refetch as inputsModel.Refetch)()); + }, [queries]); + + return refetchPage; +}; diff --git a/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx b/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx index c748d4d9a7545..878ffb6e5e29a 100644 --- a/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx @@ -13,17 +13,23 @@ import { HostsKpiUniqueIps } from './unique_ips'; import type { HostsKpiProps } from './types'; import { CallOutSwitcher } from '../../../common/components/callouts'; import * as i18n from './translations'; -import { useHostRiskScore } from '../../../risk_score/containers'; import { RiskScoreDocLink } from '../../../common/components/risk_score/risk_score_onboarding/risk_score_doc_link'; -import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { getHostRiskIndex, RiskQueries, RiskScoreEntity } from '../../../../common/search_strategy'; +import { useRiskScoreFeatureStatus } from '../../../risk_score/containers/feature_status'; +import { useSpaceId } from '../../../common/hooks/use_space_id'; export const HostsKpiComponent = React.memo( ({ filterQuery, from, indexNames, to, setQuery, skip, updateDateRange }) => { - const [loading, { isLicenseValid, isModuleEnabled }] = useHostRiskScore(); + const spaceId = useSpaceId(); + const defaultIndex = spaceId ? getHostRiskIndex(spaceId) : undefined; + const { isEnabled, isLicenseValid, isLoading } = useRiskScoreFeatureStatus( + RiskQueries.hostsRiskScore, + defaultIndex + ); return ( <> - {isLicenseValid && !isModuleEnabled && !loading && ( + {isLicenseValid && !isEnabled && !isLoading && ( <> ({ from, to }), [from, to]); const [ loading, @@ -69,7 +70,7 @@ export const HostRiskScoreQueryTabBody = ({ skip: querySkip, pagination, sort, - timerange: { from, to }, + timerange, }); const { severityCount, loading: isKpiLoading } = useHostRiskScoreKpi({ @@ -77,13 +78,11 @@ export const HostRiskScoreQueryTabBody = ({ skip: querySkip, }); - const timerange = useMemo(() => ({ from, to }), [from, to]); - if (!isModuleEnabled && !loading) { return ; } - if (isDeprecated) { + if (isDeprecated && !loading) { return ( ; + if ( + !loading && + isModuleEnabled && + severitySelectionRedux.length === 0 && + data && + data.length === 0 + ) { + return ; } return ( @@ -109,7 +114,7 @@ export const HostRiskScoreQueryTabBody = ({ refetch={refetch} setQuery={setQuery} setQuerySkip={setQuerySkip} - severityCount={severityCount} + severityCount={severityCount ?? EMPTY_SEVERITY_COUNT} totalCount={totalCount} type={type} /> diff --git a/x-pack/plugins/security_solution/public/hosts/pages/navigation/host_risk_tab_body.tsx b/x-pack/plugins/security_solution/public/hosts/pages/navigation/host_risk_tab_body.tsx index adb4e97ad13be..84b4399c1dccf 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/navigation/host_risk_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/navigation/host_risk_tab_body.tsx @@ -69,7 +69,6 @@ const HostRiskTabBodyComponent: React.FC< useQueryToggle(`${QUERY_ID} overTime`); const { toggleStatus: contributorsToggleStatus, setToggleStatus: setContributorsToggleStatus } = useQueryToggle(`${QUERY_ID} contributors`); - const [loading, { data, refetch, inspect, isDeprecated, isModuleEnabled }] = useHostRiskScore({ filterQuery, onlyLatest: false, @@ -106,7 +105,7 @@ const HostRiskTabBodyComponent: React.FC< return ; } - if (isDeprecated) { + if (isDeprecated && !loading) { return ( ; + return ; } return ( diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/columns.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/columns.tsx index 8f37f8af1ac3f..cc727efa5188e 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/columns.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/columns.tsx @@ -7,6 +7,7 @@ import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; import type { EuiBasicTableColumn } from '@elastic/eui'; +import { EuiLink } from '@elastic/eui'; import { ML_PAGES, useMlHref } from '@kbn/ml-plugin/public'; import { useDispatch } from 'react-redux'; import * as i18n from './translations'; @@ -29,6 +30,9 @@ const MediumShadeText = styled.span` color: ${({ theme }) => theme.eui.euiColorMediumShade}; `; +const INSTALL_JOBS_DOC = + 'https://www.elastic.co/guide/en/machine-learning/current/ml-ad-run-jobs.html'; + export const useAnomaliesColumns = (loading: boolean): AnomaliesColumns => { const columns: AnomaliesColumns = useMemo( () => [ @@ -73,6 +77,14 @@ export const useAnomaliesColumns = (loading: boolean): AnomaliesColumns => { return ; } + if (status === AnomalyJobStatus.uninstalled) { + return ( + + {i18n.JOB_STATUS_UNINSTALLED} + + ); + } + return {I18N_JOB_STATUS[status]}; } }, @@ -86,7 +98,6 @@ export const useAnomaliesColumns = (loading: boolean): AnomaliesColumns => { const I18N_JOB_STATUS = { [AnomalyJobStatus.disabled]: i18n.JOB_STATUS_DISABLED, [AnomalyJobStatus.failed]: i18n.JOB_STATUS_FAILED, - [AnomalyJobStatus.uninstalled]: i18n.JOB_STATUS_UNINSTALLED, }; const EnableJobLink = ({ jobId }: { jobId: string }) => { diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.test.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.test.tsx index fe8fd01665280..0a8abe2500e0c 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.test.tsx @@ -19,24 +19,12 @@ const severityCount: SeverityCount = { [RiskSeverity.unknown]: 1, [RiskSeverity.critical]: 1, }; -const href = 'test-href'; describe('RiskScoreDonutChart', () => { - it('renders link', () => { - const { getByTestId } = render( - - {}} href={href} /> - - ); - - expect(getByTestId('view-total-button')).toBeInTheDocument(); - expect(getByTestId('view-total-button')).toHaveAttribute('href', href); - }); - it('renders legends', () => { const { getByTestId } = render( - {}} href={href} /> + ); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.tsx index aad763e7ee38e..ecd3f31489d6b 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/common/risk_score_donut_chart.tsx @@ -6,11 +6,9 @@ */ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import type { MouseEventHandler } from 'react'; import React from 'react'; import type { ShapeTreeNode } from '@elastic/charts'; import styled from 'styled-components'; -import { LinkAnchor } from '../../../../common/components/links'; import type { SeverityCount } from '../../../../common/components/severity/types'; import { useRiskDonutChartData } from './use_risk_donut_chart_data'; import type { FillColor } from '../../../../common/components/charts/donutchart'; @@ -39,11 +37,9 @@ const StyledLegendItems = styled(EuiFlexItem)` interface RiskScoreDonutChartProps { severityCount: SeverityCount; - onClick: MouseEventHandler; - href: string; } -export const RiskScoreDonutChart = ({ severityCount, onClick, href }: RiskScoreDonutChartProps) => { +export const RiskScoreDonutChart = ({ severityCount }: RiskScoreDonutChartProps) => { const [donutChartData, legendItems, total] = useRiskDonutChartData(severityCount); return ( @@ -56,11 +52,7 @@ export const RiskScoreDonutChart = ({ severityCount, onClick, href }: RiskScoreD data={donutChartData ?? null} fillColor={fillColor} height={DONUT_HEIGHT} - label={ - - {i18n.TOTAL_LABEL} - - } + label={i18n.TOTAL_LABEL} title={} totalCount={total} /> diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.tsx index f94c7d52f6fce..d8f087a7cc884 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.tsx @@ -8,7 +8,7 @@ import React, { useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; import styled from 'styled-components'; import { useDispatch } from 'react-redux'; -import { sum } from 'lodash/fp'; +import { sumBy } from 'lodash/fp'; import { ML_PAGES, useMlHref } from '@kbn/ml-plugin/public'; import { useHostRiskScoreKpi, useUserRiskScoreKpi } from '../../../../risk_score/containers'; import { LinkAnchor, useGetSecuritySolutionLinkProps } from '../../../../common/components/links'; @@ -25,15 +25,41 @@ import { useNotableAnomaliesSearch } from '../../../../common/components/ml/anom import { useGlobalTime } from '../../../../common/containers/use_global_time'; import { useKibana } from '../../../../common/lib/kibana'; import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; +import { useQueryInspector } from '../../../../common/components/page/manage_query'; const StyledEuiTitle = styled(EuiTitle)` color: ${({ theme: { eui } }) => eui.euiColorVis9}; `; +const HOST_RISK_QUERY_ID = 'hostRiskScoreKpiQuery'; +const USER_RISK_QUERY_ID = 'userRiskScoreKpiQuery'; + export const EntityAnalyticsHeader = () => { - const { severityCount: hostsSeverityCount } = useHostRiskScoreKpi({}); - const { severityCount: usersSeverityCount } = useUserRiskScoreKpi({}); const { from, to } = useGlobalTime(false); + const timerange = useMemo( + () => ({ + from, + to, + }), + [from, to] + ); + + const { + severityCount: hostsSeverityCount, + loading: hostRiskLoading, + inspect: inspectHostRiskScore, + refetch: refetchHostRiskScore, + } = useHostRiskScoreKpi({ timerange }); + + const { + severityCount: usersSeverityCount, + loading: userRiskLoading, + refetch: refetchUserRiskScore, + inspect: inspectUserRiskScore, + } = useUserRiskScoreKpi({ + timerange, + }); + const { data } = useNotableAnomaliesSearch({ skip: false, from, to }); const dispatch = useDispatch(); const getSecuritySolutionLinkProps = useGetSecuritySolutionLinkProps(); @@ -88,7 +114,33 @@ export const EntityAnalyticsHeader = () => { return [onClick, href]; }, [dispatch, getSecuritySolutionLinkProps]); - const totalAnomalies = useMemo(() => sum(data.map(({ count }) => count)), [data]); + const { deleteQuery, setQuery } = useGlobalTime(); + + useQueryInspector({ + queryId: USER_RISK_QUERY_ID, + loading: userRiskLoading, + refetch: refetchUserRiskScore, + setQuery, + deleteQuery, + inspect: inspectUserRiskScore, + }); + + useQueryInspector({ + queryId: HOST_RISK_QUERY_ID, + loading: hostRiskLoading, + refetch: refetchHostRiskScore, + setQuery, + deleteQuery, + inspect: inspectHostRiskScore, + }); + + // Anomalies are enabled if at least one job is installed + const areJobsEnabled = useMemo(() => data.some(({ jobId }) => !!jobId), [data]); + + const totalAnomalies = useMemo( + () => (areJobsEnabled ? sumBy('count', data) : '-'), + [data, areJobsEnabled] + ); const jobsUrl = useMlHref(ml, http.basePath.get(), { page: ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, @@ -102,7 +154,9 @@ export const EntityAnalyticsHeader = () => { - {hostsSeverityCount[RiskSeverity.critical]} + + {hostsSeverityCount ? hostsSeverityCount[RiskSeverity.critical] : '-'} + @@ -122,7 +176,9 @@ export const EntityAnalyticsHeader = () => { - {usersSeverityCount[RiskSeverity.critical]} + + {usersSeverityCount ? usersSeverityCount[RiskSeverity.critical] : '-'} + diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/host_risk_score/index.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/host_risk_score/index.tsx index 123f190446255..1db3fd6e5d873 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/host_risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/host_risk_score/index.tsx @@ -19,7 +19,7 @@ import { HeaderSection } from '../../../../common/components/header_section'; import { useHostRiskScore, useHostRiskScoreKpi } from '../../../../risk_score/containers'; import type { RiskSeverity } from '../../../../../common/search_strategy'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; +import { EMPTY_SEVERITY_COUNT, RiskScoreEntity } from '../../../../../common/search_strategy'; import { SecurityPageName } from '../../../../app/types'; import * as i18n from './translations'; import { generateSeverityFilter } from '../../../../hosts/store/helpers'; @@ -34,8 +34,10 @@ import { RISKY_HOSTS_EXTERNAL_DOC_LINK } from '../../../../../common/constants'; import { EntityAnalyticsHostRiskScoreDisable } from '../../../../common/components/risk_score/risk_score_disabled/host_risk_score_disabled'; import { RiskScoreHeaderTitle } from '../../../../common/components/risk_score/risk_score_onboarding/risk_score_header_title'; import { RiskScoresNoDataDetected } from '../../../../common/components/risk_score/risk_score_onboarding/risk_score_no_data_detected'; +import { useRefetchQueries } from '../../../../common/hooks/use_refetch_queries'; const TABLE_QUERY_ID = 'hostRiskDashboardTable'; +const HOST_RISK_KPI_QUERY_ID = 'headerHostRiskScoreKpiQuery'; const EntityAnalyticsHostRiskScoresComponent = () => { const { deleteQuery, setQuery, from, to } = useGlobalTime(); @@ -52,11 +54,6 @@ const EntityAnalyticsHostRiskScoresComponent = () => { return filter ? JSON.stringify(filter.query) : undefined; }, [selectedSeverity]); - const { severityCount, loading: isKpiLoading } = useHostRiskScoreKpi({ - filterQuery: severityFilter, - skip: !toggleStatus, - }); - const timerange = useMemo( () => ({ from, @@ -65,6 +62,25 @@ const EntityAnalyticsHostRiskScoresComponent = () => { [from, to] ); + const { + severityCount, + loading: isKpiLoading, + refetch: refetchKpi, + inspect: inspectKpi, + } = useHostRiskScoreKpi({ + filterQuery: severityFilter, + skip: !toggleStatus, + timerange, + }); + + useQueryInspector({ + queryId: HOST_RISK_KPI_QUERY_ID, + loading: isKpiLoading, + refetch: refetchKpi, + setQuery, + deleteQuery, + inspect: inspectKpi, + }); const [ isTableLoading, { data, inspect, refetch, isDeprecated, isLicenseValid, isModuleEnabled }, @@ -107,26 +123,28 @@ const EntityAnalyticsHostRiskScoresComponent = () => { return [onClick, href]; }, [dispatch, getSecuritySolutionLinkProps]); + const refreshPage = useRefetchQueries(); + if (!isLicenseValid) { return null; } - if (!isModuleEnabled) { - return ; + if (!isModuleEnabled && !isTableLoading) { + return ; } - if (isDeprecated) { + if (isDeprecated && !isTableLoading) { return ( ); } if (isModuleEnabled && selectedSeverity.length === 0 && data && data.length === 0) { - return ; + return ; } return ( @@ -156,7 +174,7 @@ const EntityAnalyticsHostRiskScoresComponent = () => { @@ -176,11 +194,7 @@ const EntityAnalyticsHostRiskScoresComponent = () => { {toggleStatus && ( - + { const { deleteQuery, setQuery, from, to } = useGlobalTime(); @@ -52,11 +54,6 @@ const EntityAnalyticsUserRiskScoresComponent = () => { return filter ? JSON.stringify(filter.query) : undefined; }, [selectedSeverity]); - const { severityCount, loading: isKpiLoading } = useUserRiskScoreKpi({ - filterQuery: severityFilter, - skip: !toggleStatus, - }); - const timerange = useMemo( () => ({ from, @@ -65,6 +62,17 @@ const EntityAnalyticsUserRiskScoresComponent = () => { [from, to] ); + const { + severityCount, + loading: isKpiLoading, + refetch: refetchKpi, + inspect: inspectKpi, + } = useUserRiskScoreKpi({ + filterQuery: severityFilter, + skip: !toggleStatus, + timerange, + }); + const [ isTableLoading, { data, inspect, refetch, isLicenseValid, isDeprecated, isModuleEnabled }, @@ -87,6 +95,15 @@ const EntityAnalyticsUserRiskScoresComponent = () => { inspect, }); + useQueryInspector({ + queryId: USER_RISK_KPI_QUERY_ID, + loading: isKpiLoading, + refetch: refetchKpi, + setQuery, + deleteQuery, + inspect: inspectKpi, + }); + useEffect(() => { setUpdatedAt(Date.now()); }, [isTableLoading, isKpiLoading]); // Update the time when data loads @@ -106,26 +123,28 @@ const EntityAnalyticsUserRiskScoresComponent = () => { return [onClick, href]; }, [dispatch, getSecuritySolutionLinkProps]); + const refreshPage = useRefetchQueries(); + if (!isLicenseValid) { return null; } - if (!isModuleEnabled) { - return ; + if (!isModuleEnabled && !isTableLoading) { + return ; } - if (isDeprecated) { + if (isDeprecated && !isTableLoading) { return ( ); } if (isModuleEnabled && selectedSeverity.length === 0 && data && data.length === 0) { - return ; + return ; } return ( @@ -155,7 +174,7 @@ const EntityAnalyticsUserRiskScoresComponent = () => { @@ -175,11 +194,7 @@ const EntityAnalyticsUserRiskScoresComponent = () => { {toggleStatus && ( - + ( ); const { from, to } = useGlobalTime(); + const timerange = useMemo( + () => ({ + from, + to, + }), + [from, to] + ); const [_, { data: hostRisk, isLicenseValid }] = useHostRiskScore({ filterQuery, skip: hostName == null, - timerange: { to, from }, + timerange, }); const getDefaultRenderer = useCallback( diff --git a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx index e635f94e51d51..68b40f581d384 100644 --- a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx @@ -85,10 +85,18 @@ export const UserOverview = React.memo( const { from, to } = useGlobalTime(); + const timerange = useMemo( + () => ({ + from, + to, + }), + [from, to] + ); + const [_, { data: userRisk, isLicenseValid }] = useUserRiskScore({ filterQuery, skip: userName == null, - timerange: { to, from }, + timerange, }); const getDefaultRenderer = useCallback( diff --git a/x-pack/plugins/security_solution/public/overview/pages/entity_analytics.tsx b/x-pack/plugins/security_solution/public/overview/pages/entity_analytics.tsx index bc478eeecc4b1..3ef48810d6094 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/entity_analytics.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/entity_analytics.tsx @@ -27,15 +27,15 @@ import { InputsModelId } from '../../common/store/inputs/constants'; const EntityAnalyticsComponent = () => { const { indicesExist, loading: isSourcererLoading, indexPattern } = useSourcererDataView(); + const { isPlatinumOrTrialLicense, capabilitiesFetched } = useMlCapabilities(); - const isPlatinumOrTrialLicense = useMlCapabilities().isPlatinumOrTrialLicense; return ( <> {indicesExist ? ( <> - {isPlatinumOrTrialLicense && ( + {isPlatinumOrTrialLicense && capabilitiesFetched && ( { /> )} - {isPlatinumOrTrialLicense ? ( - isSourcererLoading ? ( - - ) : ( - - - - + {!isPlatinumOrTrialLicense && capabilitiesFetched ? ( + + ) : isSourcererLoading ? ( + + ) : ( + + + + - - - + + + - - - + + + - - - - - ) - ) : ( - + + + + )} diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx b/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx index e1f1b7ecd13ba..9c5671640f87a 100644 --- a/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx +++ b/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx @@ -12,8 +12,8 @@ import { createFilter } from '../../../common/containers/helpers'; import type { RiskScoreSortField, StrategyResponseType } from '../../../../common/search_strategy'; import { getHostRiskIndex, - RiskQueries, getUserRiskIndex, + RiskQueries, } from '../../../../common/search_strategy'; import type { ESQuery } from '../../../../common/typed_json'; @@ -64,7 +64,14 @@ export const initialResult: Omit< }; export const useHostRiskScore = (params?: UseRiskScoreParams) => { - const { timerange, onlyLatest, filterQuery, sort, skip = false, pagination } = params ?? {}; + const { + timerange, + onlyLatest = true, + filterQuery, + sort, + skip = false, + pagination, + } = params ?? {}; const spaceId = useSpaceId(); const defaultIndex = spaceId ? getHostRiskIndex(spaceId, onlyLatest) : undefined; @@ -81,7 +88,14 @@ export const useHostRiskScore = (params?: UseRiskScoreParams) => { }; export const useUserRiskScore = (params?: UseRiskScoreParams) => { - const { timerange, onlyLatest, filterQuery, sort, skip = false, pagination } = params ?? {}; + const { + timerange, + onlyLatest = true, + filterQuery, + sort, + skip = false, + pagination, + } = params ?? {}; const spaceId = useSpaceId(); const defaultIndex = spaceId ? getUserRiskIndex(spaceId, onlyLatest) : undefined; @@ -99,6 +113,7 @@ export const useUserRiskScore = (params?: UseRiskScoreParams) => { const useRiskScore = ({ timerange, + onlyLatest, filterQuery, sort, skip = false, @@ -167,6 +182,11 @@ const useRiskScore = (timerange ? { to: timerange.to, from: timerange.from, interval: '' } : undefined), + [timerange] + ); + const riskScoreRequest = useMemo( () => defaultIndex @@ -182,9 +202,19 @@ const useRiskScore = { @@ -196,10 +226,25 @@ const useRiskScore = { - if (!skip && riskScoreRequest != null && isLicenseValid && isEnabled && !isDeprecated) { + if ( + !skip && + !isDeprecatedLoading && + riskScoreRequest != null && + isLicenseValid && + isEnabled && + !isDeprecated + ) { search(riskScoreRequest); } - }, [isEnabled, isDeprecated, isLicenseValid, riskScoreRequest, search, skip]); + }, [ + isEnabled, + isDeprecated, + isLicenseValid, + isDeprecatedLoading, + riskScoreRequest, + search, + skip, + ]); return [loading || isDeprecatedLoading, riskScoreResponse]; }; diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/feature_status/index.test.ts b/x-pack/plugins/security_solution/public/risk_score/containers/feature_status/index.test.ts index cb5b549894044..619de81b36b9b 100644 --- a/x-pack/plugins/security_solution/public/risk_score/containers/feature_status/index.test.ts +++ b/x-pack/plugins/security_solution/public/risk_score/containers/feature_status/index.test.ts @@ -37,7 +37,7 @@ describe(`risk score feature status`, () => { isDeprecated: true, isLicenseValid: true, isEnabled: true, - isLoading: false, + isLoading: true, }; test('does not search if license is not valid, and initial isDeprecated state is false', () => { diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/feature_status/index.ts b/x-pack/plugins/security_solution/public/risk_score/containers/feature_status/index.ts index cf5a8feb0ee0d..0099ed0df3f09 100644 --- a/x-pack/plugins/security_solution/public/risk_score/containers/feature_status/index.ts +++ b/x-pack/plugins/security_solution/public/risk_score/containers/feature_status/index.ts @@ -27,7 +27,7 @@ export const useRiskScoreFeatureStatus = ( factoryQueryType: RiskQueries.hostsRiskScore | RiskQueries.usersRiskScore, defaultIndex?: string ): RiskScoresFeatureStatus => { - const isPlatinumOrTrialLicense = useMlCapabilities().isPlatinumOrTrialLicense; + const { isPlatinumOrTrialLicense, capabilitiesFetched } = useMlCapabilities(); const entity = useMemo( () => factoryQueryType === RiskQueries.hostsRiskScore ? RiskScoreEntity.host : RiskScoreEntity.user, @@ -66,7 +66,7 @@ export const useRiskScoreFeatureStatus = ( return { error, - isLoading, + isLoading: isLoading || !capabilitiesFetched || defaultIndex == null, refetch: searchIndexStatus, isLicenseValid: isPlatinumOrTrialLicense, ...response, diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/kpi/index.tsx b/x-pack/plugins/security_solution/public/risk_score/containers/kpi/index.tsx index 2c137a8bf1e06..340ec3347a4f7 100644 --- a/x-pack/plugins/security_solution/public/risk_score/containers/kpi/index.tsx +++ b/x-pack/plugins/security_solution/public/risk_score/containers/kpi/index.tsx @@ -5,77 +5,35 @@ * 2.0. */ -import type { Observable } from 'rxjs'; -import { filter } from 'rxjs/operators'; import { useEffect, useMemo } from 'react'; -import { useObservable, withOptionalSignal } from '@kbn/securitysolution-hook-utils'; -import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common'; -import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; -import { createFilter } from '../../../common/containers/helpers'; - -import type { - KpiRiskScoreRequestOptions, - KpiRiskScoreStrategyResponse, -} from '../../../../common/search_strategy'; + import { getHostRiskIndex, getUserRiskIndex, RiskQueries, RiskSeverity, RiskScoreEntity, + EMPTY_SEVERITY_COUNT, } from '../../../../common/search_strategy'; - -import { useKibana } from '../../../common/lib/kibana'; +import * as i18n from './translations'; import { isIndexNotFoundError } from '../../../common/utils/exceptions'; import type { ESTermQuery } from '../../../../common/typed_json'; import type { SeverityCount } from '../../../common/components/severity/types'; import { useSpaceId } from '../../../common/hooks/use_space_id'; import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; - -type GetHostRiskScoreProps = KpiRiskScoreRequestOptions & { - data: DataPublicPluginStart; - signal: AbortSignal; -}; - -const getRiskScoreKpi = ({ - data, - defaultIndex, - signal, - filterQuery, - entity, -}: GetHostRiskScoreProps): Observable => - data.search.search( - { - defaultIndex, - factoryQueryType: RiskQueries.kpiRiskScore, - filterQuery: createFilter(filterQuery), - entity, - }, - { - strategy: 'securitySolutionSearchStrategy', - abortSignal: signal, - } - ); - -const getRiskScoreKpiComplete = ( - props: GetHostRiskScoreProps -): Observable => { - return getRiskScoreKpi(props).pipe( - filter((response) => { - return isErrorResponse(response) || isCompleteResponse(response); - }) - ); -}; - -const getRiskScoreKpiWithOptionalSignal = withOptionalSignal(getRiskScoreKpiComplete); - -const useRiskScoreKpiComplete = () => useObservable(getRiskScoreKpiWithOptionalSignal); +import { useSearchStrategy } from '../../../common/containers/use_search_strategy'; +import type { InspectResponse } from '../../../types'; +import type { inputsModel } from '../../../common/store'; +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; interface RiskScoreKpi { error: unknown; isModuleDisabled: boolean; - severityCount: SeverityCount; + severityCount?: SeverityCount; loading: boolean; + refetch: inputsModel.Refetch; + inspect: InspectResponse; + timerange?: { to: string; from: string }; } type UseHostRiskScoreKpiProps = Omit< @@ -90,6 +48,7 @@ type UseUserRiskScoreKpiProps = Omit< export const useUserRiskScoreKpi = ({ filterQuery, skip, + timerange, }: UseUserRiskScoreKpiProps): RiskScoreKpi => { const spaceId = useSpaceId(); const defaultIndex = spaceId ? getUserRiskIndex(spaceId) : undefined; @@ -101,12 +60,14 @@ export const useUserRiskScoreKpi = ({ defaultIndex, entity: RiskScoreEntity.user, featureEnabled: isPlatinumOrTrialLicense, + timerange, }); }; export const useHostRiskScoreKpi = ({ filterQuery, skip, + timerange, }: UseHostRiskScoreKpiProps): RiskScoreKpi => { const spaceId = useSpaceId(); const defaultIndex = spaceId ? getHostRiskIndex(spaceId) : undefined; @@ -118,6 +79,7 @@ export const useHostRiskScoreKpi = ({ defaultIndex, entity: RiskScoreEntity.host, featureEnabled: isPlatinumOrTrialLicense, + timerange, }); }; @@ -127,6 +89,7 @@ interface UseRiskScoreKpiProps { defaultIndex: string | undefined; entity: RiskScoreEntity; featureEnabled: boolean; + timerange?: { to: string; from: string }; } const useRiskScoreKpi = ({ @@ -135,33 +98,59 @@ const useRiskScoreKpi = ({ defaultIndex, entity, featureEnabled, + timerange, }: UseRiskScoreKpiProps): RiskScoreKpi => { - const { error, result, start, loading } = useRiskScoreKpiComplete(); - const { data } = useKibana().services; + const { addError } = useAppToasts(); + + const { loading, result, search, refetch, inspect, error } = + useSearchStrategy({ + factoryQueryType: RiskQueries.kpiRiskScore, + initialResult: { + kpiRiskScore: EMPTY_SEVERITY_COUNT, + }, + abort: skip, + showErrorToast: false, + }); + const isModuleDisabled = !!error && isIndexNotFoundError(error); useEffect(() => { if (!skip && defaultIndex && featureEnabled) { - start({ - data, + search({ filterQuery, defaultIndex: [defaultIndex], entity, }); } - }, [data, defaultIndex, start, filterQuery, skip, entity, featureEnabled]); - - const severityCount = useMemo( - () => ({ - [RiskSeverity.unknown]: 0, - [RiskSeverity.low]: 0, - [RiskSeverity.moderate]: 0, - [RiskSeverity.high]: 0, - [RiskSeverity.critical]: 0, - ...(result?.kpiRiskScore ?? {}), - }), - [result] - ); - - return { error, severityCount, loading, isModuleDisabled }; + }, [defaultIndex, search, filterQuery, skip, entity, featureEnabled]); + + // since query does not take timerange arg, we need to manually refetch when time range updates + useEffect(() => { + refetch(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [timerange?.to, timerange?.from]); + + useEffect(() => { + if (error) { + if (!isIndexNotFoundError(error)) { + addError(error, { title: i18n.FAIL_RISK_SCORE }); + } + } + }, [addError, error]); + + const severityCount = useMemo(() => { + if (loading || error) { + return undefined; + } + + return { + [RiskSeverity.unknown]: result.kpiRiskScore[RiskSeverity.unknown] ?? 0, + [RiskSeverity.low]: result.kpiRiskScore[RiskSeverity.low] ?? 0, + [RiskSeverity.moderate]: result.kpiRiskScore[RiskSeverity.moderate] ?? 0, + [RiskSeverity.high]: result.kpiRiskScore[RiskSeverity.high] ?? 0, + [RiskSeverity.critical]: result.kpiRiskScore[RiskSeverity.critical] ?? 0, + }; + }, [result, loading, error]); + + return { error, severityCount, loading, isModuleDisabled, refetch, inspect }; }; diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/kpi/translations.ts b/x-pack/plugins/security_solution/public/risk_score/containers/kpi/translations.ts new file mode 100644 index 0000000000000..83b402220f3d4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/risk_score/containers/kpi/translations.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const FAIL_RISK_SCORE = i18n.translate( + 'xpack.securitySolution.riskScore.kpi.failSearchDescription', + { + defaultMessage: `Failed to run search on risk score`, + } +); diff --git a/x-pack/plugins/security_solution/public/users/components/kpi_users/index.tsx b/x-pack/plugins/security_solution/public/users/components/kpi_users/index.tsx index 43933340fac7f..4344c52e10d4b 100644 --- a/x-pack/plugins/security_solution/public/users/components/kpi_users/index.tsx +++ b/x-pack/plugins/security_solution/public/users/components/kpi_users/index.tsx @@ -12,19 +12,25 @@ import type { UsersKpiProps } from './types'; import { UsersKpiAuthentications } from './authentications'; import { TotalUsersKpi } from './total_users'; -import { useUserRiskScore } from '../../../risk_score/containers'; import { CallOutSwitcher } from '../../../common/components/callouts'; import * as i18n from './translations'; import { RiskScoreDocLink } from '../../../common/components/risk_score/risk_score_onboarding/risk_score_doc_link'; -import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { getUserRiskIndex, RiskQueries, RiskScoreEntity } from '../../../../common/search_strategy'; +import { useSpaceId } from '../../../common/hooks/use_space_id'; +import { useRiskScoreFeatureStatus } from '../../../risk_score/containers/feature_status'; export const UsersKpiComponent = React.memo( ({ filterQuery, from, indexNames, to, setQuery, skip, updateDateRange }) => { - const [loading, { isLicenseValid, isModuleEnabled }] = useUserRiskScore(); + const spaceId = useSpaceId(); + const defaultIndex = spaceId ? getUserRiskIndex(spaceId) : undefined; + const { isEnabled, isLicenseValid, isLoading } = useRiskScoreFeatureStatus( + RiskQueries.usersRiskScore, + defaultIndex + ); return ( <> - {isLicenseValid && !isModuleEnabled && !loading && ( + {isLicenseValid && !isEnabled && !isLoading && ( <> ; } - if (isDeprecated) { + if (isDeprecated && !loading) { return ( ; + return ; } return ( @@ -110,7 +110,7 @@ export const UserRiskScoreQueryTabBody = ({ refetch={refetch} setQuery={setQuery} setQuerySkip={setQuerySkip} - severityCount={severityCount} + severityCount={severityCount ?? EMPTY_SEVERITY_COUNT} totalCount={totalCount} type={type} /> diff --git a/x-pack/plugins/security_solution/public/users/pages/navigation/user_risk_tab_body.tsx b/x-pack/plugins/security_solution/public/users/pages/navigation/user_risk_tab_body.tsx index d8123148480c6..fed651759df7c 100644 --- a/x-pack/plugins/security_solution/public/users/pages/navigation/user_risk_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/users/pages/navigation/user_risk_tab_body.tsx @@ -94,7 +94,7 @@ const UserRiskTabBodyComponent: React.FC< return ; } - if (isDeprecated) { + if (isDeprecated && !loading) { return ( ; + return ; } const lastUsertRiskItem: UserRiskScore | null = From 36ceb94d42110983125120f7e1f0b5d31ecdbdfc Mon Sep 17 00:00:00 2001 From: Philippe Oberti Date: Mon, 26 Sep 2022 10:12:55 -0500 Subject: [PATCH 16/51] [TIP] Rename lib folders to utils (#141781) --- .../indicator_field_value/indicator_field_value.tsx | 2 +- .../indicator_value_actions/indicator_value_actions.tsx | 2 +- .../components/indicators_flyout/indicators_flyout.tsx | 2 +- .../highlighted_values_table/highlighted_values_table.tsx | 2 +- .../indicators_flyout_overview.tsx | 2 +- .../indicators_flyout_table.test.tsx | 2 +- .../components/indicators_table/cell_actions.tsx | 2 +- .../components/indicators_table/indicators_table.tsx | 2 +- .../modules/indicators/hooks/use_aggregated_indicators.ts | 4 ++-- .../public/modules/indicators/hooks/use_indicators.ts | 4 ++-- .../modules/indicators/{lib => utils}/display_name.test.ts | 0 .../modules/indicators/{lib => utils}/display_name.ts | 0 .../modules/indicators/{lib => utils}/field_value.test.ts | 0 .../modules/indicators/{lib => utils}/field_value.ts | 0 .../modules/indicators/{lib => utils}/get_field_schema.ts | 0 .../indicators/{lib => utils}/get_indicators_query.ts | 0 .../indicators/{lib => utils}/get_runtime_mappings.ts | 0 .../modules/indicators/{lib => utils}/unwrap_value.test.ts | 0 .../modules/indicators/{lib => utils}/unwrap_value.ts | 0 .../modules/query_bar/components/filter_in/filter_in.tsx | 7 +++++-- .../modules/query_bar/components/filter_out/filter_out.tsx | 7 +++++-- .../public/modules/query_bar/{lib => utils}/filter.test.ts | 0 .../public/modules/query_bar/{lib => utils}/filter.ts | 0 .../components/add_to_timeline/add_to_timeline.tsx | 7 +++++-- .../modules/timeline/hooks/use_investigate_in_timeline.ts | 6 +++--- .../modules/timeline/{lib => utils}/data_provider.test.ts | 0 .../modules/timeline/{lib => utils}/data_provider.ts | 0 27 files changed, 30 insertions(+), 21 deletions(-) rename x-pack/plugins/threat_intelligence/public/modules/indicators/{lib => utils}/display_name.test.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/indicators/{lib => utils}/display_name.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/indicators/{lib => utils}/field_value.test.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/indicators/{lib => utils}/field_value.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/indicators/{lib => utils}/get_field_schema.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/indicators/{lib => utils}/get_indicators_query.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/indicators/{lib => utils}/get_runtime_mappings.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/indicators/{lib => utils}/unwrap_value.test.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/indicators/{lib => utils}/unwrap_value.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/query_bar/{lib => utils}/filter.test.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/query_bar/{lib => utils}/filter.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/timeline/{lib => utils}/data_provider.test.ts (100%) rename x-pack/plugins/threat_intelligence/public/modules/timeline/{lib => utils}/data_provider.ts (100%) diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_field_value/indicator_field_value.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_field_value/indicator_field_value.tsx index c0b46cd1b44b0..55dfa883c30ad 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_field_value/indicator_field_value.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_field_value/indicator_field_value.tsx @@ -10,7 +10,7 @@ import { useFieldTypes } from '../../../../hooks/use_field_types'; import { EMPTY_VALUE } from '../../../../../common/constants'; import { Indicator, RawIndicatorFieldId } from '../../../../../common/types/indicator'; import { DateFormatter } from '../../../../components/date_formatter'; -import { unwrapValue } from '../../lib/unwrap_value'; +import { unwrapValue } from '../../utils/unwrap_value'; export interface IndicatorFieldValueProps { /** diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_value_actions/indicator_value_actions.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_value_actions/indicator_value_actions.tsx index f3c5fd7c2e7d8..42fd697ec5395 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_value_actions/indicator_value_actions.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicator_value_actions/indicator_value_actions.tsx @@ -12,7 +12,7 @@ import { Indicator } from '../../../../../common/types/indicator'; import { FilterIn } from '../../../query_bar/components/filter_in'; import { FilterOut } from '../../../query_bar/components/filter_out'; import { AddToTimeline } from '../../../timeline/components/add_to_timeline'; -import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../lib/field_value'; +import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../utils/field_value'; export const TIMELINE_BUTTON_TEST_ID = 'TimelineButton'; export const FILTER_IN_BUTTON_TEST_ID = 'FilterInButton'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/indicators_flyout.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/indicators_flyout.tsx index 303059c61fc69..86949da21a814 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/indicators_flyout.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/indicators_flyout.tsx @@ -26,7 +26,7 @@ import { DateFormatter } from '../../../../components/date_formatter/date_format import { Indicator, RawIndicatorFieldId } from '../../../../../common/types/indicator'; import { IndicatorsFlyoutJson } from './tabs/indicators_flyout_json/indicators_flyout_json'; import { IndicatorsFlyoutTable } from './tabs/indicators_flyout_table/indicators_flyout_table'; -import { unwrapValue } from '../../lib/unwrap_value'; +import { unwrapValue } from '../../utils/unwrap_value'; import { IndicatorsFlyoutOverview } from './tabs/indicators_flyout_overview'; export const TITLE_TEST_ID = 'tiIndicatorFlyoutTitle'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/components/highlighted_values_table/highlighted_values_table.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/components/highlighted_values_table/highlighted_values_table.tsx index d7cf25dca3239..d9af696065db1 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/components/highlighted_values_table/highlighted_values_table.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/components/highlighted_values_table/highlighted_values_table.tsx @@ -7,7 +7,7 @@ import React, { useMemo, VFC } from 'react'; import { Indicator, RawIndicatorFieldId } from '../../../../../../../../../common/types/indicator'; -import { unwrapValue } from '../../../../../../lib/unwrap_value'; +import { unwrapValue } from '../../../../../../utils/unwrap_value'; import { IndicatorFieldsTable } from '../../../../components/indicator_fields_table'; /** diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/indicators_flyout_overview.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/indicators_flyout_overview.tsx index c1a0468822269..a7551398b62c4 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/indicators_flyout_overview.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_overview/indicators_flyout_overview.tsx @@ -19,7 +19,7 @@ import React, { useMemo } from 'react'; import { VFC } from 'react'; import { EMPTY_VALUE } from '../../../../../../../common/constants'; import { Indicator, RawIndicatorFieldId } from '../../../../../../../common/types/indicator'; -import { unwrapValue } from '../../../../lib/unwrap_value'; +import { unwrapValue } from '../../../../utils/unwrap_value'; import { IndicatorEmptyPrompt } from '../../components/indicator_empty_prompt'; import { IndicatorBlock } from './components/block'; import { HighlightedValuesTable } from './components/highlighted_values_table'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_table/indicators_flyout_table.test.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_table/indicators_flyout_table.test.tsx index c91ce0e6aa89c..5e1264b1b2e4a 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_table/indicators_flyout_table.test.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_flyout/tabs/indicators_flyout_table/indicators_flyout_table.test.tsx @@ -14,7 +14,7 @@ import { RawIndicatorFieldId, } from '../../../../../../../common/types/indicator'; import { IndicatorsFlyoutTable, TABLE_TEST_ID } from './indicators_flyout_table'; -import { unwrapValue } from '../../../../lib/unwrap_value'; +import { unwrapValue } from '../../../../utils/unwrap_value'; import { EMPTY_PROMPT_TEST_ID } from '../../components/indicator_empty_prompt'; const mockIndicator: Indicator = generateMockIndicator(); diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/cell_actions.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/cell_actions.tsx index 0f111f96c4c25..38f22fe34556e 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/cell_actions.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/cell_actions.tsx @@ -11,7 +11,7 @@ import { ComponentType } from '../../../../../common/types/component_type'; import { Indicator } from '../../../../../common/types/indicator'; import { Pagination } from '../../hooks/use_indicators'; import { AddToTimeline } from '../../../timeline/components/add_to_timeline'; -import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../lib/field_value'; +import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../utils/field_value'; import { FilterIn } from '../../../query_bar/components/filter_in'; import { FilterOut } from '../../../query_bar/components/filter_out'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/indicators_table.tsx b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/indicators_table.tsx index 072fd42db696e..3e3035c8c43e4 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/indicators_table.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/components/indicators_table/indicators_table.tsx @@ -28,7 +28,7 @@ import { Pagination } from '../../hooks/use_indicators'; import { useToolbarOptions } from './hooks/use_toolbar_options'; import { ColumnSettingsValue } from './hooks/use_column_settings'; import { useFieldTypes } from '../../../../hooks/use_field_types'; -import { getFieldSchema } from '../../lib/get_field_schema'; +import { getFieldSchema } from '../../utils/get_field_schema'; export interface IndicatorsTableProps { indicators: Indicator[]; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts index 02230defa9688..ab583fb0ed95a 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_aggregated_indicators.ts @@ -23,8 +23,8 @@ import { calculateBarchartColumnTimeInterval } from '../../../common/utils/dates import { useKibana } from '../../../hooks/use_kibana'; import { DEFAULT_TIME_RANGE } from '../../query_bar/hooks/use_filters/utils'; import { useSourcererDataView } from './use_sourcerer_data_view'; -import { getRuntimeMappings } from '../lib/get_runtime_mappings'; -import { getIndicatorsQuery } from '../lib/get_indicators_query'; +import { getRuntimeMappings } from '../utils/get_runtime_mappings'; +import { getIndicatorsQuery } from '../utils/get_indicators_query'; export interface UseAggregatedIndicatorsParam { /** diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts index e44e2e05ca230..f06fb03b27d5c 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/indicators/hooks/use_indicators.ts @@ -18,8 +18,8 @@ import { useInspector } from '../../../hooks/use_inspector'; import { Indicator } from '../../../../common/types/indicator'; import { useKibana } from '../../../hooks/use_kibana'; import { useSourcererDataView } from './use_sourcerer_data_view'; -import { getRuntimeMappings } from '../lib/get_runtime_mappings'; -import { getIndicatorsQuery } from '../lib/get_indicators_query'; +import { getRuntimeMappings } from '../utils/get_runtime_mappings'; +import { getIndicatorsQuery } from '../utils/get_indicators_query'; const PAGE_SIZES = [10, 25, 50]; diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/display_name.test.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/utils/display_name.test.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/indicators/lib/display_name.test.ts rename to x-pack/plugins/threat_intelligence/public/modules/indicators/utils/display_name.test.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/display_name.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/utils/display_name.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/indicators/lib/display_name.ts rename to x-pack/plugins/threat_intelligence/public/modules/indicators/utils/display_name.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.test.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/utils/field_value.test.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.test.ts rename to x-pack/plugins/threat_intelligence/public/modules/indicators/utils/field_value.test.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/utils/field_value.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/indicators/lib/field_value.ts rename to x-pack/plugins/threat_intelligence/public/modules/indicators/utils/field_value.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_field_schema.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/utils/get_field_schema.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_field_schema.ts rename to x-pack/plugins/threat_intelligence/public/modules/indicators/utils/get_field_schema.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_indicators_query.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/utils/get_indicators_query.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_indicators_query.ts rename to x-pack/plugins/threat_intelligence/public/modules/indicators/utils/get_indicators_query.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_runtime_mappings.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/utils/get_runtime_mappings.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/indicators/lib/get_runtime_mappings.ts rename to x-pack/plugins/threat_intelligence/public/modules/indicators/utils/get_runtime_mappings.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/unwrap_value.test.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/utils/unwrap_value.test.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/indicators/lib/unwrap_value.test.ts rename to x-pack/plugins/threat_intelligence/public/modules/indicators/utils/unwrap_value.test.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/indicators/lib/unwrap_value.ts b/x-pack/plugins/threat_intelligence/public/modules/indicators/utils/unwrap_value.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/indicators/lib/unwrap_value.ts rename to x-pack/plugins/threat_intelligence/public/modules/indicators/utils/unwrap_value.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/filter_in.tsx b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/filter_in.tsx index d801f46915921..d6d62b3e35380 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/filter_in.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_in/filter_in.tsx @@ -11,8 +11,11 @@ import { EuiButtonEmpty, EuiButtonIcon, EuiContextMenuItem, EuiToolTip } from '@ import { Filter } from '@kbn/es-query'; import { ComponentType } from '../../../../../common/types/component_type'; import { useIndicatorsFiltersContext } from '../../../indicators/hooks/use_indicators_filters_context'; -import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../../indicators/lib/field_value'; -import { FilterIn as FilterInConst, updateFiltersArray } from '../../lib/filter'; +import { + fieldAndValueValid, + getIndicatorFieldAndValue, +} from '../../../indicators/utils/field_value'; +import { FilterIn as FilterInConst, updateFiltersArray } from '../../utils/filter'; import { Indicator } from '../../../../../common/types/indicator'; import { useStyles } from './styles'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/filter_out.tsx b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/filter_out.tsx index 67f28a66b486e..afa1bc02a6ba9 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/filter_out.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/query_bar/components/filter_out/filter_out.tsx @@ -11,8 +11,11 @@ import { EuiButtonEmpty, EuiButtonIcon, EuiContextMenuItem, EuiToolTip } from '@ import { Filter } from '@kbn/es-query'; import { ComponentType } from '../../../../../common/types/component_type'; import { useIndicatorsFiltersContext } from '../../../indicators/hooks/use_indicators_filters_context'; -import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../../indicators/lib/field_value'; -import { FilterOut as FilterOutConst, updateFiltersArray } from '../../lib/filter'; +import { + fieldAndValueValid, + getIndicatorFieldAndValue, +} from '../../../indicators/utils/field_value'; +import { FilterOut as FilterOutConst, updateFiltersArray } from '../../utils/filter'; import { Indicator } from '../../../../../common/types/indicator'; import { useStyles } from './styles'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/query_bar/lib/filter.test.ts b/x-pack/plugins/threat_intelligence/public/modules/query_bar/utils/filter.test.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/query_bar/lib/filter.test.ts rename to x-pack/plugins/threat_intelligence/public/modules/query_bar/utils/filter.test.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/query_bar/lib/filter.ts b/x-pack/plugins/threat_intelligence/public/modules/query_bar/utils/filter.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/query_bar/lib/filter.ts rename to x-pack/plugins/threat_intelligence/public/modules/query_bar/utils/filter.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/add_to_timeline.tsx b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/add_to_timeline.tsx index 2c0d2ec6c5f37..5b33a3bfeaa35 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/add_to_timeline.tsx +++ b/x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/add_to_timeline.tsx @@ -12,9 +12,12 @@ import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui/src/components/butto import { EuiContextMenuItem, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { generateDataProvider } from '../../lib/data_provider'; +import { generateDataProvider } from '../../utils/data_provider'; import { ComponentType } from '../../../../../common/types/component_type'; -import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../../indicators/lib/field_value'; +import { + fieldAndValueValid, + getIndicatorFieldAndValue, +} from '../../../indicators/utils/field_value'; import { useKibana } from '../../../../hooks/use_kibana'; import { Indicator } from '../../../../../common/types/indicator'; import { useStyles } from './styles'; diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/hooks/use_investigate_in_timeline.ts b/x-pack/plugins/threat_intelligence/public/modules/timeline/hooks/use_investigate_in_timeline.ts index 904a0afc4fd93..4f79990d00c34 100644 --- a/x-pack/plugins/threat_intelligence/public/modules/timeline/hooks/use_investigate_in_timeline.ts +++ b/x-pack/plugins/threat_intelligence/public/modules/timeline/hooks/use_investigate_in_timeline.ts @@ -8,10 +8,10 @@ import { useContext } from 'react'; import moment from 'moment'; import { DataProvider } from '@kbn/timelines-plugin/common'; -import { generateDataProvider } from '../lib/data_provider'; +import { generateDataProvider } from '../utils/data_provider'; import { SecuritySolutionContext } from '../../../containers/security_solution_context'; -import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../indicators/lib/field_value'; -import { unwrapValue } from '../../indicators/lib/unwrap_value'; +import { fieldAndValueValid, getIndicatorFieldAndValue } from '../../indicators/utils/field_value'; +import { unwrapValue } from '../../indicators/utils/unwrap_value'; import { Indicator, IndicatorFieldEventEnrichmentMap, diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/lib/data_provider.test.ts b/x-pack/plugins/threat_intelligence/public/modules/timeline/utils/data_provider.test.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/timeline/lib/data_provider.test.ts rename to x-pack/plugins/threat_intelligence/public/modules/timeline/utils/data_provider.test.ts diff --git a/x-pack/plugins/threat_intelligence/public/modules/timeline/lib/data_provider.ts b/x-pack/plugins/threat_intelligence/public/modules/timeline/utils/data_provider.ts similarity index 100% rename from x-pack/plugins/threat_intelligence/public/modules/timeline/lib/data_provider.ts rename to x-pack/plugins/threat_intelligence/public/modules/timeline/utils/data_provider.ts From 636f9239fd435830cf028882f16495c84c52d29b Mon Sep 17 00:00:00 2001 From: "Joey F. Poon" Date: Mon, 26 Sep 2022 10:45:35 -0500 Subject: [PATCH 17/51] [Security Solution] add endpoint rbac (#140865) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/fleet/common/authz.test.ts | 85 +++++ x-pack/plugins/fleet/common/authz.ts | 82 +++++ .../plugins/fleet/common/constants/authz.ts | 26 ++ .../plugins/fleet/common/constants/index.ts | 1 + x-pack/plugins/fleet/common/index.ts | 2 + x-pack/plugins/fleet/public/plugin.ts | 27 +- .../plugins/fleet/server/constants/index.ts | 2 + .../plugins/fleet/server/routes/security.ts | 28 +- .../common/endpoint/service/authz/authz.ts | 6 +- .../common/experimental_features.ts | 5 + .../endpoint/use_endpoint_privileges.test.ts | 3 + .../endpoint/use_endpoint_privileges.ts | 14 +- .../public/management/links.test.ts | 16 + .../public/management/links.ts | 23 +- .../endpoint/endpoint_app_context_services.ts | 20 +- .../server/endpoint/mocks.ts | 1 + .../security_solution/server/features.ts | 340 +++++++++++++++++- .../security_solution/server/plugin.ts | 5 +- .../server/request_context_factory.ts | 10 +- 19 files changed, 658 insertions(+), 38 deletions(-) create mode 100644 x-pack/plugins/fleet/common/authz.test.ts create mode 100644 x-pack/plugins/fleet/common/constants/authz.ts diff --git a/x-pack/plugins/fleet/common/authz.test.ts b/x-pack/plugins/fleet/common/authz.test.ts new file mode 100644 index 0000000000000..ced783c6d4adb --- /dev/null +++ b/x-pack/plugins/fleet/common/authz.test.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; + +import { + calculatePackagePrivilegesFromCapabilities, + calculatePackagePrivilegesFromKibanaPrivileges, +} from './authz'; +import { ENDPOINT_PRIVILEGES } from './constants'; + +const SECURITY_SOLUTION_ID = DEFAULT_APP_CATEGORIES.security.id; + +function generateActions(privileges: string[] = [], overrides: Record = {}) { + return privileges.reduce((acc, privilege) => { + const executePackageAction = overrides[privilege] || false; + + return { + ...acc, + [privilege]: { + executePackageAction, + }, + }; + }, {}); +} + +describe('fleet authz', () => { + describe('calculatePackagePrivilegesFromCapabilities', () => { + it('calculates privileges correctly', () => { + const endpointCapabilities = { + writeEndpointList: true, + writeTrustedApplications: true, + writePolicyManagement: false, + readPolicyManagement: true, + writeHostIsolationExceptions: true, + writeHostIsolation: false, + }; + const expected = { + endpoint: { + actions: generateActions(ENDPOINT_PRIVILEGES, endpointCapabilities), + }, + }; + const actual = calculatePackagePrivilegesFromCapabilities({ + navLinks: {}, + management: {}, + catalogue: {}, + siem: endpointCapabilities, + }); + + expect(actual).toEqual(expected); + }); + }); + + describe('calculatePackagePrivilegesFromKibanaPrivileges', () => { + it('calculates privileges correctly', () => { + const endpointPrivileges = [ + { privilege: `${SECURITY_SOLUTION_ID}-writeEndpointList`, authorized: true }, + { privilege: `${SECURITY_SOLUTION_ID}-writeTrustedApplications`, authorized: true }, + { privilege: `${SECURITY_SOLUTION_ID}-writePolicyManagement`, authorized: false }, + { privilege: `${SECURITY_SOLUTION_ID}-readPolicyManagement`, authorized: true }, + { privilege: `${SECURITY_SOLUTION_ID}-writeHostIsolationExceptions`, authorized: true }, + { privilege: `${SECURITY_SOLUTION_ID}-writeHostIsolation`, authorized: false }, + { privilege: `${SECURITY_SOLUTION_ID}-ignoreMe`, authorized: true }, + ]; + const expected = { + endpoint: { + actions: generateActions(ENDPOINT_PRIVILEGES, { + writeEndpointList: true, + writeTrustedApplications: true, + writePolicyManagement: false, + readPolicyManagement: true, + writeHostIsolationExceptions: true, + writeHostIsolation: false, + }), + }, + }; + const actual = calculatePackagePrivilegesFromKibanaPrivileges(endpointPrivileges); + expect(actual).toEqual(expected); + }); + }); +}); diff --git a/x-pack/plugins/fleet/common/authz.ts b/x-pack/plugins/fleet/common/authz.ts index c8ae7b76d0403..72812576e13b3 100644 --- a/x-pack/plugins/fleet/common/authz.ts +++ b/x-pack/plugins/fleet/common/authz.ts @@ -5,6 +5,11 @@ * 2.0. */ +import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; +import type { Capabilities } from '@kbn/core-capabilities-common'; + +import { ENDPOINT_PRIVILEGES } from './constants'; + export interface FleetAuthz { fleet: { all: boolean; @@ -27,6 +32,16 @@ export interface FleetAuthz { readIntegrationPolicies: boolean; writeIntegrationPolicies: boolean; }; + + packagePrivileges?: { + [packageName: string]: { + actions: { + [key: string]: { + executePackageAction: boolean; + }; + }; + }; + }; } interface CalculateParams { @@ -72,3 +87,70 @@ export const calculateAuthz = ({ writeIntegrationPolicies: fleet.all && integrations.all, }, }); + +export function calculatePackagePrivilegesFromCapabilities( + capabilities: Capabilities | undefined +): FleetAuthz['packagePrivileges'] { + if (!capabilities) { + return {}; + } + + const endpointActions = ENDPOINT_PRIVILEGES.reduce((acc, privilege) => { + return { + ...acc, + [privilege]: { + executePackageAction: capabilities.siem[privilege] || false, + }, + }; + }, {}); + + return { + endpoint: { + actions: endpointActions, + }, + }; +} + +function getAuthorizationFromPrivileges( + kibanaPrivileges: Array<{ + resource?: string; + privilege: string; + authorized: boolean; + }>, + searchPrivilege: string +): boolean { + const privilege = kibanaPrivileges.find((p) => + p.privilege.endsWith(`${DEFAULT_APP_CATEGORIES.security.id}-${searchPrivilege}`) + ); + return privilege?.authorized || false; +} + +export function calculatePackagePrivilegesFromKibanaPrivileges( + kibanaPrivileges: + | Array<{ + resource?: string; + privilege: string; + authorized: boolean; + }> + | undefined +): FleetAuthz['packagePrivileges'] { + if (!kibanaPrivileges || !kibanaPrivileges.length) { + return {}; + } + + const endpointActions = ENDPOINT_PRIVILEGES.reduce((acc, privilege: string) => { + const kibanaPrivilege = getAuthorizationFromPrivileges(kibanaPrivileges, privilege); + return { + ...acc, + [privilege]: { + executePackageAction: kibanaPrivilege, + }, + }; + }, {}); + + return { + endpoint: { + actions: endpointActions, + }, + }; +} diff --git a/x-pack/plugins/fleet/common/constants/authz.ts b/x-pack/plugins/fleet/common/constants/authz.ts new file mode 100644 index 0000000000000..3bf1aeb46adc8 --- /dev/null +++ b/x-pack/plugins/fleet/common/constants/authz.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const ENDPOINT_PRIVILEGES = [ + 'writeEndpointList', + 'readEndpointList', + 'writeTrustedApplications', + 'readTrustedApplications', + 'writeHostIsolationExceptions', + 'readHostIsolationExceptions', + 'writeBlocklist', + 'readBlocklist', + 'writeEventFilters', + 'readEventFilters', + 'writePolicyManagement', + 'readPolicyManagement', + 'writeActionsLogManagement', + 'readActionsLogManagement', + 'writeHostIsolation', + 'writeProcessOperations', + 'writeFileOperations', +]; diff --git a/x-pack/plugins/fleet/common/constants/index.ts b/x-pack/plugins/fleet/common/constants/index.ts index 615a48f7493cf..955abb6b7456c 100644 --- a/x-pack/plugins/fleet/common/constants/index.ts +++ b/x-pack/plugins/fleet/common/constants/index.ts @@ -16,6 +16,7 @@ export * from './enrollment_api_key'; export * from './settings'; export * from './preconfiguration'; export * from './download_source'; +export * from './authz'; // TODO: This is the default `index.max_result_window` ES setting, which dictates // the maximum amount of results allowed to be returned from a search. It's possible diff --git a/x-pack/plugins/fleet/common/index.ts b/x-pack/plugins/fleet/common/index.ts index d9e3fd8b9ceb6..e8995b4bf6b74 100644 --- a/x-pack/plugins/fleet/common/index.ts +++ b/x-pack/plugins/fleet/common/index.ts @@ -48,6 +48,8 @@ export { // Should probably be removed SO_SEARCH_LIMIT, // Statuses + // Authz + ENDPOINT_PRIVILEGES, } from './constants'; export { // Route services diff --git a/x-pack/plugins/fleet/public/plugin.ts b/x-pack/plugins/fleet/public/plugin.ts index 5b5a31461c911..b1d845aa9e52f 100644 --- a/x-pack/plugins/fleet/public/plugin.ts +++ b/x-pack/plugins/fleet/public/plugin.ts @@ -46,7 +46,7 @@ import type { GlobalSearchPluginSetup } from '@kbn/global-search-plugin/public'; import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { PLUGIN_ID, INTEGRATIONS_PLUGIN_ID, setupRouteService, appRoutesService } from '../common'; -import { calculateAuthz } from '../common/authz'; +import { calculateAuthz, calculatePackagePrivilegesFromCapabilities } from '../common/authz'; import { parseExperimentalConfigValue } from '../common/experimental_features'; import type { CheckPermissionsResponse, PostFleetSetupResponse } from '../common/types'; import type { FleetAuthz } from '../common'; @@ -277,17 +277,20 @@ export class FleetPlugin implements Plugin { const permissionsResponse = await getPermissions(); diff --git a/x-pack/plugins/fleet/server/constants/index.ts b/x-pack/plugins/fleet/server/constants/index.ts index 87f0b5eeedfcf..cd0c0262a77d2 100644 --- a/x-pack/plugins/fleet/server/constants/index.ts +++ b/x-pack/plugins/fleet/server/constants/index.ts @@ -64,6 +64,8 @@ export { DEFAULT_DOWNLOAD_SOURCE_URI, DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, DEFAULT_DOWNLOAD_SOURCE_ID, + // Authz + ENDPOINT_PRIVILEGES, } from '../../common/constants'; export { diff --git a/x-pack/plugins/fleet/server/routes/security.ts b/x-pack/plugins/fleet/server/routes/security.ts index 410bd9a5b9224..da90480944a46 100644 --- a/x-pack/plugins/fleet/server/routes/security.ts +++ b/x-pack/plugins/fleet/server/routes/security.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; import type { IRouter, RouteConfig, @@ -17,11 +18,11 @@ import type { import type { FleetAuthz } from '../../common'; import { INTEGRATIONS_PLUGIN_ID } from '../../common'; -import { calculateAuthz } from '../../common/authz'; +import { calculateAuthz, calculatePackagePrivilegesFromKibanaPrivileges } from '../../common/authz'; import { appContextService } from '../services'; import type { FleetRequestHandlerContext } from '../types'; -import { PLUGIN_ID } from '../constants'; +import { PLUGIN_ID, ENDPOINT_PRIVILEGES } from '../constants'; function checkSecurityEnabled() { return appContextService.getSecurityLicense().isEnabled(); @@ -63,12 +64,16 @@ export async function getAuthzFromRequest(req: KibanaRequest): Promise + security.authz.actions.api.get(`${DEFAULT_APP_CATEGORIES.security.id}-${privilege}`) + ); const { privileges } = await checkPrivileges({ kibana: [ security.authz.actions.api.get(`${PLUGIN_ID}-all`), security.authz.actions.api.get(`${PLUGIN_ID}-setup`), security.authz.actions.api.get(`${INTEGRATIONS_PLUGIN_ID}-all`), security.authz.actions.api.get(`${INTEGRATIONS_PLUGIN_ID}-read`), + ...endpointPrivileges, ], }); const fleetAllAuth = getAuthorizationFromPrivileges(privileges.kibana, `${PLUGIN_ID}-all`); @@ -82,14 +87,17 @@ export async function getAuthzFromRequest(req: KibanaRequest): Promise + fleetAuthz: FleetAuthz, + userRoles: MaybeImmutable, + // to be used in follow-up PRs + isEndpointRbacEnabled: boolean = false ): EndpointAuthz => { const isPlatinumPlusLicense = licenseService.isPlatinumPlus(); const isEnterpriseLicense = licenseService.isEnterprise(); diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index fe65aab259395..aa581971e5f09 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -59,6 +59,11 @@ export const allowedExperimentalValues = Object.freeze({ * Enables the detection response actions in rule + alerts */ responseActionsEnabled: true, + + /** + * Enables endpoint package level rbac + */ + endpointRbacEnabled: false, }); type ExperimentalConfigKeys = Array; diff --git a/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.test.ts b/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.test.ts index c499861e6abfb..29da5688357b0 100644 --- a/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.test.ts @@ -29,6 +29,9 @@ jest.mock('../../../hooks/use_license', () => { }, }; }); +jest.mock('../../../hooks/use_experimental_features', () => ({ + useIsExperimentalFeatureEnabled: jest.fn((feature: string) => feature === 'endpointRbacEnabled'), +})); const licenseServiceMock = licenseService as jest.Mocked; diff --git a/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.ts b/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.ts index d0a1057d9f00e..7d7233312fecc 100644 --- a/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.ts +++ b/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.ts @@ -19,6 +19,7 @@ import { getEndpointAuthzInitialState, } from '../../../../../common/endpoint/service/authz'; import { useSecuritySolutionStartDependencies } from './security_solution_start_dependencies'; +import { useIsExperimentalFeatureEnabled } from '../../../hooks/use_experimental_features'; /** * Retrieve the endpoint privileges for the current user. @@ -41,17 +42,26 @@ export const useEndpointPrivileges = (): Immutable => { const [userRoles, setUserRoles] = useState>([]); const fleetServices = fleetServicesFromUseKibana ?? fleetServicesFromPluginStart; + const isEndpointRbacEnabled = useIsExperimentalFeatureEnabled('endpointRbacEnabled'); const privileges = useMemo(() => { const privilegeList: EndpointPrivileges = Object.freeze({ loading: !fleetCheckDone || !userRolesCheckDone || !user, ...(fleetAuthz - ? calculateEndpointAuthz(licenseService, fleetAuthz, userRoles) + ? calculateEndpointAuthz(licenseService, fleetAuthz, userRoles, isEndpointRbacEnabled) : getEndpointAuthzInitialState()), }); return privilegeList; - }, [fleetCheckDone, userRolesCheckDone, user, fleetAuthz, licenseService, userRoles]); + }, [ + fleetCheckDone, + userRolesCheckDone, + user, + fleetAuthz, + licenseService, + userRoles, + isEndpointRbacEnabled, + ]); // Check if user can access fleet useEffect(() => { diff --git a/x-pack/plugins/security_solution/public/management/links.test.ts b/x-pack/plugins/security_solution/public/management/links.test.ts index 7d386b6d6c5e0..09c47bc70095c 100644 --- a/x-pack/plugins/security_solution/public/management/links.test.ts +++ b/x-pack/plugins/security_solution/public/management/links.test.ts @@ -7,10 +7,13 @@ import type { HttpSetup } from '@kbn/core/public'; import { coreMock } from '@kbn/core/public/mocks'; + import { SecurityPageName } from '../app/types'; import { licenseService } from '../common/hooks/use_license'; import type { StartPlugins } from '../types'; import { links, getManagementFilteredLinks } from './links'; +import { allowedExperimentalValues } from '../../common/experimental_features'; +import { ExperimentalFeaturesService } from '../common/experimental_features_service'; jest.mock('../common/hooks/use_license', () => { const licenseServiceInstance = { @@ -30,6 +33,12 @@ describe('links', () => { let getPlugins: (roles: string[]) => StartPlugins; let fakeHttpServices: jest.Mocked; + beforeAll(() => { + ExperimentalFeaturesService.init({ + experimentalFeatures: { ...allowedExperimentalValues }, + }); + }); + beforeEach(() => { coreMockStarted = coreMock.createStart(); fakeHttpServices = coreMockStarted.http as jest.Mocked; @@ -41,6 +50,13 @@ describe('links', () => { getCurrentUser: jest.fn().mockReturnValue({ roles }), }, }, + fleet: { + authz: { + fleet: { + all: true, + }, + }, + }, } as unknown as StartPlugins); }); diff --git a/x-pack/plugins/security_solution/public/management/links.ts b/x-pack/plugins/security_solution/public/management/links.ts index 659fb7a8216a5..54c729e41911d 100644 --- a/x-pack/plugins/security_solution/public/management/links.ts +++ b/x-pack/plugins/security_solution/public/management/links.ts @@ -7,7 +7,11 @@ import type { CoreStart } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; -import { calculateEndpointAuthz } from '../../common/endpoint/service/authz'; + +import { + calculateEndpointAuthz, + getEndpointAuthzInitialState, +} from '../../common/endpoint/service/authz'; import { BLOCKLIST_PATH, ENDPOINTS_PATH, @@ -53,6 +57,7 @@ import { IconHostIsolation } from './icons/host_isolation'; import { IconSiemRules } from './icons/siem_rules'; import { IconTrustedApplications } from './icons/trusted_applications'; import { HostIsolationExceptionsApiClient } from './pages/host_isolation_exceptions/host_isolation_exceptions_api_client'; +import { ExperimentalFeaturesService } from '../common/experimental_features_service'; const categories = [ { @@ -230,13 +235,19 @@ export const getManagementFilteredLinks = async ( core: CoreStart, plugins: StartPlugins ): Promise => { + const fleetAuthz = plugins.fleet?.authz; + const isEndpointRbacEnabled = ExperimentalFeaturesService.get().endpointRbacEnabled; + try { const currentUserResponse = await plugins.security.authc.getCurrentUser(); - const privileges = calculateEndpointAuthz( - licenseService, - plugins.fleet?.authz, - currentUserResponse.roles - ); + const privileges = fleetAuthz + ? calculateEndpointAuthz( + licenseService, + fleetAuthz, + currentUserResponse.roles, + isEndpointRbacEnabled + ) + : getEndpointAuthzInitialState(); if (!privileges.canAccessEndpointManagement) { return getFilteredLinks([SecurityPageName.hostIsolationExceptions]); } diff --git a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts index 59deaae59f450..06d54a4353958 100644 --- a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts +++ b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts @@ -42,6 +42,7 @@ import { registerListsPluginEndpointExtensionPoints } from '../lists_integration import type { EndpointAuthz } from '../../common/endpoint/types/authz'; import { calculateEndpointAuthz } from '../../common/endpoint/service/authz'; import type { FeatureUsageService } from './services/feature_usage/service'; +import type { ExperimentalFeatures } from '../../common/experimental_features'; export interface EndpointAppContextServiceSetupContract { securitySolutionRequestContextFactory: IRequestContextFactory; @@ -67,6 +68,7 @@ export type EndpointAppContextServiceStartContract = Partial< exceptionListsClient: ExceptionListClient | undefined; cases: CasesPluginStartContract | undefined; featureUsageService: FeatureUsageService; + experimentalFeatures: ExperimentalFeatures; }; /** @@ -161,8 +163,14 @@ export class EndpointAppContextService { public async getEndpointAuthz(request: KibanaRequest): Promise { const fleetAuthz = await this.getFleetAuthzService().fromRequest(request); const userRoles = this.startDependencies?.security.authc.getCurrentUser(request)?.roles ?? []; - - return calculateEndpointAuthz(this.getLicenseService(), fleetAuthz, userRoles); + const isEndpointRbacEnabled = this.experimentalFeatures.endpointRbacEnabled; + + return calculateEndpointAuthz( + this.getLicenseService(), + fleetAuthz, + userRoles, + isEndpointRbacEnabled + ); } public getEndpointMetadataService(): EndpointMetadataService { @@ -222,4 +230,12 @@ export class EndpointAppContextService { } return this.startDependencies.featureUsageService; } + + public get experimentalFeatures(): ExperimentalFeatures { + if (this.startDependencies == null) { + throw new EndpointAppContentServicesNotStartedError(); + } + + return this.startDependencies.experimentalFeatures; + } } diff --git a/x-pack/plugins/security_solution/server/endpoint/mocks.ts b/x-pack/plugins/security_solution/server/endpoint/mocks.ts index 8b9623b51b24c..50785f9c29bf9 100644 --- a/x-pack/plugins/security_solution/server/endpoint/mocks.ts +++ b/x-pack/plugins/security_solution/server/endpoint/mocks.ts @@ -158,6 +158,7 @@ export const createMockEndpointAppContextServiceStartContract = getCasesClientWithRequest: jest.fn(async () => casesClientMock), }, featureUsageService: createFeatureUsageServiceMock(), + experimentalFeatures: createMockConfig().experimentalFeatures, }; }; diff --git a/x-pack/plugins/security_solution/server/features.ts b/x-pack/plugins/security_solution/server/features.ts index 2a794285b52b7..fc3307a650097 100644 --- a/x-pack/plugins/security_solution/server/features.ts +++ b/x-pack/plugins/security_solution/server/features.ts @@ -11,8 +11,10 @@ import type { KibanaFeatureConfig } from '@kbn/features-plugin/common'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common'; import { createUICapabilities } from '@kbn/cases-plugin/common'; + import { APP_ID, CASES_FEATURE_ID, SERVER_APP_ID } from '../common/constants'; import { savedObjectTypes } from './saved_objects'; +import type { ConfigType } from './config'; export const getCasesKibanaFeature = (): KibanaFeatureConfig => { const casesCapabilities = createUICapabilities(); @@ -99,7 +101,10 @@ const CLOUD_POSTURE_APP_ID = 'csp'; // Same as the saved-object type for rules defined by Cloud Security Posture const CLOUD_POSTURE_SAVED_OBJECT_RULE_TYPE = 'csp_rule'; -export const getKibanaPrivilegesFeaturePrivileges = (ruleTypes: string[]): KibanaFeatureConfig => ({ +export const getKibanaPrivilegesFeaturePrivileges = ( + ruleTypes: string[], + experimentalFeatures: ConfigType['experimentalFeatures'] +): KibanaFeatureConfig => ({ id: SERVER_APP_ID, name: i18n.translate('xpack.securitySolution.featureRegistry.linkSecuritySolutionTitle', { defaultMessage: 'Security', @@ -112,7 +117,6 @@ export const getKibanaPrivilegesFeaturePrivileges = (ruleTypes: string[]): Kiban insightsAndAlerting: ['triggersActions'], }, alerting: ruleTypes, - subFeatures: [], privileges: { all: { app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], @@ -178,4 +182,336 @@ export const getKibanaPrivilegesFeaturePrivileges = (ruleTypes: string[]): Kiban ui: ['show'], }, }, + subFeatures: experimentalFeatures.endpointRbacEnabled + ? [ + { + name: i18n.translate('xpack.securitySolution.featureRegistry.subFeatures.endpointList', { + defaultMessage: 'Endpoint List', + }), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [`${APP_ID}-writeEndpointList`, `${APP_ID}-readEndpointList`], + id: 'endpoint_list_all', + includeIn: 'all', + name: 'All', + savedObject: { + all: [], + read: [], + }, + ui: ['writeEndpointList', 'readEndpointList'], + }, + { + api: [`${APP_ID}-readEndpointList`], + id: 'endpoint_list_read', + includeIn: 'read', + name: 'Read', + savedObject: { + all: [], + read: [], + }, + ui: ['readEndpointList'], + }, + ], + }, + ], + }, + { + name: i18n.translate( + 'xpack.securitySolution.featureRegistry.subFeatures.trustedApplications', + { + defaultMessage: 'Trusted Applications', + } + ), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [`${APP_ID}-writeTrustedApplications`, `${APP_ID}-readTrustedApplications`], + id: 'trusted_applications_all', + includeIn: 'all', + name: 'All', + savedObject: { + all: [], + read: [], + }, + ui: ['writeTrustedApplications', 'readTrustedApplications'], + }, + { + api: [`${APP_ID}-readTrustedApplications`], + id: 'trusted_applications_read', + includeIn: 'read', + name: 'Read', + savedObject: { + all: [], + read: [], + }, + ui: ['readTrustedApplications'], + }, + ], + }, + ], + }, + { + name: i18n.translate( + 'xpack.securitySolution.featureRegistry.subFeatures.hostIsolationExceptions', + { + defaultMessage: 'Host Isolation Exceptions', + } + ), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [ + `${APP_ID}-writeHostIsolationExceptions`, + `${APP_ID}-readHostIsolationExceptions`, + ], + id: 'host_isolation_exceptions_all', + includeIn: 'all', + name: 'All', + savedObject: { + all: [], + read: [], + }, + ui: ['writeHostIsolationExceptions', 'readHostIsolationExceptions'], + }, + { + api: [`${APP_ID}-readHostIsolationExceptions`], + id: 'host_isolation_exceptions_read', + includeIn: 'read', + name: 'Read', + savedObject: { + all: [], + read: [], + }, + ui: ['readHostIsolationExceptions'], + }, + ], + }, + ], + }, + { + name: i18n.translate('xpack.securitySolution.featureRegistry.subFeatures.blockList', { + defaultMessage: 'Blocklist', + }), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [`${APP_ID}-writeBlocklist`, `${APP_ID}-readBlocklist`], + id: 'blocklist_all', + includeIn: 'all', + name: 'All', + savedObject: { + all: [], + read: [], + }, + ui: ['writeBlocklist', 'readBlocklist'], + }, + { + api: [`${APP_ID}-readBlocklist`], + id: 'blocklist_read', + includeIn: 'read', + name: 'Read', + savedObject: { + all: [], + read: [], + }, + ui: ['readBlocklist'], + }, + ], + }, + ], + }, + { + name: i18n.translate('xpack.securitySolution.featureRegistry.subFeatures.eventFilters', { + defaultMessage: 'Event Filters', + }), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [`${APP_ID}-writeEventFilters`, `${APP_ID}-readEventFilters`], + id: 'event_filters_all', + includeIn: 'all', + name: 'All', + savedObject: { + all: [], + read: [], + }, + ui: ['writeEventFilters', 'readEventFilters'], + }, + { + api: [`${APP_ID}-readEventFilters`], + id: 'event_filters_read', + includeIn: 'read', + name: 'Read', + savedObject: { + all: [], + read: [], + }, + ui: ['readEventFilters'], + }, + ], + }, + ], + }, + { + name: i18n.translate( + 'xpack.securitySolution.featureRegistry.subFeatures.policyManagement', + { + defaultMessage: 'Policy Management', + } + ), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [`${APP_ID}-writePolicyManagement`, `${APP_ID}-readPolicyManagement`], + id: 'policy_management_all', + includeIn: 'all', + name: 'All', + savedObject: { + all: [], + read: [], + }, + ui: ['writePolicyManagement', 'readPolicyManagement'], + }, + { + api: [`${APP_ID}-readPolicyManagement`], + id: 'policy_management_read', + includeIn: 'read', + name: 'Read', + savedObject: { + all: [], + read: [], + }, + ui: ['readPolicyManagement'], + }, + ], + }, + ], + }, + { + name: i18n.translate( + 'xpack.securitySolution.featureRegistry.subFeatures.actionsLogManagement', + { + defaultMessage: 'Actions Log Management', + } + ), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [ + `${APP_ID}-writeActionsLogManagement`, + `${APP_ID}-readActionsLogManagement`, + ], + id: 'actions_log_management_all', + includeIn: 'all', + name: 'All', + savedObject: { + all: [], + read: [], + }, + ui: ['writeActionsLogManagement', 'readActionsLogManagement'], + }, + { + api: [`${APP_ID}-readActionsLogManagement`], + id: 'actions_log_management_read', + includeIn: 'read', + name: 'Read', + savedObject: { + all: [], + read: [], + }, + ui: ['readActionsLogManagement'], + }, + ], + }, + ], + }, + { + name: i18n.translate('xpack.securitySolution.featureRegistry.subFeatures.hostIsolation', { + defaultMessage: 'Host Isolation', + }), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [`${APP_ID}-writeHostIsolation`], + id: 'host_isolation_all', + includeIn: 'all', + name: 'All', + savedObject: { + all: [], + read: [], + }, + ui: ['writeHostIsolation'], + }, + ], + }, + ], + }, + { + name: i18n.translate( + 'xpack.securitySolution.featureRegistry.subFeatures.processOperations', + { + defaultMessage: 'Process Operations', + } + ), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [`${APP_ID}-writeProcessOperations`], + id: 'process_operations_all', + includeIn: 'all', + name: 'All', + savedObject: { + all: [], + read: [], + }, + ui: ['writeProcessOperations'], + }, + ], + }, + ], + }, + { + name: i18n.translate('xpack.securitySolution.featureRegistr.subFeatures.fileOperations', { + defaultMessage: 'File Operations', + }), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + api: [`${APP_ID}-writeFileOperations`], + id: 'file_operations_all', + includeIn: 'all', + name: 'All', + savedObject: { + all: [], + read: [], + }, + ui: ['writeFileOperations'], + }, + ], + }, + ], + }, + ] + : [], }); diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index 0552f9bb2bd00..a71048462b5e6 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -307,7 +307,9 @@ export class Plugin implements ISecuritySolutionPlugin { NEW_TERMS_RULE_TYPE_ID, ]; - plugins.features.registerKibanaFeature(getKibanaPrivilegesFeaturePrivileges(ruleTypes)); + plugins.features.registerKibanaFeature( + getKibanaPrivilegesFeaturePrivileges(ruleTypes, experimentalFeatures) + ); plugins.features.registerKibanaFeature(getCasesKibanaFeature()); if (plugins.alerting != null) { @@ -471,6 +473,7 @@ export class Plugin implements ISecuritySolutionPlugin { exceptionListsClient: exceptionListClient, registerListsServerExtension: this.lists?.registerExtension, featureUsageService, + experimentalFeatures: config.experimentalFeatures, }); this.telemetryReceiver.start( diff --git a/x-pack/plugins/security_solution/server/request_context_factory.ts b/x-pack/plugins/security_solution/server/request_context_factory.ts index b0eb6b1d7dbd9..730cbd259f50e 100644 --- a/x-pack/plugins/security_solution/server/request_context_factory.ts +++ b/x-pack/plugins/security_solution/server/request_context_factory.ts @@ -79,6 +79,9 @@ export class RequestContextFactory implements IRequestContextFactory { (await context.fleet)?.authz ?? (await startPlugins.fleet?.authz.fromRequest(request)); } + const isEndpointRbacEnabled = + endpointAppContextService.experimentalFeatures.endpointRbacEnabled; + const coreContext = await context.core; return { @@ -92,7 +95,12 @@ export class RequestContextFactory implements IRequestContextFactory { endpointAuthz = getEndpointAuthzInitialState(); } else { const userRoles = security?.authc.getCurrentUser(request)?.roles ?? []; - endpointAuthz = calculateEndpointAuthz(licenseService, fleetAuthz, userRoles); + endpointAuthz = calculateEndpointAuthz( + licenseService, + fleetAuthz, + userRoles, + isEndpointRbacEnabled + ); } } From a864509f2d98d34b2ba0890c49f62e3afbc47bac Mon Sep 17 00:00:00 2001 From: Kyle Pollich Date: Mon, 26 Sep 2022 11:50:49 -0400 Subject: [PATCH 18/51] Check for bundled package dir once during setup (#141660) --- .../services/epm/packages/bundled_packages.ts | 8 +++++ x-pack/plugins/fleet/server/services/setup.ts | 30 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/server/services/epm/packages/bundled_packages.ts b/x-pack/plugins/fleet/server/services/epm/packages/bundled_packages.ts index e18b64d8daae8..ede8a25ca254f 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/bundled_packages.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/bundled_packages.ts @@ -22,6 +22,14 @@ export async function getBundledPackages(): Promise { throw new FleetError('xpack.fleet.developer.bundledPackageLocation is not configured'); } + // If the bundled package directory is missing, we log a warning during setup, + // so we can safely ignore this case here and just retun and empty array + try { + await fs.stat(bundledPackageLocation); + } catch (error) { + return []; + } + try { const dirContents = await fs.readdir(bundledPackageLocation); const zipFiles = dirContents.filter((file) => file.endsWith('.zip')); diff --git a/x-pack/plugins/fleet/server/services/setup.ts b/x-pack/plugins/fleet/server/services/setup.ts index e9b26e50735b9..f536125e054a2 100644 --- a/x-pack/plugins/fleet/server/services/setup.ts +++ b/x-pack/plugins/fleet/server/services/setup.ts @@ -5,6 +5,8 @@ * 2.0. */ +import fs from 'fs/promises'; + import { compact } from 'lodash'; import pMap from 'p-map'; import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; @@ -31,7 +33,7 @@ import { outputService } from './output'; import { downloadSourceService } from './download_source'; import { generateEnrollmentAPIKey, hasEnrollementAPIKeysForPolicy } from './api_keys'; -import { settingsService } from '.'; +import { getRegistryUrl, settingsService } from '.'; import { awaitIfPending } from './setup_utils'; import { ensureFleetFinalPipelineIsInstalled } from './epm/elasticsearch/ingest_pipeline/install'; import { ensureDefaultComponentTemplates } from './epm/elasticsearch/template/install'; @@ -64,6 +66,8 @@ async function createSetupSideEffects( const logger = appContextService.getLogger(); logger.info('Beginning fleet setup'); + await ensureFleetDirectories(); + const { agentPolicies: policiesOrUndefined, packages: packagesOrUndefined } = appContextService.getConfig() ?? {}; @@ -266,3 +270,27 @@ export function formatNonFatalErrors( } }); } + +/** + * Confirm existence of various directories used by Fleet and warn if they don't exist + */ +export async function ensureFleetDirectories() { + const logger = appContextService.getLogger(); + const config = appContextService.getConfig(); + + const bundledPackageLocation = config?.developer?.bundledPackageLocation; + const registryUrl = getRegistryUrl(); + + if (!bundledPackageLocation) { + logger.warn('xpack.fleet.developer.bundledPackageLocation is not configured'); + return; + } + + try { + await fs.stat(bundledPackageLocation); + } catch (error) { + logger.warn( + `Bundled package directory ${bundledPackageLocation} does not exist. All packages will be sourced from ${registryUrl}.` + ); + } +} From 249b59646500b343f979e483d13fca67e61ecb2f Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 26 Sep 2022 10:56:31 -0500 Subject: [PATCH 19/51] [journeys] restart ES for each journey, fix flakiness (#141530) --- .buildkite/pipelines/performance/daily.yml | 6 + .../functional/performance_playwright.sh | 110 +++++++++++++----- .../scalability_dataset_extraction.sh | 15 ++- .../report_failures_to_file.ts | 24 +++- ...report_failures_to_file_html_template.html | 61 ++++++++-- .../journey/journey_ftr_config.ts | 2 +- .../journey/journey_ftr_harness.ts | 14 ++- .../journey/journey_screenshots.ts | 16 ++- x-pack/performance/jest.config.js | 12 ++ x-pack/performance/services/lib/time.test.ts | 26 +++++ x-pack/performance/services/lib/time.ts | 41 +++++++ x-pack/performance/services/toasts.ts | 15 ++- x-pack/performance/tsconfig.json | 2 +- 13 files changed, 291 insertions(+), 53 deletions(-) create mode 100644 x-pack/performance/jest.config.js create mode 100644 x-pack/performance/services/lib/time.test.ts create mode 100644 x-pack/performance/services/lib/time.ts diff --git a/.buildkite/pipelines/performance/daily.yml b/.buildkite/pipelines/performance/daily.yml index 10f137a5c5088..ea7e406ba63d8 100644 --- a/.buildkite/pipelines/performance/daily.yml +++ b/.buildkite/pipelines/performance/daily.yml @@ -20,6 +20,12 @@ steps: depends_on: build key: tests timeout_in_minutes: 60 + retry: + automatic: + - exit_status: '-1' + limit: 3 + - exit_status: '*' + limit: 1 - label: '🚢 Performance Tests dataset extraction for scalability benchmarking' command: .buildkite/scripts/steps/functional/scalability_dataset_extraction.sh diff --git a/.buildkite/scripts/steps/functional/performance_playwright.sh b/.buildkite/scripts/steps/functional/performance_playwright.sh index 111825b3b03a0..6f0399b2de90d 100644 --- a/.buildkite/scripts/steps/functional/performance_playwright.sh +++ b/.buildkite/scripts/steps/functional/performance_playwright.sh @@ -11,26 +11,9 @@ is_test_execution_step rm -rf "$KIBANA_BUILD_LOCATION" .buildkite/scripts/download_build_artifacts.sh -echo "--- 🦺 Starting Elasticsearch" - -node scripts/es snapshot& -export esPid=$! -trap 'kill ${esPid}' EXIT - -export TEST_ES_URL=http://elastic:changeme@localhost:9200 -export TEST_ES_DISABLE_STARTUP=true - -# Pings the es server every second for up to 2 minutes until it is green -curl \ - --fail \ - --silent \ - --retry 120 \ - --retry-delay 1 \ - --retry-connrefused \ - -XGET "${TEST_ES_URL}/_cluster/health?wait_for_nodes=>=1&wait_for_status=yellow" \ - > /dev/null - -echo "✅ ES is ready and will continue to run in the background" +function is_running { + kill -0 "$1" &>/dev/null +} # unset env vars defined in other parts of CI for automatic APM collection of # Kibana. We manage APM config in our FTR config and performance service, and @@ -46,29 +29,100 @@ unset ELASTIC_APM_SERVER_URL unset ELASTIC_APM_SECRET_TOKEN unset ELASTIC_APM_GLOBAL_LABELS -journeys=("login" "ecommerce_dashboard" "flight_dashboard" "web_logs_dashboard" "promotion_tracking_dashboard" "many_fields_discover" "data_stress_test_lens") +# `kill $esPid` doesn't work, seems that kbn-es doesn't listen to signals correctly, this does work +trap 'killall node -q' EXIT + +export TEST_ES_URL=http://elastic:changeme@localhost:9200 +export TEST_ES_DISABLE_STARTUP=true + +echo "--- determining which journeys to run" + +journeys=$(buildkite-agent meta-data get "failed-journeys" --default '') +if [ "$journeys" != "" ]; then + echo "re-running failed journeys:${journeys}" +else + paths=() + for path in x-pack/performance/journeys/*; do + paths+=("$path") + done + journeys=$(printf "%s\n" "${paths[@]}") + echo "running discovered journeys:${journeys}" +fi + +# track failed journeys here which might get written to metadata +failedJourneys=() + +while read -r journey; do + if [ "$journey" == "" ]; then + continue; + fi + + echo "--- $journey - 🔎 Start es" -for journey in "${journeys[@]}"; do - set +e + node scripts/es snapshot& + export esPid=$! + + # Pings the es server every second for up to 2 minutes until it is green + curl \ + --fail \ + --silent \ + --retry 120 \ + --retry-delay 1 \ + --retry-connrefused \ + -XGET "${TEST_ES_URL}/_cluster/health?wait_for_nodes=>=1&wait_for_status=yellow" \ + > /dev/null + + echo "✅ ES is ready and will run in the background" phases=("WARMUP" "TEST") + status=0 for phase in "${phases[@]}"; do echo "--- $journey - $phase" export TEST_PERFORMANCE_PHASE="$phase" + + set +e node scripts/functional_tests \ - --config "x-pack/performance/journeys/$journey.ts" \ + --config "$journey" \ --kibana-install-dir "$KIBANA_BUILD_LOCATION" \ --debug \ --bail - status=$? + set -e + if [ $status -ne 0 ]; then + failedJourneys+=("$journey") echo "^^^ +++" echo "❌ FTR failed with status code: $status" - exit 1 + break + fi + done + + # remove trap, we're manually shutting down + trap - EXIT; + + echo "--- $journey - 🔎 Shutdown ES" + killall node + echo "waiting for $esPid to exit gracefully"; + + timeout=30 #seconds + dur=0 + while is_running $esPid; do + sleep 1; + ((dur=dur+1)) + if [ $dur -ge $timeout ]; then + echo "es still running after $dur seconds, killing ES and node forcefully"; + killall -SIGKILL java + killall -SIGKILL node + sleep 5; fi done +done <<< "$journeys" + +echo "--- report/record failed journeys" +if [ "${failedJourneys[*]}" != "" ]; then + buildkite-agent meta-data set "failed-journeys" "$(printf "%s\n" "${failedJourneys[@]}")" - set -e -done + echo "failed journeys: ${failedJourneys[*]}" + exit 1 +fi diff --git a/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh b/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh index a2b81f538b92b..aff087005ac5c 100755 --- a/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh +++ b/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh @@ -46,8 +46,13 @@ cd "${OUTPUT_DIR}/.." gsutil -m cp -r "${BUILD_ID}" "${GCS_BUCKET}" cd - -echo "--- Promoting '${BUILD_ID}' dataset to LATEST" -cd "${OUTPUT_DIR}/.." -echo "${BUILD_ID}" > latest -gsutil cp latest "${GCS_BUCKET}" -cd - +if [ "$BUILDKITE_PIPELINE_SLUG" == "kibana-single-user-performance" ]; then + echo "--- Promoting '${BUILD_ID}' dataset to LATEST" + cd "${OUTPUT_DIR}/.." + echo "${BUILD_ID}" > latest + gsutil cp latest "${GCS_BUCKET}" + cd - +else + echo "--- Skipping promotion of dataset to LATEST" + echo "$BUILDKITE_PIPELINE_SLUG is not 'kibana-single-user-performance', so skipping" +fi diff --git a/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file.ts index d34df80f3d0a8..da643164a14aa 100644 --- a/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file.ts +++ b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file.ts @@ -44,12 +44,26 @@ async function getJourneySnapshotHtml(log: ToolingLog, journeyMeta: JourneyMeta) return [ '

    ', '
    Steps
    ', - ...screenshots.get().flatMap(({ title, path }) => { + ...screenshots.get().flatMap(({ title, path, fullscreenPath }) => { const base64 = Fs.readFileSync(path, 'base64'); + const fullscreenBase64 = Fs.readFileSync(fullscreenPath, 'base64'); return [ `

    ${escape(title)}

    `, - ``, + `
    + + + + +
    `, ]; }), '
    ', @@ -88,7 +102,11 @@ function getFtrScreenshotHtml(log: ToolingLog, failureName: string) { .filter((s) => s.name.startsWith(FtrScreenshotFilename.create(failureName, { ext: false }))) .map((s) => { const base64 = Fs.readFileSync(s.path).toString('base64'); - return ``; + return ` +
    + +
    + `; }) .join('\n'); } diff --git a/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file_html_template.html b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file_html_template.html index 485a2c2d4eb3f..01ebc4ba22210 100644 --- a/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file_html_template.html +++ b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file_html_template.html @@ -16,12 +16,24 @@ img.screenshot { cursor: pointer; - height: 200px; margin: 5px 0; } + .screenshotContainer:not(.expanded) img.screenshot { + height: 200px; + } + + .screenshotContainer:not(.fs) img.screenshot.fs, + .screenshotContainer:not(.fs) button.toggleFs.off, + .screenshotContainer.fs img.screenshot:not(.fs), + .screenshotContainer.fs button.toggleFs.on { + display: none; + } - img.screenshot.expanded { - height: auto; + .screenshotContainer .toggleFs { + background: none; + border: none; + margin: 0 0 0 5px; + vertical-align: top; } $TITLE @@ -31,11 +43,46 @@
    $MAIN
diff --git a/packages/kbn-journeys/journey/journey_ftr_config.ts b/packages/kbn-journeys/journey/journey_ftr_config.ts index 392ad69b63ba1..b0d8e33ad01c0 100644 --- a/packages/kbn-journeys/journey/journey_ftr_config.ts +++ b/packages/kbn-journeys/journey/journey_ftr_config.ts @@ -82,7 +82,7 @@ export function makeFtrConfigProvider( kbnTestServer: { ...baseConfig.kbnTestServer, // delay shutdown by 15 seconds to ensure that APM can report the data it collects during test execution - delayShutdown: 15_000, + delayShutdown: process.env.TEST_PERFORMANCE_PHASE === 'TEST' ? 15_000 : 0, serverArgs: [ ...baseConfig.kbnTestServer.serverArgs, diff --git a/packages/kbn-journeys/journey/journey_ftr_harness.ts b/packages/kbn-journeys/journey/journey_ftr_harness.ts index 672b14f0e1a85..6154581738ac7 100644 --- a/packages/kbn-journeys/journey/journey_ftr_harness.ts +++ b/packages/kbn-journeys/journey/journey_ftr_harness.ts @@ -198,7 +198,12 @@ export class JourneyFtrHarness { return; } - await this.screenshots.addSuccess(step, await this.page.screenshot()); + const [screenshot, fs] = await Promise.all([ + this.page.screenshot(), + this.page.screenshot({ fullPage: true }), + ]); + + await this.screenshots.addSuccess(step, screenshot, fs); } private async onStepError(step: AnyStep, err: Error) { @@ -208,7 +213,12 @@ export class JourneyFtrHarness { } if (this.page) { - await this.screenshots.addError(step, await this.page.screenshot()); + const [screenshot, fs] = await Promise.all([ + this.page.screenshot(), + this.page.screenshot({ fullPage: true }), + ]); + + await this.screenshots.addError(step, screenshot, fs); } } diff --git a/packages/kbn-journeys/journey/journey_screenshots.ts b/packages/kbn-journeys/journey/journey_screenshots.ts index 8cd36444ef7ee..adf1021fa163d 100644 --- a/packages/kbn-journeys/journey/journey_screenshots.ts +++ b/packages/kbn-journeys/journey/journey_screenshots.ts @@ -19,6 +19,7 @@ interface StepShot { type: 'success' | 'failure'; title: string; filename: string; + fullscreenFilename: string; } interface Manifest { @@ -87,34 +88,44 @@ export class JourneyScreenshots { } } - async addError(step: AnyStep, screenshot: Buffer) { + async addError(step: AnyStep, screenshot: Buffer, fullscreenScreenshot: Buffer) { await this.lock(async () => { const filename = FtrScreenshotFilename.create(`${step.index}-${step.name}-failure`); + const fullscreenFilename = FtrScreenshotFilename.create( + `${step.index}-${step.name}-failure-fullscreen` + ); this.#manifest.steps.push({ type: 'failure', title: `Step #${step.index + 1}: ${step.name} - FAILED`, filename, + fullscreenFilename, }); await Promise.all([ write(Path.resolve(this.#dir, 'manifest.json'), JSON.stringify(this.#manifest)), write(Path.resolve(this.#dir, filename), screenshot), + write(Path.resolve(this.#dir, fullscreenFilename), fullscreenScreenshot), ]); }); } - async addSuccess(step: AnyStep, screenshot: Buffer) { + async addSuccess(step: AnyStep, screenshot: Buffer, fullscreenScreenshot: Buffer) { await this.lock(async () => { const filename = FtrScreenshotFilename.create(`${step.index}-${step.name}`); + const fullscreenFilename = FtrScreenshotFilename.create( + `${step.index}-${step.name}-fullscreen` + ); this.#manifest.steps.push({ type: 'success', title: `Step #${step.index + 1}: ${step.name} - DONE`, filename, + fullscreenFilename, }); await Promise.all([ write(Path.resolve(this.#dir, 'manifest.json'), JSON.stringify(this.#manifest)), write(Path.resolve(this.#dir, filename), screenshot), + write(Path.resolve(this.#dir, fullscreenFilename), fullscreenScreenshot), ]); }); } @@ -123,6 +134,7 @@ export class JourneyScreenshots { return this.#manifest.steps.map((stepShot) => ({ ...stepShot, path: Path.resolve(this.#dir, stepShot.filename), + fullscreenPath: Path.resolve(this.#dir, stepShot.fullscreenFilename), })); } } diff --git a/x-pack/performance/jest.config.js b/x-pack/performance/jest.config.js new file mode 100644 index 0000000000000..b8afeee25a9ed --- /dev/null +++ b/x-pack/performance/jest.config.js @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../..', + roots: ['/x-pack/performance'], +}; diff --git a/x-pack/performance/services/lib/time.test.ts b/x-pack/performance/services/lib/time.test.ts new file mode 100644 index 0000000000000..a1dab5878fcc2 --- /dev/null +++ b/x-pack/performance/services/lib/time.test.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ms, toMs } from './time'; + +describe('ms()', () => { + it('converts simple timestrings to milliseconds', () => { + expect(ms('1s')).toMatchInlineSnapshot(`1000`); + expect(ms('10s')).toMatchInlineSnapshot(`10000`); + expect(ms('1m')).toMatchInlineSnapshot(`60000`); + expect(ms('10m')).toMatchInlineSnapshot(`600000`); + expect(ms('0.5s')).toMatchInlineSnapshot(`500`); + expect(ms('0.5m')).toMatchInlineSnapshot(`30000`); + }); +}); + +describe('toMs()', () => { + it('converts strings to ms, returns number directly', () => { + expect(toMs(1000)).toBe(1000); + expect(toMs('1s')).toBe(1000); + }); +}); diff --git a/x-pack/performance/services/lib/time.ts b/x-pack/performance/services/lib/time.ts new file mode 100644 index 0000000000000..4557ca71d2d36 --- /dev/null +++ b/x-pack/performance/services/lib/time.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const SECOND = 1000; +export const MINUTE = 60 * SECOND; + +const TIME_STR_RE = /^((?:\d+)(?:\.\d+)?)(m|s)$/i; + +/** + * Either a number of milliseconds or a simple time string (eg. 2m or 30s) + */ +export type TimeOrMilliseconds = number | string; + +export function toMs(timeOrMs: TimeOrMilliseconds) { + return typeof timeOrMs === 'number' ? timeOrMs : ms(timeOrMs); +} + +/** + * Convert a basic time string into milliseconds. The string can end with + * `m` (for minutes) or `s` (for seconds) and have any number before it. + */ +export function ms(time: string) { + const match = time.match(TIME_STR_RE); + if (!match) { + throw new Error('invalid time string, expected a number followed by "m" or "s"'); + } + + const [, num, unit] = match; + switch (unit.toLowerCase()) { + case 's': + return Number.parseFloat(num) * SECOND; + case 'm': + return Number.parseFloat(num) * MINUTE; + default: + throw new Error(`unexpected timestring unit [time=${time}] [unit=${unit}]`); + } +} diff --git a/x-pack/performance/services/toasts.ts b/x-pack/performance/services/toasts.ts index b3859ddb92ec4..4a556e3780105 100644 --- a/x-pack/performance/services/toasts.ts +++ b/x-pack/performance/services/toasts.ts @@ -9,6 +9,8 @@ import { ToolingLog } from '@kbn/tooling-log'; import { subj } from '@kbn/test-subj-selector'; import { Page } from 'playwright'; +import { toMs, type TimeOrMilliseconds } from './lib/time'; + export class ToastsService { constructor(private readonly log: ToolingLog, private readonly page: Page) {} @@ -16,13 +18,18 @@ export class ToastsService { * Wait for a toast with some bit of text matching the provided `textSnipped`, then clear * it and resolve the promise. */ - async waitForAndClear(textSnippet: string) { + async waitForAndClear( + textSnippet: string, + options?: { + /** How long should we wait for the toast to show up? */ + timeout?: TimeOrMilliseconds; + } + ) { const txt = JSON.stringify(textSnippet); this.log.info(`waiting for toast that has the text ${txt}`); - const toastSel = `.euiToast:has-text(${txt})`; - const toast = this.page.locator(toastSel); - await toast.waitFor(); + const toast = this.page.locator(`.euiToast:has-text(${txt})`); + await toast.waitFor({ timeout: toMs(options?.timeout ?? '2m') }); this.log.info('toast found, closing'); diff --git a/x-pack/performance/tsconfig.json b/x-pack/performance/tsconfig.json index caff6d53f4476..923a42ffe52f3 100644 --- a/x-pack/performance/tsconfig.json +++ b/x-pack/performance/tsconfig.json @@ -5,7 +5,7 @@ "emitDeclarationOnly": true, "declaration": true, "declarationMap": true, - "types": ["node", "mocha"] + "types": ["node", "jest"] }, "include": ["**/*.ts"], } From c9d9d63ee7e95e58eea9c0058a1c76369a81b25c Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Mon, 26 Sep 2022 12:46:38 -0400 Subject: [PATCH 20/51] [Fleet] Add unit test for mapping generation (#141795) --- .../elasticsearch/template/mappings.test.ts | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 x-pack/plugins/fleet/server/services/epm/elasticsearch/template/mappings.test.ts diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/mappings.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/mappings.test.ts new file mode 100644 index 0000000000000..6925da569bae4 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/mappings.test.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { keyword } from './mappings'; + +describe('mappings', () => { + describe('keyword', () => { + it('should set ignore_above:1024 by default for indexed field', () => { + const mappings = keyword({ + name: 'test', + type: 'keyword', + }); + + expect(mappings).toEqual({ + ignore_above: 1024, + type: 'keyword', + }); + }); + + it('should not set ignore_above for non indexed field', () => { + const mappings = keyword({ + name: 'test', + type: 'keyword', + index: false, + }); + + expect(mappings).toEqual({ + type: 'keyword', + index: false, + }); + }); + + it('should not set ignore_above field with doc_values:false', () => { + const mappings = keyword({ + name: 'test', + type: 'keyword', + doc_values: false, + }); + + expect(mappings).toEqual({ + type: 'keyword', + doc_values: false, + }); + }); + }); +}); From fd16e6b224ddff8a3bbf90d4f17ad59c180d3d36 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Mon, 26 Sep 2022 12:46:55 -0400 Subject: [PATCH 21/51] [Fleet] Fix upgrade one agent should check fleet server version too (#141788) --- .../server/routes/agent/upgrade_handler.ts | 53 +++++++---- .../apis/agents/upgrade.ts | 92 +++++++++++++------ x-pack/test/fleet_api_integration/helpers.ts | 2 + 3 files changed, 103 insertions(+), 44 deletions(-) diff --git a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts index 4af0c1ff653b2..43a3987f29f60 100644 --- a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts +++ b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts @@ -47,26 +47,43 @@ export const postAgentUpgradeHandler: RequestHandler< }, }); } - const agent = await getAgentById(esClient, request.params.agentId); + try { + const agent = await getAgentById(esClient, request.params.agentId); - if (agent.unenrollment_started_at || agent.unenrolled_at) { - return response.customError({ - statusCode: 400, - body: { - message: 'cannot upgrade an unenrolling or unenrolled agent', - }, - }); - } - if (!force && !isAgentUpgradeable(agent, kibanaVersion, version)) { - return response.customError({ - statusCode: 400, - body: { - message: `agent ${request.params.agentId} is not upgradeable`, - }, - }); - } + const fleetServerAgents = await getAllFleetServerAgents(soClient, esClient); + const agentIsFleetServer = fleetServerAgents.some( + (fleetServerAgent) => fleetServerAgent.id === agent.id + ); + if (!agentIsFleetServer) { + try { + checkFleetServerVersion(version, fleetServerAgents); + } catch (err) { + return response.customError({ + statusCode: 400, + body: { + message: err.message, + }, + }); + } + } + + if (agent.unenrollment_started_at || agent.unenrolled_at) { + return response.customError({ + statusCode: 400, + body: { + message: 'cannot upgrade an unenrolling or unenrolled agent', + }, + }); + } + if (!force && !isAgentUpgradeable(agent, kibanaVersion, version)) { + return response.customError({ + statusCode: 400, + body: { + message: `agent ${request.params.agentId} is not upgradeable`, + }, + }); + } - try { await AgentService.sendUpgradeAgentAction({ soClient, esClient, diff --git a/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts b/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts index b842f89c8ac64..e941752f5f1b6 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts @@ -57,8 +57,38 @@ export default function (providerContext: FtrProviderContext) { }); describe('one agent', () => { + const fleetServerVersion = '7.16.0'; + + beforeEach(async () => { + await supertest.post(`/api/fleet/agent_policies`).set('kbn-xsrf', 'kibana').send({ + name: 'Fleet Server policy 1', + id: 'fleet-server-policy', + namespace: 'default', + has_fleet_server: true, + }); + + await kibanaServer.savedObjects.create({ + id: `package-policy-test`, + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + overwrite: true, + attributes: { + policy_id: 'fleet-server-policy', + name: 'Fleet Server', + package: { + name: 'fleet_server', + }, + }, + }); + await generateAgent( + providerContext, + 'healthy', + 'agentWithFS', + 'fleet-server-policy', + fleetServerVersion + ); + }); + it('should respond 200 to upgrade agent and update the agent SO', async () => { - const kibanaVersion = await kibanaServer.version.get(); await es.update({ id: 'agent1', refresh: 'wait_for', @@ -73,23 +103,39 @@ export default function (providerContext: FtrProviderContext) { .post(`/api/fleet/agents/agent1/upgrade`) .set('kbn-xsrf', 'xxx') .send({ - version: kibanaVersion, + version: fleetServerVersion, }) .expect(200); const res = await supertest.get(`/api/fleet/agents/agent1`).set('kbn-xsrf', 'xxx'); expect(typeof res.body.item.upgrade_started_at).to.be('string'); }); - it('should respond 400 if upgrading agent with version the same as snapshot version', async () => { + + it('should allow to upgrade a Fleet server agent to a version > fleet server version', async () => { const kibanaVersion = await kibanaServer.version.get(); - const kibanaVersionSnapshot = makeSnapshotVersion(kibanaVersion); + await supertest + .post(`/api/fleet/agents/agentWithFS/upgrade`) + .set('kbn-xsrf', 'xxx') + .send({ + version: kibanaVersion, + }) + .expect(200); + + const res = await supertest.get(`/api/fleet/agents/agentWithFS`).set('kbn-xsrf', 'xxx'); + expect(typeof res.body.item.upgrade_started_at).to.be('string'); + }); + + it('should respond 400 if upgrading agent with version the same as snapshot version', async () => { + const fleetServerVersionSnapshot = makeSnapshotVersion(fleetServerVersion); await es.update({ id: 'agent1', refresh: 'wait_for', index: AGENTS_INDEX, body: { doc: { - local_metadata: { elastic: { agent: { upgradeable: true, version: kibanaVersion } } }, + local_metadata: { + elastic: { agent: { upgradeable: true, version: fleetServerVersion } }, + }, }, }, }); @@ -97,20 +143,21 @@ export default function (providerContext: FtrProviderContext) { .post(`/api/fleet/agents/agent1/upgrade`) .set('kbn-xsrf', 'xxx') .send({ - version: kibanaVersionSnapshot, + version: fleetServerVersionSnapshot, }) .expect(400); }); it('should respond 200 if upgrading agent with version the same as snapshot version and force flag is passed', async () => { - const kibanaVersion = await kibanaServer.version.get(); - const kibanaVersionSnapshot = makeSnapshotVersion(kibanaVersion); + const fleetServerVersionSnapshot = makeSnapshotVersion(fleetServerVersion); await es.update({ id: 'agent1', refresh: 'wait_for', index: AGENTS_INDEX, body: { doc: { - local_metadata: { elastic: { agent: { upgradeable: true, version: kibanaVersion } } }, + local_metadata: { + elastic: { agent: { upgradeable: true, version: fleetServerVersion } }, + }, }, }, }); @@ -118,14 +165,13 @@ export default function (providerContext: FtrProviderContext) { .post(`/api/fleet/agents/agent1/upgrade`) .set('kbn-xsrf', 'xxx') .send({ - version: kibanaVersionSnapshot, + version: fleetServerVersionSnapshot, force: true, }) .expect(200); }); it('should respond 200 if upgrading agent with version less than kibana snapshot version', async () => { - const kibanaVersion = await kibanaServer.version.get(); - const kibanaVersionSnapshot = makeSnapshotVersion(kibanaVersion); + const fleetServerVersionSnapshot = makeSnapshotVersion(fleetServerVersion); await es.update({ id: 'agent1', @@ -141,12 +187,11 @@ export default function (providerContext: FtrProviderContext) { .post(`/api/fleet/agents/agent1/upgrade`) .set('kbn-xsrf', 'xxx') .send({ - version: kibanaVersionSnapshot, + version: fleetServerVersionSnapshot, }) .expect(200); }); it('should respond 200 if trying to upgrade with source_uri set', async () => { - const kibanaVersion = await kibanaServer.version.get(); await es.update({ id: 'agent1', refresh: 'wait_for', @@ -161,7 +206,7 @@ export default function (providerContext: FtrProviderContext) { .post(`/api/fleet/agents/agent1/upgrade`) .set('kbn-xsrf', 'xxx') .send({ - version: kibanaVersion, + version: fleetServerVersion, source_uri: 'http://path/to/download', }) .expect(200); @@ -205,7 +250,6 @@ export default function (providerContext: FtrProviderContext) { .expect(400); }); it('should respond 400 if trying to upgrade an agent that is unenrolling', async () => { - const kibanaVersion = await kibanaServer.version.get(); await supertest.post(`/api/fleet/agents/agent1/unenroll`).set('kbn-xsrf', 'xxx').send({ revoke: true, }); @@ -213,12 +257,11 @@ export default function (providerContext: FtrProviderContext) { .post(`/api/fleet/agents/agent1/upgrade`) .set('kbn-xsrf', 'xxx') .send({ - version: kibanaVersion, + version: fleetServerVersion, }) .expect(400); }); it('should respond 400 if trying to upgrade an agent that is unenrolled', async () => { - const kibanaVersion = await kibanaServer.version.get(); await es.update({ id: 'agent1', refresh: 'wait_for', @@ -233,18 +276,17 @@ export default function (providerContext: FtrProviderContext) { .post(`/api/fleet/agents/agent1/upgrade`) .set('kbn-xsrf', 'xxx') .send({ - version: kibanaVersion, + version: fleetServerVersion, }) .expect(400); }); it('should respond 400 if trying to upgrade an agent that is not upgradeable', async () => { - const kibanaVersion = await kibanaServer.version.get(); const res = await supertest .post(`/api/fleet/agents/agent1/upgrade`) .set('kbn-xsrf', 'xxx') .send({ - version: kibanaVersion, + version: fleetServerVersion, }) .expect(400); expect(res.body.message).to.equal('agent agent1 is not upgradeable'); @@ -258,7 +300,6 @@ export default function (providerContext: FtrProviderContext) { is_managed: true, }); - const kibanaVersion = await kibanaServer.version.get(); await es.update({ id: 'agent1', refresh: 'wait_for', @@ -273,7 +314,7 @@ export default function (providerContext: FtrProviderContext) { const { body } = await supertest .post(`/api/fleet/agents/agent1/upgrade`) .set('kbn-xsrf', 'xxx') - .send({ version: kibanaVersion }) + .send({ version: fleetServerVersion }) .expect(400); expect(body.message).to.contain( 'Cannot upgrade agent agent1 in hosted agent policy policy1' @@ -284,7 +325,6 @@ export default function (providerContext: FtrProviderContext) { }); it('should respond 403 if user lacks fleet all permissions', async () => { - const kibanaVersion = await kibanaServer.version.get(); await es.update({ id: 'agent1', refresh: 'wait_for', @@ -300,7 +340,7 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxx') .auth(testUsers.fleet_no_access.username, testUsers.fleet_no_access.password) .send({ - version: kibanaVersion, + version: fleetServerVersion, }) .expect(403); }); @@ -312,7 +352,7 @@ export default function (providerContext: FtrProviderContext) { beforeEach(async () => { await supertest.post(`/api/fleet/agent_policies`).set('kbn-xsrf', 'kibana').send({ name: 'Fleet Server policy 1', - policy_id: 'fleet-server-policy', + id: 'fleet-server-policy', namespace: 'default', has_fleet_server: true, }); diff --git a/x-pack/test/fleet_api_integration/helpers.ts b/x-pack/test/fleet_api_integration/helpers.ts index 552c83d3ca890..d3b623d0426f3 100644 --- a/x-pack/test/fleet_api_integration/helpers.ts +++ b/x-pack/test/fleet_api_integration/helpers.ts @@ -69,6 +69,7 @@ export async function generateAgent( await es.index({ index: '.fleet-agents', + id, body: { id, active: true, @@ -79,6 +80,7 @@ export async function generateAgent( elastic: { agent: { version, + upgradeable: true, }, }, }, From e35a7310e5e146886ad2912bfa04611229f1a2ea Mon Sep 17 00:00:00 2001 From: Julia Rechkunova Date: Mon, 26 Sep 2022 18:49:21 +0200 Subject: [PATCH 22/51] [Discover] Fix management flaky test (#141650) * [Discover] Tmp commit * [Discover] Update deprecated class * [Discover] Wait for lens page to load --- .../apps/management/_scripted_fields.ts | 27 +++++++++++-------- test/functional/page_objects/discover_page.ts | 3 ++- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/test/functional/apps/management/_scripted_fields.ts b/test/functional/apps/management/_scripted_fields.ts index 03a298182eec0..d12585088893d 100644 --- a/test/functional/apps/management/_scripted_fields.ts +++ b/test/functional/apps/management/_scripted_fields.ts @@ -211,10 +211,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.clickFieldListItemVisualize(scriptedPainlessFieldName); await PageObjects.header.waitUntilLoadingHasFinished(); // verify Lens opens a visualization - expect(await testSubjects.getVisibleTextAll('lns-dimensionTrigger')).to.contain( - '@timestamp', - 'Median of ram_Pain1' - ); + await retry.waitFor('lens visualization', async () => { + const elements = await testSubjects.getVisibleTextAll('lns-dimensionTrigger'); + return elements[0] === '@timestamp' && elements[1] === 'Median of ram_Pain1'; + }); }); }); @@ -314,9 +314,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.clickFieldListItemVisualize(scriptedPainlessFieldName2); await PageObjects.header.waitUntilLoadingHasFinished(); // verify Lens opens a visualization - expect(await testSubjects.getVisibleTextAll('lns-dimensionTrigger')).to.contain( - 'Top 5 values of painString' - ); + await retry.waitFor('lens visualization', async () => { + const elements = await testSubjects.getVisibleTextAll('lns-dimensionTrigger'); + return elements[0] === 'Top 5 values of painString'; + }); }); after(async () => { @@ -408,9 +409,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.clickFieldListItemVisualize(scriptedPainlessFieldName2); await PageObjects.header.waitUntilLoadingHasFinished(); // verify Lens opens a visualization - expect(await testSubjects.getVisibleTextAll('lns-dimensionTrigger')).to.contain( - 'Top 5 values of painBool' - ); + await retry.waitFor('lens visualization', async () => { + const elements = await testSubjects.getVisibleTextAll('lns-dimensionTrigger'); + return elements[0] === 'Top 5 values of painBool'; + }); }); after(async () => { @@ -503,7 +505,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.discover.clickFieldListItemVisualize(scriptedPainlessFieldName2); await PageObjects.header.waitUntilLoadingHasFinished(); // verify Lens opens a visualization - expect(await testSubjects.getVisibleTextAll('lns-dimensionTrigger')).to.contain('painDate'); + await retry.waitFor('lens visualization', async () => { + const elements = await testSubjects.getVisibleTextAll('lns-dimensionTrigger'); + return elements[0] === 'painDate'; + }); }); }); diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts index 5a6f842086498..cc398f8d67be6 100644 --- a/test/functional/page_objects/discover_page.ts +++ b/test/functional/page_objects/discover_page.ts @@ -486,7 +486,7 @@ export class DiscoverPageObject extends FtrService { public async clickFieldListItemVisualize(fieldName: string) { const field = await this.testSubjects.find(`field-${fieldName}-showDetails`); - const isActive = await field.elementHasClass('dscSidebarItem--active'); + const isActive = await field.elementHasClass('kbnFieldButton-isActive'); if (!isActive) { // expand the field to show the "Visualize" button @@ -494,6 +494,7 @@ export class DiscoverPageObject extends FtrService { } await this.testSubjects.click(`fieldVisualize-${fieldName}`); + await this.header.waitUntilLoadingHasFinished(); } public async expectFieldListItemVisualize(field: string) { From 74bf60f14a4a59a97f376ce2e236f2c075122ac0 Mon Sep 17 00:00:00 2001 From: Davis McPhee Date: Mon, 26 Sep 2022 13:52:23 -0300 Subject: [PATCH 23/51] [Discover] Show error and fix app state when updating data view ID in the URL to an invalid ID (#141540) * [Discover] Fix issue where updating the data view ID in the URL to an invalid ID does not trigger an error, and sets the app state to an invalid state * [Discover] Clean up work for invalid data view ID Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../main/hooks/use_discover_state.ts | 31 ++++++++++++++--- .../main/utils/resolve_data_view.ts | 2 ++ .../apps/discover/group1/_discover.ts | 34 +++++++++++++++++++ 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/plugins/discover/public/application/main/hooks/use_discover_state.ts b/src/plugins/discover/public/application/main/hooks/use_discover_state.ts index 8ad0d7ff7b590..1c530f475f0b1 100644 --- a/src/plugins/discover/public/application/main/hooks/use_discover_state.ts +++ b/src/plugins/discover/public/application/main/hooks/use_discover_state.ts @@ -16,7 +16,7 @@ import { useUrlTracking } from './use_url_tracking'; import { getState } from '../services/discover_state'; import { getStateDefaults } from '../utils/get_state_defaults'; import { DiscoverServices } from '../../../build_services'; -import { loadDataView } from '../utils/resolve_data_view'; +import { loadDataView, resolveDataView } from '../utils/resolve_data_view'; import { useSavedSearch as useSavedSearchData } from './use_saved_search'; import { MODIFY_COLUMNS_ON_SWITCH, @@ -67,7 +67,7 @@ export function useDiscoverState({ [history, savedSearch, services] ); - const { appStateContainer } = stateContainer; + const { appStateContainer, replaceUrlAppState } = stateContainer; const [state, setState] = useState(appStateContainer.getState()); @@ -190,13 +190,25 @@ export function useDiscoverState({ * That's because appState is updated before savedSearchData$ * The following line of code catches this, but should be improved */ - const nextDataView = await loadDataView( + const nextDataViewData = await loadDataView( services.dataViews, services.uiSettings, nextState.index ); - savedSearch.searchSource.setField('index', nextDataView.loaded); + const nextDataView = resolveDataView( + nextDataViewData, + savedSearch.searchSource, + services.toastNotifications + ); + + // If the requested data view is not found, don't try to load it, + // and instead reset the app state to the fallback data view + if (!nextDataViewData.stateValFound) { + replaceUrlAppState({ index: nextDataView.id }); + return; + } + savedSearch.searchSource.setField('index', nextDataView); reset(); } @@ -206,7 +218,16 @@ export function useDiscoverState({ setState(nextState); }); return () => unsubscribe(); - }, [services, appStateContainer, state, refetch$, data$, reset, savedSearch.searchSource]); + }, [ + services, + appStateContainer, + state, + refetch$, + data$, + reset, + savedSearch.searchSource, + replaceUrlAppState, + ]); /** * function to revert any changes to a given saved search diff --git a/src/plugins/discover/public/application/main/utils/resolve_data_view.ts b/src/plugins/discover/public/application/main/utils/resolve_data_view.ts index 7baede8101851..094e1ec837e3c 100644 --- a/src/plugins/discover/public/application/main/utils/resolve_data_view.ts +++ b/src/plugins/discover/public/application/main/utils/resolve_data_view.ts @@ -166,6 +166,7 @@ export function resolveDataView( ownDataViewId: ownDataView.id, }, }), + 'data-test-subj': 'dscDataViewNotFoundShowSavedWarning', }); return ownDataView; } @@ -180,6 +181,7 @@ export function resolveDataView( loadedDataViewId: loadedDataView.id, }, }), + 'data-test-subj': 'dscDataViewNotFoundShowDefaultWarning', }); } diff --git a/test/functional/apps/discover/group1/_discover.ts b/test/functional/apps/discover/group1/_discover.ts index 39793c9c047f0..9ac159fa39168 100644 --- a/test/functional/apps/discover/group1/_discover.ts +++ b/test/functional/apps/discover/group1/_discover.ts @@ -362,5 +362,39 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(newMainPanelSize).to.be(mainPanelSize - resizeDistance); }); }); + + describe('URL state', () => { + const getCurrentDataViewId = (currentUrl: string) => { + const [indexSubstring] = currentUrl.match(/index:[^,]*/)!; + const dataViewId = indexSubstring.replace('index:', ''); + return dataViewId; + }; + + it('should show a warning and fall back to the default data view when navigating to a URL with an invalid data view ID', async () => { + await PageObjects.common.navigateToApp('discover'); + await PageObjects.timePicker.setDefaultAbsoluteRange(); + await PageObjects.header.waitUntilLoadingHasFinished(); + const originalUrl = await browser.getCurrentUrl(); + const dataViewId = getCurrentDataViewId(originalUrl); + const newUrl = originalUrl.replace(dataViewId, 'invalid-data-view-id'); + await browser.get(newUrl); + await PageObjects.header.waitUntilLoadingHasFinished(); + expect(await browser.getCurrentUrl()).to.be(originalUrl); + expect(await testSubjects.exists('dscDataViewNotFoundShowDefaultWarning')).to.be(true); + }); + + it('should show a warning and fall back to the current data view if the URL is updated to an invalid data view ID', async () => { + await PageObjects.common.navigateToApp('discover'); + await PageObjects.timePicker.setDefaultAbsoluteRange(); + const originalHash = await browser.execute<[], string>('return window.location.hash'); + const dataViewId = getCurrentDataViewId(originalHash); + const newHash = originalHash.replace(dataViewId, 'invalid-data-view-id'); + await browser.execute(`window.location.hash = "${newHash}"`); + await PageObjects.header.waitUntilLoadingHasFinished(); + const currentHash = await browser.execute<[], string>('return window.location.hash'); + expect(currentHash).to.be(originalHash); + expect(await testSubjects.exists('dscDataViewNotFoundShowSavedWarning')).to.be(true); + }); + }); }); } From 90b9afdceea2439f7d7493000b22e8e6ff0f7185 Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Mon, 26 Sep 2022 11:12:57 -0600 Subject: [PATCH 24/51] [APM] Hash service name/environment for APM per_service telemetry (#141685) * Hash service name/environment for per_service telemetry * Fix typing and reorder service name/env Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../lib/apm_telemetry/collect_data_telemetry/tasks.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts index 167fb0d57208f..430930fb3f916 100644 --- a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts @@ -6,6 +6,7 @@ */ import { fromKueryExpression } from '@kbn/es-query'; import { flatten, merge, sortBy, sum, pickBy } from 'lodash'; +import { createHash } from 'crypto'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { asMutableArray } from '../../../../common/utils/as_mutable_array'; @@ -1247,11 +1248,15 @@ export const tasks: TelemetryTask[] = [ }); const envBuckets = response.aggregations?.environments.buckets ?? []; const data: APMPerService[] = envBuckets.flatMap((envBucket) => { - const env = envBucket.key; + const envHash = createHash('sha256') + .update(envBucket.key as string) + .digest('hex'); const serviceBuckets = envBucket.service_names?.buckets ?? []; return serviceBuckets.map((serviceBucket) => { - const name = serviceBucket.key; - const fullServiceName = `${env}~${name}`; + const nameHash = createHash('sha256') + .update(serviceBucket.key as string) + .digest('hex'); + const fullServiceName = `${nameHash}~${envHash}`; return { service_id: fullServiceName, timed_out: response.timed_out, From 924c7f912ab9203b8c0e320ce97ed8e3f1b5a817 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Mon, 26 Sep 2022 10:27:06 -0700 Subject: [PATCH 25/51] [Profiling] Simplify query post-processing and flamegraph response (#141729) * Replace non-null assertion with nullish coalescing * Remove createFrameGroup * Remove callers * Use adjacency list representation for tree * Move frame type map outside function * Inline frame group name * Replace FrameGroupID with ID * Create columnar view model in client --- .../{callercallee.test.ts => callee.test.ts} | 13 +- x-pack/plugins/profiling/common/callee.ts | 193 ++++++++++++++++ .../plugins/profiling/common/callercallee.ts | 177 -------------- .../profiling/common/flamegraph.test.ts | 32 +++ x-pack/plugins/profiling/common/flamegraph.ts | 216 +++++++++--------- .../profiling/common/frame_group.test.ts | 112 +++++++-- .../plugins/profiling/common/frame_group.ts | 72 +----- x-pack/plugins/profiling/common/functions.ts | 11 +- x-pack/plugins/profiling/common/profiling.ts | 40 ++-- .../public/components/flamegraph.tsx | 10 +- .../utils/get_flamegraph_model/index.ts | 38 ++- .../profiling/server/routes/flamechart.ts | 78 +++---- .../routes/get_executables_and_stacktraces.ts | 3 +- .../profiling/server/routes/stacktrace.ts | 16 +- 14 files changed, 535 insertions(+), 476 deletions(-) rename x-pack/plugins/profiling/common/{callercallee.test.ts => callee.test.ts} (51%) create mode 100644 x-pack/plugins/profiling/common/callee.ts delete mode 100644 x-pack/plugins/profiling/common/callercallee.ts create mode 100644 x-pack/plugins/profiling/common/flamegraph.test.ts diff --git a/x-pack/plugins/profiling/common/callercallee.test.ts b/x-pack/plugins/profiling/common/callee.test.ts similarity index 51% rename from x-pack/plugins/profiling/common/callercallee.test.ts rename to x-pack/plugins/profiling/common/callee.test.ts index a249d21623c44..0ae26e6d848e7 100644 --- a/x-pack/plugins/profiling/common/callercallee.test.ts +++ b/x-pack/plugins/profiling/common/callee.test.ts @@ -6,18 +6,19 @@ */ import { sum } from 'lodash'; -import { createCallerCalleeGraph } from './callercallee'; +import { createCalleeTree } from './callee'; import { events, stackTraces, stackFrames, executables } from './__fixtures__/stacktraces'; -describe('Caller-callee operations', () => { +describe('Callee operations', () => { test('1', () => { const totalSamples = sum([...events.values()]); + const totalFrames = sum([...stackTraces.values()].map((trace) => trace.FrameIDs.length)); - const graph = createCallerCalleeGraph(events, stackTraces, stackFrames, executables); + const tree = createCalleeTree(events, stackTraces, stackFrames, executables, totalFrames); - expect(graph.root.Samples).toEqual(totalSamples); - expect(graph.root.CountInclusive).toEqual(totalSamples); - expect(graph.root.CountExclusive).toEqual(0); + expect(tree.Samples[0]).toEqual(totalSamples); + expect(tree.CountInclusive[0]).toEqual(totalSamples); + expect(tree.CountExclusive[0]).toEqual(0); }); }); diff --git a/x-pack/plugins/profiling/common/callee.ts b/x-pack/plugins/profiling/common/callee.ts new file mode 100644 index 0000000000000..63db0640513c3 --- /dev/null +++ b/x-pack/plugins/profiling/common/callee.ts @@ -0,0 +1,193 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import fnv from 'fnv-plus'; + +import { createFrameGroupID, FrameGroupID } from './frame_group'; +import { + createStackFrameMetadata, + emptyExecutable, + emptyStackFrame, + emptyStackTrace, + Executable, + FileID, + getCalleeLabel, + StackFrame, + StackFrameID, + StackFrameMetadata, + StackTrace, + StackTraceID, +} from './profiling'; + +type NodeID = number; + +export interface CalleeTree { + Size: number; + Edges: Array>; + + ID: string[]; + FrameType: number[]; + FrameID: StackFrameID[]; + FileID: FileID[]; + Label: string[]; + + Samples: number[]; + CountInclusive: number[]; + CountExclusive: number[]; +} + +function initCalleeTree(capacity: number): CalleeTree { + const metadata = createStackFrameMetadata(); + const frameGroupID = createFrameGroupID( + metadata.FileID, + metadata.AddressOrLine, + metadata.ExeFileName, + metadata.SourceFilename, + metadata.FunctionName + ); + const tree: CalleeTree = { + Size: 1, + Edges: new Array(capacity), + ID: new Array(capacity), + FrameType: new Array(capacity), + FrameID: new Array(capacity), + FileID: new Array(capacity), + Label: new Array(capacity), + Samples: new Array(capacity), + CountInclusive: new Array(capacity), + CountExclusive: new Array(capacity), + }; + + tree.Edges[0] = new Map(); + + tree.ID[0] = fnv.fast1a64utf(frameGroupID).toString(); + tree.FrameType[0] = metadata.FrameType; + tree.FrameID[0] = metadata.FrameID; + tree.FileID[0] = metadata.FileID; + tree.Label[0] = 'root: Represents 100% of CPU time.'; + tree.Samples[0] = 0; + tree.CountInclusive[0] = 0; + tree.CountExclusive[0] = 0; + + return tree; +} + +function insertNode( + tree: CalleeTree, + parent: NodeID, + metadata: StackFrameMetadata, + frameGroupID: FrameGroupID, + samples: number +) { + const node = tree.Size; + + tree.Edges[parent].set(frameGroupID, node); + tree.Edges[node] = new Map(); + + tree.ID[node] = fnv.fast1a64utf(`${tree.ID[parent]}${frameGroupID}`).toString(); + tree.FrameType[node] = metadata.FrameType; + tree.FrameID[node] = metadata.FrameID; + tree.FileID[node] = metadata.FileID; + tree.Label[node] = getCalleeLabel(metadata); + tree.Samples[node] = samples; + tree.CountInclusive[node] = 0; + tree.CountExclusive[node] = 0; + + tree.Size++; + + return node; +} + +// createCalleeTree creates a tree from the trace results, the number of +// times that the trace has been seen, and the respective metadata. +// +// The resulting data structure contains all of the data, but is not yet in the +// form most easily digestible by others. +export function createCalleeTree( + events: Map, + stackTraces: Map, + stackFrames: Map, + executables: Map, + totalFrames: number +): CalleeTree { + const tree = initCalleeTree(totalFrames); + + const sortedStackTraceIDs = new Array(); + for (const trace of stackTraces.keys()) { + sortedStackTraceIDs.push(trace); + } + sortedStackTraceIDs.sort((t1, t2) => { + return t1.localeCompare(t2); + }); + + // Walk through all traces. Increment the count of the root by the count of + // that trace. Walk "down" the trace (through the callees) and add the count + // of the trace to each callee. + + for (const stackTraceID of sortedStackTraceIDs) { + // The slice of frames is ordered so that the leaf function is at the + // highest index. + + // It is possible that we do not have a stacktrace for an event, + // e.g. when stopping the host agent or on network errors. + const stackTrace = stackTraces.get(stackTraceID) ?? emptyStackTrace; + const lenStackTrace = stackTrace.FrameIDs.length; + const samples = events.get(stackTraceID) ?? 0; + + let currentNode = 0; + tree.Samples[currentNode] += samples; + + for (let i = 0; i < lenStackTrace; i++) { + const frameID = stackTrace.FrameIDs[i]; + const fileID = stackTrace.FileIDs[i]; + const addressOrLine = stackTrace.AddressOrLines[i]; + const frame = stackFrames.get(frameID) ?? emptyStackFrame; + const executable = executables.get(fileID) ?? emptyExecutable; + + const frameGroupID = createFrameGroupID( + fileID, + addressOrLine, + executable.FileName, + frame.FileName, + frame.FunctionName + ); + + let node = tree.Edges[currentNode].get(frameGroupID); + + if (node === undefined) { + const metadata = createStackFrameMetadata({ + FrameID: frameID, + FileID: fileID, + AddressOrLine: addressOrLine, + FrameType: stackTrace.Types[i], + FunctionName: frame.FunctionName, + FunctionOffset: frame.FunctionOffset, + SourceLine: frame.LineNumber, + SourceFilename: frame.FileName, + ExeFileName: executable.FileName, + }); + + node = insertNode(tree, currentNode, metadata, frameGroupID, samples); + } else { + tree.Samples[node] += samples; + } + + tree.CountInclusive[node] += samples; + + if (i === lenStackTrace - 1) { + // Leaf frame: sum up counts for exclusive CPU. + tree.CountExclusive[node] += samples; + } + currentNode = node; + } + } + + tree.CountExclusive[0] = 0; + tree.CountInclusive[0] = tree.Samples[0]; + + return tree; +} diff --git a/x-pack/plugins/profiling/common/callercallee.ts b/x-pack/plugins/profiling/common/callercallee.ts deleted file mode 100644 index 60573306d7f29..0000000000000 --- a/x-pack/plugins/profiling/common/callercallee.ts +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { createFrameGroup, createFrameGroupID, FrameGroupID } from './frame_group'; -import { - createStackFrameMetadata, - emptyStackTrace, - Executable, - FileID, - StackFrame, - StackFrameID, - StackFrameMetadata, - StackTrace, - StackTraceID, -} from './profiling'; - -export interface CallerCalleeNode { - Callers: Map; - Callees: Map; - FrameMetadata: StackFrameMetadata; - FrameGroupID: FrameGroupID; - Samples: number; - CountInclusive: number; - CountExclusive: number; -} - -export function createCallerCalleeNode( - frameMetadata: StackFrameMetadata, - frameGroupID: FrameGroupID, - samples: number -): CallerCalleeNode { - return { - Callers: new Map(), - Callees: new Map(), - FrameMetadata: frameMetadata, - FrameGroupID: frameGroupID, - Samples: samples, - CountInclusive: 0, - CountExclusive: 0, - }; -} - -export interface CallerCalleeGraph { - root: CallerCalleeNode; - size: number; -} - -// createCallerCalleeGraph creates a graph in the internal representation -// from a StackFrameMetadata that identifies the "centered" function and -// the trace results that provide traces and the number of times that the -// trace has been seen. -// -// The resulting data structure contains all of the data, but is not yet in the -// form most easily digestible by others. -export function createCallerCalleeGraph( - events: Map, - stackTraces: Map, - stackFrames: Map, - executables: Map -): CallerCalleeGraph { - // Create a root node for the graph - const rootFrame = createStackFrameMetadata(); - const rootFrameGroup = createFrameGroup( - rootFrame.FileID, - rootFrame.AddressOrLine, - rootFrame.ExeFileName, - rootFrame.SourceFilename, - rootFrame.FunctionName - ); - const rootFrameGroupID = createFrameGroupID(rootFrameGroup); - const root = createCallerCalleeNode(rootFrame, rootFrameGroupID, 0); - const graph: CallerCalleeGraph = { root, size: 1 }; - - const sortedStackTraceIDs = new Array(); - for (const trace of stackTraces.keys()) { - sortedStackTraceIDs.push(trace); - } - sortedStackTraceIDs.sort((t1, t2) => { - return t1.localeCompare(t2); - }); - - // Walk through all traces that contain the root. Increment the count of the - // root by the count of that trace. Walk "up" the trace (through the callers) - // and add the count of the trace to each caller. Then walk "down" the trace - // (through the callees) and add the count of the trace to each callee. - - for (const stackTraceID of sortedStackTraceIDs) { - // The slice of frames is ordered so that the leaf function is at the - // highest index. This means that the "first part" of the slice are the - // callers, and the "second part" are the callees. - // - // We currently assume there are no callers. - - // It is possible that we do not have a stacktrace for an event, - // e.g. when stopping the host agent or on network errors. - const stackTrace = stackTraces.get(stackTraceID) ?? emptyStackTrace; - const lenStackTrace = stackTrace.FrameIDs.length; - const samples = events.get(stackTraceID)!; - - let currentNode = root; - root.Samples += samples; - - for (let i = 0; i < lenStackTrace; i++) { - const frameID = stackTrace.FrameIDs[i]; - const fileID = stackTrace.FileIDs[i]; - const addressOrLine = stackTrace.AddressOrLines[i]; - const frame = stackFrames.get(frameID)!; - const executable = executables.get(fileID)!; - - const frameGroup = createFrameGroup( - fileID, - addressOrLine, - executable.FileName, - frame.FileName, - frame.FunctionName - ); - const frameGroupID = createFrameGroupID(frameGroup); - - let node = currentNode.Callees.get(frameGroupID); - - if (node === undefined) { - const callee = createStackFrameMetadata({ - FrameID: frameID, - FileID: fileID, - AddressOrLine: addressOrLine, - FrameType: stackTrace.Types[i], - FunctionName: frame.FunctionName, - FunctionOffset: frame.FunctionOffset, - SourceLine: frame.LineNumber, - SourceFilename: frame.FileName, - ExeFileName: executable.FileName, - }); - - node = createCallerCalleeNode(callee, frameGroupID, samples); - currentNode.Callees.set(frameGroupID, node); - graph.size++; - } else { - node.Samples += samples; - } - - node.CountInclusive += samples; - - if (i === lenStackTrace - 1) { - // Leaf frame: sum up counts for exclusive CPU. - node.CountExclusive += samples; - } - currentNode = node; - } - } - - root.CountExclusive = 0; - root.CountInclusive = root.Samples; - - return graph; -} - -export function sortCallerCalleeNodes( - nodes: Map -): CallerCalleeNode[] { - const sortedNodes = new Array(); - for (const [_, node] of nodes) { - sortedNodes.push(node); - } - return sortedNodes.sort((n1, n2) => { - if (n1.Samples > n2.Samples) { - return -1; - } - if (n1.Samples < n2.Samples) { - return 1; - } - return n1.FrameGroupID.localeCompare(n2.FrameGroupID); - }); -} diff --git a/x-pack/plugins/profiling/common/flamegraph.test.ts b/x-pack/plugins/profiling/common/flamegraph.test.ts new file mode 100644 index 0000000000000..3852d0152bf12 --- /dev/null +++ b/x-pack/plugins/profiling/common/flamegraph.test.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { sum } from 'lodash'; +import { createCalleeTree } from './callee'; +import { createColumnarViewModel, createFlameGraph } from './flamegraph'; + +import { events, stackTraces, stackFrames, executables } from './__fixtures__/stacktraces'; + +describe('Flamegraph operations', () => { + test('1', () => { + const totalSamples = sum([...events.values()]); + const totalFrames = sum([...stackTraces.values()].map((trace) => trace.FrameIDs.length)); + + const tree = createCalleeTree(events, stackTraces, stackFrames, executables, totalFrames); + const graph = createFlameGraph(tree, 60, totalSamples, totalSamples); + + expect(graph.Size).toEqual(totalFrames - 2); + + const viewModel1 = createColumnarViewModel(graph); + + expect(sum(viewModel1.color)).toBeGreaterThan(0); + + const viewModel2 = createColumnarViewModel(graph, false); + + expect(sum(viewModel2.color)).toEqual(0); + }); +}); diff --git a/x-pack/plugins/profiling/common/flamegraph.ts b/x-pack/plugins/profiling/common/flamegraph.ts index 71c4128b01cbb..e392022a18fcf 100644 --- a/x-pack/plugins/profiling/common/flamegraph.ts +++ b/x-pack/plugins/profiling/common/flamegraph.ts @@ -5,37 +5,24 @@ * 2.0. */ -import fnv from 'fnv-plus'; -import { CallerCalleeGraph, sortCallerCalleeNodes } from './callercallee'; -import { getCalleeLabel } from './profiling'; +import { ColumnarViewModel } from '@elastic/charts'; + +import { CalleeTree } from './callee'; + +export interface ElasticFlameGraph { + Size: number; + Edges: number[][]; -interface ColumnarCallerCallee { - Label: string[]; - Value: number[]; - X: number[]; - Y: number[]; - Color: number[]; - CountInclusive: number[]; - CountExclusive: number[]; ID: string[]; + FrameType: number[]; FrameID: string[]; ExecutableID: string[]; -} - -export interface FlameGraph { Label: string[]; - Value: number[]; - Position: number[]; - Size: number[]; - Color: number[]; + + Samples: number[]; CountInclusive: number[]; CountExclusive: number[]; - ID: string[]; - FrameID: string[]; - ExecutableID: string[]; -} -export interface ElasticFlameGraph extends FlameGraph { TotalSeconds: number; TotalTraces: number; SampledTraces: number; @@ -94,110 +81,119 @@ function normalize(n: number, lower: number, upper: number): number { return (n - lower) / (upper - lower); } -// createColumnarCallerCallee flattens the intermediate representation of the diagram -// into a columnar format that is more compact than JSON. This representation will later -// need to be normalized into the response ultimately consumed by the flamegraph. -export function createColumnarCallerCallee(graph: CallerCalleeGraph): ColumnarCallerCallee { - const numCallees = graph.size; - const columnar: ColumnarCallerCallee = { - Label: new Array(numCallees), - Value: new Array(numCallees), - X: new Array(numCallees), - Y: new Array(numCallees), - Color: new Array(numCallees * 4), - CountInclusive: new Array(numCallees), - CountExclusive: new Array(numCallees), - ID: new Array(numCallees), - FrameID: new Array(numCallees), - ExecutableID: new Array(numCallees), +// createFlameGraph encapsulates the tree representation into a serialized form. +export function createFlameGraph( + tree: CalleeTree, + totalSeconds: number, + totalTraces: number, + sampledTraces: number +): ElasticFlameGraph { + const graph: ElasticFlameGraph = { + Size: tree.Size, + Edges: new Array(tree.Size), + + ID: tree.ID.slice(0, tree.Size), + Label: tree.Label.slice(0, tree.Size), + FrameID: tree.FrameID.slice(0, tree.Size), + FrameType: tree.FrameType.slice(0, tree.Size), + ExecutableID: tree.FileID.slice(0, tree.Size), + + Samples: tree.Samples.slice(0, tree.Size), + CountInclusive: tree.CountInclusive.slice(0, tree.Size), + CountExclusive: tree.CountExclusive.slice(0, tree.Size), + + TotalSeconds: totalSeconds, + TotalTraces: totalTraces, + SampledTraces: sampledTraces, }; - const queue = [{ x: 0, depth: 1, node: graph.root, parentID: 'root' }]; - - let idx = 0; - while (queue.length > 0) { - const { x, depth, node, parentID } = queue.pop()!; - - if (x === 0 && depth === 1) { - columnar.Label[idx] = 'root: Represents 100% of CPU time.'; - } else { - columnar.Label[idx] = getCalleeLabel(node.FrameMetadata); + for (let i = 0; i < tree.Size; i++) { + let j = 0; + const nodes = new Array(tree.Edges[i].size); + for (const [, n] of tree.Edges[i]) { + nodes[j] = n; + j++; } - columnar.Value[idx] = node.Samples; - columnar.X[idx] = x; - columnar.Y[idx] = depth; - - const [red, green, blue, alpha] = rgbToRGBA(frameTypeToRGB(node.FrameMetadata.FrameType, x)); - const j = 4 * idx; - columnar.Color[j] = red; - columnar.Color[j + 1] = green; - columnar.Color[j + 2] = blue; - columnar.Color[j + 3] = alpha; + graph.Edges[i] = nodes; + } - columnar.CountInclusive[idx] = node.CountInclusive; - columnar.CountExclusive[idx] = node.CountExclusive; + return graph; +} - const id = fnv.fast1a64utf(`${parentID}${node.FrameGroupID}`).toString(); +// createColumnarViewModel normalizes the columnar representation into a form +// consumed by the flamegraph in the UI. +export function createColumnarViewModel( + flamegraph: ElasticFlameGraph, + assignColors: boolean = true +): ColumnarViewModel { + const numNodes = flamegraph.Size; + const xs = new Float32Array(numNodes); + const ys = new Float32Array(numNodes); - columnar.ID[idx] = id; - columnar.FrameID[idx] = node.FrameMetadata.FrameID; - columnar.ExecutableID[idx] = node.FrameMetadata.FileID; + const queue = [{ x: 0, depth: 1, node: 0 }]; - // For a deterministic result we have to walk the callers / callees in a deterministic - // order. A deterministic result allows deterministic UI views, something that users expect. - const callees = sortCallerCalleeNodes(node.Callees); + while (queue.length > 0) { + const { x, depth, node } = queue.pop()!; + + xs[node] = x; + ys[node] = depth; + + // For a deterministic result we have to walk the callees in a deterministic + // order. A deterministic result allows deterministic UI views, something + // that users expect. + const children = flamegraph.Edges[node].sort((n1, n2) => { + if (flamegraph.Samples[n1] > flamegraph.Samples[n2]) { + return -1; + } + if (flamegraph.Samples[n1] < flamegraph.Samples[n2]) { + return 1; + } + return flamegraph.ID[n1].localeCompare(flamegraph.ID[n2]); + }); let delta = 0; - for (const callee of callees) { - delta += callee.Samples; + for (const child of children) { + delta += flamegraph.Samples[child]; } - for (let i = callees.length - 1; i >= 0; i--) { - delta -= callees[i].Samples; - queue.push({ x: x + delta, depth: depth + 1, node: callees[i], parentID: id }); + for (let i = children.length - 1; i >= 0; i--) { + delta -= flamegraph.Samples[children[i]]; + queue.push({ x: x + delta, depth: depth + 1, node: children[i] }); } - - idx++; } - return columnar; -} + const colors = new Float32Array(numNodes * 4); -// createFlameGraph normalizes the intermediate columnar representation into the -// response ultimately consumed by the flamegraph in the UI. -export function createFlameGraph(columnar: ColumnarCallerCallee): FlameGraph { - const graph: FlameGraph = { - Label: [], - Value: [], - Position: [], - Size: [], - Color: [], - CountInclusive: [], - CountExclusive: [], - ID: [], - FrameID: [], - ExecutableID: [], - }; + if (assignColors) { + for (let i = 0; i < numNodes; i++) { + const rgba = rgbToRGBA(frameTypeToRGB(flamegraph.FrameType[i], xs[i])); + colors.set(rgba, 4 * i); + } + } + + const position = new Float32Array(numNodes * 2); + const maxX = flamegraph.Samples[0]; + const maxY = ys.reduce((max, n) => (n > max ? n : max), 0); - graph.Label = columnar.Label; - graph.Value = columnar.Value; - graph.Color = columnar.Color; - graph.CountInclusive = columnar.CountInclusive; - graph.CountExclusive = columnar.CountExclusive; - graph.ID = columnar.ID; - graph.FrameID = columnar.FrameID; - graph.ExecutableID = columnar.ExecutableID; - - const maxX = columnar.Value[0]; - const maxY = columnar.Y.reduce((max, n) => (n > max ? n : max), 0); - - for (let i = 0; i < columnar.X.length; i++) { - const x = normalize(columnar.X[i], 0, maxX); - const y = normalize(maxY - columnar.Y[i], 0, maxY); - graph.Position.push(x, y); + for (let i = 0; i < numNodes; i++) { + const j = 2 * i; + position[j] = normalize(xs[i], 0, maxX); + position[j + 1] = normalize(maxY - ys[i], 0, maxY); } - graph.Size = graph.Value.map((n) => normalize(n, 0, maxX)); + const size = new Float32Array(numNodes); - return graph; + for (let i = 0; i < numNodes; i++) { + size[i] = normalize(flamegraph.Samples[i], 0, maxX); + } + + return { + label: flamegraph.Label.slice(0, numNodes), + value: Float64Array.from(flamegraph.Samples.slice(0, numNodes)), + color: colors, + position0: position, + position1: position, + size0: size, + size1: size, + } as ColumnarViewModel; } diff --git a/x-pack/plugins/profiling/common/frame_group.test.ts b/x-pack/plugins/profiling/common/frame_group.test.ts index b8dd3c8d03632..15f1e0e4edc7f 100644 --- a/x-pack/plugins/profiling/common/frame_group.test.ts +++ b/x-pack/plugins/profiling/common/frame_group.test.ts @@ -5,40 +5,116 @@ * 2.0. */ -import { createFrameGroup, createFrameGroupID } from './frame_group'; +import { createFrameGroupID } from './frame_group'; -const nonSymbolizedFrameGroups = [ - createFrameGroup('0x0123456789ABCDEF', 102938, '', '', ''), - createFrameGroup('0x0123456789ABCDEF', 1234, '', '', ''), - createFrameGroup('0x0102030405060708', 1234, '', '', ''), +const nonSymbolizedTests = [ + { + params: { + fileID: '0x0123456789ABCDEF', + addressOrLine: 102938, + exeFilename: '', + sourceFilename: '', + functionName: '', + }, + expected: 'empty;0x0123456789ABCDEF;102938', + }, + { + params: { + fileID: '0x0123456789ABCDEF', + addressOrLine: 1234, + exeFilename: 'libpthread', + sourceFilename: '', + functionName: '', + }, + expected: 'empty;0x0123456789ABCDEF;1234', + }, ]; -const elfSymbolizedFrameGroups = [ - createFrameGroup('0x0123456789ABCDEF', 0, 'libc', '', 'strlen()'), - createFrameGroup('0xFEDCBA9876543210', 0, 'libc', '', 'strtok()'), - createFrameGroup('0xFEDCBA9876543210', 0, 'myapp', '', 'main()'), +const elfSymbolizedTests = [ + { + params: { + fileID: '0x0123456789ABCDEF', + addressOrLine: 0, + exeFilename: 'libc', + sourceFilename: '', + functionName: 'strlen()', + }, + expected: 'elf;libc;strlen()', + }, + { + params: { + fileID: '0xFEDCBA9876543210', + addressOrLine: 8888, + exeFilename: 'libc', + sourceFilename: '', + functionName: 'strtok()', + }, + expected: 'elf;libc;strtok()', + }, ]; -const symbolizedFrameGroups = [ - createFrameGroup('', 0, 'chrome', 'strlen()', 'strlen()'), - createFrameGroup('', 0, 'dockerd', 'main()', 'createTask()'), - createFrameGroup('', 0, 'oom_reaper', 'main()', 'crash()'), +const symbolizedTests = [ + { + params: { + fileID: '', + addressOrLine: 0, + exeFilename: 'chrome', + sourceFilename: 'strlen()', + functionName: 'strlen()', + }, + expected: 'full;chrome;strlen();strlen()', + }, + { + params: { + fileID: '', + addressOrLine: 0, + exeFilename: 'oom_reaper', + sourceFilename: 'main()', + functionName: 'crash()', + }, + expected: 'full;oom_reaper;crash();main()', + }, ]; describe('Frame group operations', () => { describe('check serialization for', () => { test('non-symbolized frame', () => { - expect(createFrameGroupID(nonSymbolizedFrameGroups[0])).toEqual( - 'empty;0x0123456789ABCDEF;102938' - ); + for (const test of nonSymbolizedTests) { + const frameGroupID = createFrameGroupID( + test.params.fileID, + test.params.addressOrLine, + test.params.exeFilename, + test.params.sourceFilename, + test.params.functionName + ); + expect(frameGroupID).toEqual(test.expected); + } }); test('non-symbolized ELF frame', () => { - expect(createFrameGroupID(elfSymbolizedFrameGroups[0])).toEqual('elf;libc;strlen()'); + for (const test of elfSymbolizedTests) { + const frameGroupID = createFrameGroupID( + test.params.fileID, + test.params.addressOrLine, + test.params.exeFilename, + test.params.sourceFilename, + test.params.functionName + ); + expect(frameGroupID).toEqual(test.expected); + } }); test('symbolized frame', () => { - expect(createFrameGroupID(symbolizedFrameGroups[0])).toEqual('full;chrome;strlen();strlen()'); + for (const test of symbolizedTests) { + const frameGroupID = createFrameGroupID( + test.params.fileID, + test.params.addressOrLine, + test.params.exeFilename, + test.params.sourceFilename, + test.params.functionName + ); + expect(frameGroupID).toEqual(test.expected); + } }); }); }); diff --git a/x-pack/plugins/profiling/common/frame_group.ts b/x-pack/plugins/profiling/common/frame_group.ts index 5987ecdf2ebdc..30a29fe240e1f 100644 --- a/x-pack/plugins/profiling/common/frame_group.ts +++ b/x-pack/plugins/profiling/common/frame_group.ts @@ -9,86 +9,26 @@ import { StackFrameMetadata } from './profiling'; export type FrameGroupID = string; -enum FrameGroupName { - EMPTY = 'empty', - ELF = 'elf', - FULL = 'full', -} - -interface BaseFrameGroup { - readonly name: FrameGroupName; -} - -interface EmptyFrameGroup extends BaseFrameGroup { - readonly name: FrameGroupName.EMPTY; - readonly fileID: StackFrameMetadata['FileID']; - readonly addressOrLine: StackFrameMetadata['AddressOrLine']; -} - -interface ElfFrameGroup extends BaseFrameGroup { - readonly name: FrameGroupName.ELF; - readonly fileID: StackFrameMetadata['FileID']; - readonly exeFilename: StackFrameMetadata['ExeFileName']; - readonly functionName: StackFrameMetadata['FunctionName']; -} - -interface FullFrameGroup extends BaseFrameGroup { - readonly name: FrameGroupName.FULL; - readonly exeFilename: StackFrameMetadata['ExeFileName']; - readonly functionName: StackFrameMetadata['FunctionName']; - readonly sourceFilename: StackFrameMetadata['SourceFilename']; -} - -export type FrameGroup = EmptyFrameGroup | ElfFrameGroup | FullFrameGroup; - -// createFrameGroup is the "standard" way of grouping frames, by commonly +// createFrameGroupID is the "standard" way of grouping frames, by commonly // shared group identifiers. // // For ELF-symbolized frames, group by FunctionName, ExeFileName and FileID. // For non-symbolized frames, group by FileID and AddressOrLine. // otherwise group by ExeFileName, SourceFilename and FunctionName. -export function createFrameGroup( +export function createFrameGroupID( fileID: StackFrameMetadata['FileID'], addressOrLine: StackFrameMetadata['AddressOrLine'], exeFilename: StackFrameMetadata['ExeFileName'], sourceFilename: StackFrameMetadata['SourceFilename'], functionName: StackFrameMetadata['FunctionName'] -): FrameGroup { +): FrameGroupID { if (functionName === '') { - return { - name: FrameGroupName.EMPTY, - fileID, - addressOrLine, - } as EmptyFrameGroup; + return `empty;${fileID};${addressOrLine}`; } if (sourceFilename === '') { - return { - name: FrameGroupName.ELF, - fileID, - exeFilename, - functionName, - } as ElfFrameGroup; + return `elf;${exeFilename};${functionName}`; } - return { - name: FrameGroupName.FULL, - exeFilename, - functionName, - sourceFilename, - } as FullFrameGroup; -} - -export function createFrameGroupID(frameGroup: FrameGroup): FrameGroupID { - switch (frameGroup.name) { - case FrameGroupName.EMPTY: - return `${frameGroup.name};${frameGroup.fileID};${frameGroup.addressOrLine}`; - break; - case FrameGroupName.ELF: - return `${frameGroup.name};${frameGroup.exeFilename};${frameGroup.functionName}`; - break; - case FrameGroupName.FULL: - return `${frameGroup.name};${frameGroup.exeFilename};${frameGroup.functionName};${frameGroup.sourceFilename}`; - break; - } + return `full;${exeFilename};${functionName};${sourceFilename}`; } diff --git a/x-pack/plugins/profiling/common/functions.ts b/x-pack/plugins/profiling/common/functions.ts index 5ca59163227d1..70aa7cae864d7 100644 --- a/x-pack/plugins/profiling/common/functions.ts +++ b/x-pack/plugins/profiling/common/functions.ts @@ -5,9 +5,11 @@ * 2.0. */ import * as t from 'io-ts'; -import { createFrameGroup, createFrameGroupID, FrameGroupID } from './frame_group'; +import { createFrameGroupID, FrameGroupID } from './frame_group'; import { createStackFrameMetadata, + emptyExecutable, + emptyStackFrame, emptyStackTrace, Executable, FileID, @@ -66,17 +68,16 @@ export function createTopNFunctions( const frameID = stackTrace.FrameIDs[i]; const fileID = stackTrace.FileIDs[i]; const addressOrLine = stackTrace.AddressOrLines[i]; - const frame = stackFrames.get(frameID)!; - const executable = executables.get(fileID)!; + const frame = stackFrames.get(frameID) ?? emptyStackFrame; + const executable = executables.get(fileID) ?? emptyExecutable; - const frameGroup = createFrameGroup( + const frameGroupID = createFrameGroupID( fileID, addressOrLine, executable.FileName, frame.FileName, frame.FunctionName ); - const frameGroupID = createFrameGroupID(frameGroup); let topNFunction = topNFunctions.get(frameGroupID); diff --git a/x-pack/plugins/profiling/common/profiling.ts b/x-pack/plugins/profiling/common/profiling.ts index 8017189280ddd..6779a16774959 100644 --- a/x-pack/plugins/profiling/common/profiling.ts +++ b/x-pack/plugins/profiling/common/profiling.ts @@ -28,18 +28,20 @@ export enum FrameType { JavaScript, } +const frameTypeDescriptions = { + [FrameType.Unsymbolized]: '', + [FrameType.Python]: 'Python', + [FrameType.PHP]: 'PHP', + [FrameType.Native]: 'Native', + [FrameType.Kernel]: 'Kernel', + [FrameType.JVM]: 'JVM/Hotspot', + [FrameType.Ruby]: 'Ruby', + [FrameType.Perl]: 'Perl', + [FrameType.JavaScript]: 'JavaScript', +}; + export function describeFrameType(ft: FrameType): string { - return { - [FrameType.Unsymbolized]: '', - [FrameType.Python]: 'Python', - [FrameType.PHP]: 'PHP', - [FrameType.Native]: 'Native', - [FrameType.Kernel]: 'Kernel', - [FrameType.JVM]: 'JVM/Hotspot', - [FrameType.Ruby]: 'Ruby', - [FrameType.Perl]: 'Perl', - [FrameType.JavaScript]: 'JavaScript', - }[ft]; + return frameTypeDescriptions[ft]; } export interface StackTraceEvent { @@ -69,10 +71,22 @@ export interface StackFrame { SourceType: number; } +export const emptyStackFrame: StackFrame = { + FileName: '', + FunctionName: '', + FunctionOffset: 0, + LineNumber: 0, + SourceType: 0, +}; + export interface Executable { FileName: string; } +export const emptyExecutable: Executable = { + FileName: '', +}; + export interface StackFrameMetadata { // StackTrace.FrameID FrameID: string; @@ -221,8 +235,8 @@ export function groupStackFrameMetadataByStackTrace( const frameID = trace.FrameIDs[i]; const fileID = trace.FileIDs[i]; const addressOrLine = trace.AddressOrLines[i]; - const frame = stackFrames.get(frameID)!; - const executable = executables.get(fileID)!; + const frame = stackFrames.get(frameID) ?? emptyStackFrame; + const executable = executables.get(fileID) ?? emptyExecutable; frameMetadata[i] = createStackFrameMetadata({ FrameID: frameID, diff --git a/x-pack/plugins/profiling/public/components/flamegraph.tsx b/x-pack/plugins/profiling/public/components/flamegraph.tsx index afc241394aafb..9abac27ef9fb2 100644 --- a/x-pack/plugins/profiling/public/components/flamegraph.tsx +++ b/x-pack/plugins/profiling/public/components/flamegraph.tsx @@ -226,9 +226,9 @@ export const FlameGraph: React.FC = ({ exeFileName: highlightedFrame.ExeFileName, sourceFileName: highlightedFrame.SourceFilename, functionName: highlightedFrame.FunctionName, - samples: primaryFlamegraph.Value[highlightedVmIndex], + samples: primaryFlamegraph.Samples[highlightedVmIndex], childSamples: - primaryFlamegraph.Value[highlightedVmIndex] - + primaryFlamegraph.Samples[highlightedVmIndex] - primaryFlamegraph.CountExclusive[highlightedVmIndex], } : undefined; @@ -275,7 +275,7 @@ export const FlameGraph: React.FC = ({ const valueIndex = props.values[0].valueAccessor as number; const label = primaryFlamegraph.Label[valueIndex]; - const samples = primaryFlamegraph.Value[valueIndex]; + const samples = primaryFlamegraph.Samples[valueIndex]; const countInclusive = primaryFlamegraph.CountInclusive[valueIndex]; const countExclusive = primaryFlamegraph.CountExclusive[valueIndex]; const nodeID = primaryFlamegraph.ID[valueIndex]; @@ -291,8 +291,8 @@ export const FlameGraph: React.FC = ({ comparisonCountInclusive={comparisonNode?.CountInclusive} comparisonCountExclusive={comparisonNode?.CountExclusive} totalSamples={totalSamples} - comparisonTotalSamples={comparisonFlamegraph?.Value[0]} - comparisonSamples={comparisonNode?.Value} + comparisonTotalSamples={comparisonFlamegraph?.Samples[0]} + comparisonSamples={comparisonNode?.Samples} /> ); }, diff --git a/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts b/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts index 1402897b966ac..c63a73185d26b 100644 --- a/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts +++ b/x-pack/plugins/profiling/public/utils/get_flamegraph_model/index.ts @@ -4,10 +4,14 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { ColumnarViewModel } from '@elastic/charts'; import d3 from 'd3'; import { sum, uniqueId } from 'lodash'; -import { ElasticFlameGraph, FlameGraphComparisonMode, rgbToRGBA } from '../../../common/flamegraph'; +import { + createColumnarViewModel, + ElasticFlameGraph, + FlameGraphComparisonMode, + rgbToRGBA, +} from '../../../common/flamegraph'; import { getInterpolationValue } from './get_interpolation_value'; const nullColumnarViewModel = { @@ -37,21 +41,19 @@ export function getFlamegraphModel({ }) { const comparisonNodesById: Record< string, - { Value: number; CountInclusive: number; CountExclusive: number } + { Samples: number; CountInclusive: number; CountExclusive: number } > = {}; if (!primaryFlamegraph || !primaryFlamegraph.Label || primaryFlamegraph.Label.length === 0) { return { key: uniqueId(), viewModel: nullColumnarViewModel, comparisonNodesById }; } - let colors: number[] | undefined = primaryFlamegraph.Color; + const viewModel = createColumnarViewModel(primaryFlamegraph, comparisonFlamegraph === undefined); if (comparisonFlamegraph) { - colors = []; - comparisonFlamegraph.ID.forEach((nodeID, index) => { comparisonNodesById[nodeID] = { - Value: comparisonFlamegraph.Value[index], + Samples: comparisonFlamegraph.Samples[index], CountInclusive: comparisonFlamegraph.CountInclusive[index], CountExclusive: comparisonFlamegraph.CountExclusive[index], }; @@ -86,8 +88,8 @@ export function getFlamegraphModel({ : primaryFlamegraph.TotalSeconds / comparisonFlamegraph.TotalSeconds; primaryFlamegraph.ID.forEach((nodeID, index) => { - const samples = primaryFlamegraph.Value[index]; - const comparisonSamples = comparisonNodesById[nodeID]?.Value as number | undefined; + const samples = primaryFlamegraph.Samples[index]; + const comparisonSamples = comparisonNodesById[nodeID]?.Samples as number | undefined; const foreground = comparisonMode === FlameGraphComparisonMode.Absolute ? samples : samples / totalSamples; @@ -110,26 +112,14 @@ export function getFlamegraphModel({ ? positiveChangeInterpolator(interpolationValue) : negativeChangeInterpolator(Math.abs(interpolationValue)); - colors!.push(...rgbToRGBA(Number(nodeColor.replace('#', '0x')))); + const rgba = rgbToRGBA(Number(nodeColor.replace('#', '0x'))); + viewModel.color.set(rgba, 4 * index); }); } - const value = new Float64Array(primaryFlamegraph.Value); - const position = new Float32Array(primaryFlamegraph.Position); - const size = new Float32Array(primaryFlamegraph.Size); - const color = new Float32Array(colors); - return { key: uniqueId(), - viewModel: { - label: primaryFlamegraph.Label, - value, - color, - position0: position, - position1: position, - size0: size, - size1: size, - } as ColumnarViewModel, + viewModel, comparisonNodesById, }; } diff --git a/x-pack/plugins/profiling/server/routes/flamechart.ts b/x-pack/plugins/profiling/server/routes/flamechart.ts index 0f37ed4886412..6d27305a82c69 100644 --- a/x-pack/plugins/profiling/server/routes/flamechart.ts +++ b/x-pack/plugins/profiling/server/routes/flamechart.ts @@ -8,12 +8,8 @@ import { schema } from '@kbn/config-schema'; import { RouteRegisterParameters } from '.'; import { getRoutePaths } from '../../common'; -import { createCallerCalleeGraph } from '../../common/callercallee'; -import { - createColumnarCallerCallee, - createFlameGraph, - ElasticFlameGraph, -} from '../../common/flamegraph'; +import { createCalleeTree } from '../../common/callee'; +import { createFlameGraph } from '../../common/flamegraph'; import { createProfilingEsClient } from '../utils/create_profiling_es_client'; import { withProfilingSpan } from '../utils/with_profiling_span'; import { getClient } from './compat'; @@ -46,55 +42,57 @@ export function registerFlameChartSearchRoute({ router, logger }: RouteRegisterP }); const totalSeconds = timeTo - timeFrom; - const { stackTraces, executables, stackFrames, eventsIndex, totalCount, stackTraceEvents } = - await getExecutablesAndStackTraces({ - logger, - client: createProfilingEsClient({ request, esClient }), - filter, - sampleSize: targetSampleSize, - }); + const { + stackTraces, + executables, + stackFrames, + eventsIndex, + totalCount, + totalFrames, + stackTraceEvents, + } = await getExecutablesAndStackTraces({ + logger, + client: createProfilingEsClient({ request, esClient }), + filter, + sampleSize: targetSampleSize, + }); const flamegraph = await withProfilingSpan('create_flamegraph', async () => { const t0 = Date.now(); - const graph = createCallerCalleeGraph( + const tree = createCalleeTree( stackTraceEvents, stackTraces, stackFrames, - executables + executables, + totalFrames ); - logger.info(`creating caller-callee graph took ${Date.now() - t0} ms`); + logger.info(`creating callee tree took ${Date.now() - t0} ms`); - const t1 = Date.now(); - const columnar = createColumnarCallerCallee(graph); - logger.info(`creating columnar caller-callee graph took ${Date.now() - t1} ms`); + // sampleRate is 1/5^N, with N being the downsampled index the events were fetched from. + // N=0: full events table (sampleRate is 1) + // N=1: downsampled by 5 (sampleRate is 0.2) + // ... - const t2 = Date.now(); - const fg = createFlameGraph(columnar); - logger.info(`creating flamegraph took ${Date.now() - t2} ms`); + // totalCount is the sum(Count) of all events in the filter range in the + // downsampled index we were looking at. + // To estimate how many events we have in the full events index: totalCount / sampleRate. + // Do the same for single entries in the events array. + + const t1 = Date.now(); + const fg = createFlameGraph( + tree, + totalSeconds, + Math.floor(totalCount / eventsIndex.sampleRate), + totalCount + ); + logger.info(`creating flamegraph took ${Date.now() - t1} ms`); return fg; }); - // sampleRate is 1/5^N, with N being the downsampled index the events were fetched from. - // N=0: full events table (sampleRate is 1) - // N=1: downsampled by 5 (sampleRate is 0.2) - // ... - - // totalCount is the sum(Count) of all events in the filter range in the - // downsampled index we were looking at. - // To estimate how many events we have in the full events index: totalCount / sampleRate. - // Do the same for single entries in the events array. - - const body: ElasticFlameGraph = { - ...flamegraph, - TotalSeconds: totalSeconds, - TotalTraces: Math.floor(totalCount / eventsIndex.sampleRate), - SampledTraces: totalCount, - }; - logger.info('returning payload response to client'); - return response.ok({ body }); + return response.ok({ body: flamegraph }); } catch (e) { logger.error(e); return response.customError({ diff --git a/x-pack/plugins/profiling/server/routes/get_executables_and_stacktraces.ts b/x-pack/plugins/profiling/server/routes/get_executables_and_stacktraces.ts index 4025022222177..2c63b82c443f7 100644 --- a/x-pack/plugins/profiling/server/routes/get_executables_and_stacktraces.ts +++ b/x-pack/plugins/profiling/server/routes/get_executables_and_stacktraces.ts @@ -68,7 +68,7 @@ export async function getExecutablesAndStackTraces({ stackTraceEvents.set(id, Math.floor(count / (eventsIndex.sampleRate * p))); } - const { stackTraces, stackFrameDocIDs, executableDocIDs } = await mgetStackTraces({ + const { stackTraces, totalFrames, stackFrameDocIDs, executableDocIDs } = await mgetStackTraces({ logger, client, events: stackTraceEvents, @@ -86,6 +86,7 @@ export async function getExecutablesAndStackTraces({ stackFrames, stackTraceEvents, totalCount, + totalFrames, eventsIndex, }; }); diff --git a/x-pack/plugins/profiling/server/routes/stacktrace.ts b/x-pack/plugins/profiling/server/routes/stacktrace.ts index fca1c56ebe711..4ae7d91596f10 100644 --- a/x-pack/plugins/profiling/server/routes/stacktrace.ts +++ b/x-pack/plugins/profiling/server/routes/stacktrace.ts @@ -18,6 +18,8 @@ import { ProfilingStackTrace, } from '../../common/elasticsearch'; import { + emptyExecutable, + emptyStackFrame, Executable, FileID, StackFrame, @@ -310,7 +312,7 @@ export async function mgetStackTraces({ ); } - return { stackTraces, stackFrameDocIDs, executableDocIDs }; + return { stackTraces, totalFrames, stackFrameDocIDs, executableDocIDs }; } export async function mgetStackFrames({ @@ -352,13 +354,7 @@ export async function mgetStackFrames({ }); framesFound++; } else { - stackFrames.set(frame._id, { - FileName: '', - FunctionName: '', - FunctionOffset: 0, - LineNumber: 0, - SourceType: 0, - }); + stackFrames.set(frame._id, emptyStackFrame); } } logger.info(`processing data took ${Date.now() - t0} ms`); @@ -403,9 +399,7 @@ export async function mgetExecutables({ }); exeFound++; } else { - executables.set(exe._id, { - FileName: '', - }); + executables.set(exe._id, emptyExecutable); } } logger.info(`processing data took ${Date.now() - t0} ms`); From 5d482652849191d44836bdd83884ab84ce5a1add Mon Sep 17 00:00:00 2001 From: Kyle Pollich Date: Mon, 26 Sep 2022 13:35:11 -0400 Subject: [PATCH 26/51] Fix error rendering policy editor (#141705) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/fleet/server/services/package_policy.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index 70f65bb9b7987..7f294ca89d65f 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -801,7 +801,6 @@ class PackagePolicyClientImpl implements PackagePolicyClient { savedObjectsClient: soClient, pkgName: packagePolicy!.package!.name, pkgVersion: pkgVersion ?? '', - skipArchive: true, }); } From 74d39d87d82467720b4e0583fac3ff620f683da6 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Mon, 26 Sep 2022 11:00:00 -0700 Subject: [PATCH 27/51] [DOCS] Add ML open API output to appendix (#141556) --- .../machine-learning/ml-apis-passthru.adoc | 192 ++++++++++++++++++ .../machine-learning/ml-apis.asciidoc | 10 + docs/api-generated/template/index.mustache | 170 ++++++++++++++++ docs/apis.asciidoc | 14 ++ docs/index.asciidoc | 3 + docs/redirects.asciidoc | 5 - 6 files changed, 389 insertions(+), 5 deletions(-) create mode 100644 docs/api-generated/machine-learning/ml-apis-passthru.adoc create mode 100644 docs/api-generated/machine-learning/ml-apis.asciidoc create mode 100644 docs/api-generated/template/index.mustache create mode 100644 docs/apis.asciidoc diff --git a/docs/api-generated/machine-learning/ml-apis-passthru.adoc b/docs/api-generated/machine-learning/ml-apis-passthru.adoc new file mode 100644 index 0000000000000..a1275f2212ad6 --- /dev/null +++ b/docs/api-generated/machine-learning/ml-apis-passthru.adoc @@ -0,0 +1,192 @@ +//// +This content is generated from the open API specification. +Any modifications made to this file will be overwritten. +//// + +++++ + +++++ diff --git a/docs/api-generated/machine-learning/ml-apis.asciidoc b/docs/api-generated/machine-learning/ml-apis.asciidoc new file mode 100644 index 0000000000000..3482109d4ab3e --- /dev/null +++ b/docs/api-generated/machine-learning/ml-apis.asciidoc @@ -0,0 +1,10 @@ +[[machine-learning-api]] +== Machine learning APIs + +preview::[] + +//// +This file includes content that has been generated from https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/common/openapi. Any modifications required must be done in that open API specification. +//// + +include::ml-apis-passthru.adoc[] \ No newline at end of file diff --git a/docs/api-generated/template/index.mustache b/docs/api-generated/template/index.mustache new file mode 100644 index 0000000000000..8c1162f909508 --- /dev/null +++ b/docs/api-generated/template/index.mustache @@ -0,0 +1,170 @@ +//// +This content is generated from the open API specification. +Any modifications made to this file will be overwritten. +//// + +++++ +
+

Access

+ {{#hasAuthMethods}} +
    + {{#authMethods}} +
  1. {{#isBasic}}HTTP Basic Authentication{{/isBasic}}{{#isOAuth}}OAuth AuthorizationUrl:{{authorizationUrl}}TokenUrl:{{tokenUrl}}{{/isOAuth}}{{#isApiKey}}APIKey KeyParamName:{{keyParamName}} KeyInQuery:{{isKeyInQuery}} KeyInHeader:{{isKeyInHeader}}{{/isApiKey}}
  2. + {{/authMethods}} +
+ {{/hasAuthMethods}} + +

Methods

+ [ Jump to Models ] + + {{! for the tables of content, I cheat and don't use CSS styles.... }} +

Table of Contents

+
{{access}}
+ {{#apiInfo}} + {{#apis}} + {{#operations}} +

{{baseName}}

+ + {{/operations}} + {{/apis}} + {{/apiInfo}} + + {{#apiInfo}} + {{#apis}} + {{#operations}} +

{{baseName}}

+ {{#operation}} +
+
+ Up +
{{httpMethod}} {{path}}
+
{{summary}} ({{nickname}})
+ {{! notes is operation.description. So why rename it and make it super confusing???? }} +
{{notes}}
+ + {{#hasPathParams}} +

Path parameters

+
+ {{#pathParams}}{{>pathParam}}{{/pathParams}} +
+ {{/hasPathParams}} + + {{#hasConsumes}} +

Consumes

+ This API call consumes the following media types via the Content-Type request header: +
    + {{#consumes}} +
  • {{{mediaType}}}
  • + {{/consumes}} +
+ {{/hasConsumes}} + + {{#hasBodyParam}} +

Request body

+
+ {{#bodyParams}}{{>bodyParam}}{{/bodyParams}} +
+ {{/hasBodyParam}} + + {{#hasHeaderParams}} +

Request headers

+
+ {{#headerParams}}{{>headerParam}}{{/headerParams}} +
+ {{/hasHeaderParams}} + + {{#hasQueryParams}} +

Query parameters

+
+ {{#queryParams}}{{>queryParam}}{{/queryParams}} +
+ {{/hasQueryParams}} + + {{#hasFormParams}} +

Form parameters

+
+ {{#formParams}}{{>formParam}}{{/formParams}} +
+ {{/hasFormParams}} + + {{#returnType}} +

Return type

+
+ {{#hasReference}}{{^returnSimpleType}}{{returnContainer}}[{{/returnSimpleType}}{{returnBaseType}}{{^returnSimpleType}}]{{/returnSimpleType}}{{/hasReference}} + {{^hasReference}}{{returnType}}{{/hasReference}} +
+ {{/returnType}} + + + + {{#hasExamples}} + {{#examples}} +

Example data

+
Content-Type: {{{contentType}}}
+
{{{example}}}
+ {{/examples}} + {{/hasExamples}} + + {{#hasProduces}} +

Produces

+ This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
    + {{#produces}} +
  • {{{mediaType}}}
  • + {{/produces}} +
+ {{/hasProduces}} + +

Responses

+ {{#responses}} +

{{code}}

+ {{message}} + {{^containerType}}{{dataType}}{{/containerType}} + {{#examples}} +

Example data

+
Content-Type: {{{contentType}}}
+
{{example}}
+ {{/examples}} + {{/responses}} +
+
+ {{/operation}} + {{/operations}} + {{/apis}} + {{/apiInfo}} + +

Models

+ [ Jump to Methods ] + +

Table of Contents

+
    + {{#models}} + {{#model}} +
  1. {{name}}{{#title}} - {{.}}{{/title}}
  2. + {{/model}} + {{/models}} +
+ + {{#models}} + {{#model}} +
+

{{name}}{{#title}} - {{.}}{{/title}} Up

+ {{#unescapedDescription}}
{{.}}
{{/unescapedDescription}} +
+ {{#vars}}
{{name}} {{^required}}(optional){{/required}}
{{^isPrimitiveType}}{{dataType}}{{/isPrimitiveType}} {{unescapedDescription}} {{#dataFormat}}format: {{{.}}}{{/dataFormat}}
+ {{#isEnum}} +
Enum:
+ {{#_enum}}
{{this}}
{{/_enum}} + {{/isEnum}} + {{/vars}} +
+
+ {{/model}} + {{/models}} +
+++++ diff --git a/docs/apis.asciidoc b/docs/apis.asciidoc new file mode 100644 index 0000000000000..8fb4caa7d3fca --- /dev/null +++ b/docs/apis.asciidoc @@ -0,0 +1,14 @@ +[role="exclude",id="apis"] += APIs + +[partintro] +-- + +preview::[] + +These APIs are documented using the OpenAPI specification. The current supported +version of the specification is 3.0. For more information, go to https://openapi-generator.tech/[OpenAPI Generator] + +-- + +include::api-generated/machine-learning/ml-apis.asciidoc[] \ No newline at end of file diff --git a/docs/index.asciidoc b/docs/index.asciidoc index 41321f991c1b0..2823529df18d3 100644 --- a/docs/index.asciidoc +++ b/docs/index.asciidoc @@ -29,4 +29,7 @@ include::CHANGELOG.asciidoc[] include::developer/index.asciidoc[] +include::apis.asciidoc[] + include::redirects.asciidoc[] + diff --git a/docs/redirects.asciidoc b/docs/redirects.asciidoc index 1a0757453c855..5c12048315dec 100644 --- a/docs/redirects.asciidoc +++ b/docs/redirects.asciidoc @@ -420,8 +420,3 @@ This page has been deleted. Refer to <>. == Sync machine learning saved objects API This page has been deleted. Refer to <>. - -[role="exclude",id="machine-learning-api"] -== Machine learning APIs - -This page has been deleted. Refer to <>. \ No newline at end of file From 7a3e3bad44a30e6e3bb3180fafcbbd39c37ff913 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Mon, 26 Sep 2022 11:08:44 -0700 Subject: [PATCH 28/51] [DOCS] Omit specs for default spaces and extra tags in case APIs (#138779) --- .../plugins/cases/docs/openapi/bundled.json | 4124 +---------------- .../plugins/cases/docs/openapi/bundled.yaml | 3384 +------------- .../components/parameters/space_id.yaml | 2 +- .../cases/docs/openapi/entrypoint.yaml | 31 - .../cases/docs/openapi/paths/api@cases.yaml | 175 - .../docs/openapi/paths/api@cases@_find.yaml | 158 - .../paths/api@cases@alerts@{alertid}.yaml | 37 - .../openapi/paths/api@cases@configure.yaml | 93 - .../api@cases@configure@connectors@_find.yaml | 28 - ...api@cases@configure@{configurationid}.yaml | 57 - .../openapi/paths/api@cases@reporters.yaml | 34 - .../docs/openapi/paths/api@cases@status.yaml | 34 - .../docs/openapi/paths/api@cases@tags.yaml | 36 - .../openapi/paths/api@cases@{caseid}.yaml | 35 - .../paths/api@cases@{caseid}@alerts.yaml | 29 - .../paths/api@cases@{caseid}@comments.yaml | 126 - ...i@cases@{caseid}@comments@{commentid}.yaml | 50 - ...caseid}@connector@{connectorid}@_push.yaml | 35 - .../api@cases@{caseid}@user_actions.yaml | 29 - .../openapi/paths/s@{spaceid}@api@cases.yaml | 3 - .../paths/s@{spaceid}@api@cases@_find.yaml | 1 - ...@{spaceid}@api@cases@alerts@{alertid}.yaml | 1 - .../s@{spaceid}@api@cases@configure.yaml | 2 - ...@api@cases@configure@connectors@_find.yaml | 1 - ...api@cases@configure@{configurationid}.yaml | 1 - .../s@{spaceid}@api@cases@reporters.yaml | 1 - .../paths/s@{spaceid}@api@cases@status.yaml | 1 - .../paths/s@{spaceid}@api@cases@tags.yaml | 1 - .../paths/s@{spaceid}@api@cases@{caseid}.yaml | 1 - ...s@{spaceid}@api@cases@{caseid}@alerts.yaml | 1 - ...{spaceid}@api@cases@{caseid}@comments.yaml | 4 - ...i@cases@{caseid}@comments@{commentid}.yaml | 2 - ...caseid}@connector@{connectorid}@_push.yaml | 1 - ...ceid}@api@cases@{caseid}@user_actions.yaml | 1 - 34 files changed, 43 insertions(+), 8476 deletions(-) delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@_find.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@alerts@{alertid}.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@configure.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@configure@connectors@_find.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@configure@{configurationid}.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@reporters.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@status.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@tags.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@alerts.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@comments.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@comments@{commentid}.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@connector@{connectorid}@_push.yaml delete mode 100644 x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@user_actions.yaml diff --git a/x-pack/plugins/cases/docs/openapi/bundled.json b/x-pack/plugins/cases/docs/openapi/bundled.json index 3822f2f458a0b..4202c658ee4ff 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.json +++ b/x-pack/plugins/cases/docs/openapi/bundled.json @@ -29,4052 +29,13 @@ } ], "paths": { - "/api/cases": { - "post": { - "summary": "Creates a case in the default space.", - "operationId": "createCaseDefaultSpace", - "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're creating.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "connector": { - "description": "An object that contains the connector configuration.", - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - }, - "required": [ - "fields", - "id", - "name", - "type" - ] - }, - "description": { - "description": "The description for the case.", - "type": "string" - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "settings": { - "$ref": "#/components/schemas/settings" - }, - "severity": { - "$ref": "#/components/schemas/severity_property" - }, - "tags": { - "description": "The words and phrases that help categorize cases. It can be an empty array.", - "type": "array", - "items": { - "type": "string" - } - }, - "title": { - "description": "A title for the case.", - "type": "string" - } - }, - "required": [ - "connector", - "description", - "owner", - "settings", - "tags", - "title" - ] - }, - "examples": { - "createCaseRequest": { - "$ref": "#/components/examples/create_case_request" - } - } - } - } - }, - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "object", - "properties": { - "closed_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "closed_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "comments": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/alert_comment_response_properties" - }, - { - "$ref": "#/components/schemas/user_comment_response_properties" - } - ] - }, - "example": [] - }, - "connector": { - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - } - }, - "created_at": { - "type": "string", - "format": "date-time", - "example": "2022-05-13T09:16:17.416Z" - }, - "created_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - } - }, - "description": { - "type": "string", - "example": "A case description." - }, - "duration": { - "type": "integer", - "description": "The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero.\n", - "example": 120 - }, - "external_service": { - "$ref": "#/components/schemas/external_service" - }, - "id": { - "type": "string", - "example": "66b9aa00-94fa-11ea-9f74-e7e108796192" - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "settings": { - "$ref": "#/components/schemas/settings" - }, - "severity": { - "$ref": "#/components/schemas/severity_property" - }, - "status": { - "$ref": "#/components/schemas/status" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "example": [ - "tag-1" - ] - }, - "title": { - "type": "string", - "example": "Case title 1" - }, - "totalAlerts": { - "type": "integer", - "example": 0 - }, - "totalComment": { - "type": "integer", - "example": 0 - }, - "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "updated_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "version": { - "type": "string", - "example": "WzUzMiwxXQ==" - } - } - }, - "examples": { - "createCaseResponse": { - "$ref": "#/components/examples/create_case_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "delete": { - "summary": "Deletes one or more cases from the default space.", - "operationId": "deleteCaseDefaultSpace", - "description": "You must have `read` or `all` privileges and the `delete` sub-feature privilege for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're deleting.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - }, - { - "name": "ids", - "description": "The cases that you want to removed. To retrieve case IDs, use the find cases API. All non-ASCII characters must be URL encoded.", - "in": "query", - "required": true, - "schema": { - "type": "string" - }, - "example": "d4e7abb0-b462-11ec-9a8d-698504725a43" - } - ], - "responses": { - "204": { - "description": "Indicates a successful call." - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "patch": { - "summary": "Updates one or more cases in the default space.", - "operationId": "updateCaseDefaultSpace", - "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're updating.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "cases": { - "type": "array", - "items": { - "type": "object", - "properties": { - "connector": { - "description": "An object that contains the connector configuration.", - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - }, - "required": [ - "fields", - "id", - "name", - "type" - ] - }, - "description": { - "description": "The description for the case.", - "type": "string" - }, - "id": { - "description": "The identifier for the case.", - "type": "string" - }, - "settings": { - "$ref": "#/components/schemas/settings" - }, - "severity": { - "$ref": "#/components/schemas/severity_property" - }, - "status": { - "$ref": "#/components/schemas/status" - }, - "tags": { - "description": "The words and phrases that help categorize cases.", - "type": "array", - "items": { - "type": "string" - } - }, - "title": { - "description": "A title for the case.", - "type": "string" - }, - "version": { - "description": "The current version of the case.", - "type": "string" - } - }, - "required": [ - "id", - "version" - ] - } - } - } - }, - "examples": { - "updateCaseRequest": { - "$ref": "#/components/examples/update_case_request" - } - } - } - } - }, - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "object", - "properties": { - "closed_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "closed_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "comments": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/alert_comment_response_properties" - }, - { - "$ref": "#/components/schemas/user_comment_response_properties" - } - ] - }, - "example": [] - }, - "connector": { - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - } - }, - "created_at": { - "type": "string", - "format": "date-time", - "example": "2022-05-13T09:16:17.416Z" - }, - "created_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - } - }, - "description": { - "type": "string", - "example": "A case description." - }, - "duration": { - "type": "integer", - "description": "The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero.\n", - "example": 120 - }, - "external_service": { - "$ref": "#/components/schemas/external_service" - }, - "id": { - "type": "string", - "example": "66b9aa00-94fa-11ea-9f74-e7e108796192" - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "settings": { - "$ref": "#/components/schemas/settings" - }, - "severity": { - "$ref": "#/components/schemas/severity_property" - }, - "status": { - "$ref": "#/components/schemas/status" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "example": [ - "tag-1" - ] - }, - "title": { - "type": "string", - "example": "Case title 1" - }, - "totalAlerts": { - "type": "integer", - "example": 0 - }, - "totalComment": { - "type": "integer", - "example": 0 - }, - "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "updated_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "version": { - "type": "string", - "example": "WzUzMiwxXQ==" - } - } - }, - "examples": { - "updateCaseResponse": { - "$ref": "#/components/examples/update_case_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/_find": { - "get": { - "summary": "Retrieves a paginated subset of cases from the default space.", - "operationId": "getCasesDefaultSpace", - "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "name": "defaultSearchOperator", - "in": "query", - "description": "The default operator to use for the simple_query_string.", - "schema": { - "type": "string", - "default": "OR" - }, - "example": "OR" - }, - { - "name": "fields", - "in": "query", - "description": "The fields in the entity to return in the response.", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - }, - { - "name": "from", - "in": "query", - "description": "[preview] Returns only cases that were created after a specific date. The date must be specified as a KQL data range or date match expression. This functionality is in technical preview and may be changed or removed in a future release. Elastic will apply best effort to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.\n", - "schema": { - "type": "string" - }, - "example": "now-1d", - "x-technical-preview": true - }, - { - "$ref": "#/components/parameters/owner" - }, - { - "name": "page", - "in": "query", - "description": "The page number to return.", - "schema": { - "type": "integer", - "default": 1 - }, - "example": 1 - }, - { - "name": "perPage", - "in": "query", - "description": "The number of rules to return per page.", - "schema": { - "type": "integer", - "default": 20 - }, - "example": 20 - }, - { - "name": "reporters", - "in": "query", - "description": "Filters the returned cases by the user name of the reporter.", - "schema": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "example": "elastic" - }, - { - "name": "search", - "in": "query", - "description": "An Elasticsearch simple_query_string query that filters the objects in the response.", - "schema": { - "type": "string" - } - }, - { - "name": "searchFields", - "in": "query", - "description": "The fields to perform the simple_query_string parsed query against.", - "schema": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - } - }, - { - "$ref": "#/components/parameters/severity" - }, - { - "name": "sortField", - "in": "query", - "description": "Determines which field is used to sort the results.", - "schema": { - "type": "string", - "enum": [ - "createdAt", - "updatedAt" - ], - "default": "createdAt" - }, - "example": "updatedAt" - }, - { - "name": "sortOrder", - "in": "query", - "description": "Determines the sort order.", - "schema": { - "type": "string", - "enum": [ - "asc", - "desc" - ], - "default": "desc" - }, - "example": "asc" - }, - { - "in": "query", - "name": "status", - "description": "Filters the returned cases by state.", - "schema": { - "type": "string", - "enum": [ - "closed", - "in-progress", - "open" - ] - }, - "example": "open" - }, - { - "name": "tags", - "in": "query", - "description": "Filters the returned cases by tags.", - "schema": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "example": "tag-1" - }, - { - "name": "to", - "in": "query", - "description": "Returns only cases that were created before a specific date. The date must be specified as a KQL data range or date match expression.", - "schema": { - "type": "string" - }, - "example": "now%2B1d", - "x-technical-preview": true - } - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "object", - "properties": { - "cases": { - "type": "array", - "items": { - "type": "object", - "properties": { - "closed_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "closed_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "comments": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/alert_comment_response_properties" - }, - { - "$ref": "#/components/schemas/user_comment_response_properties" - } - ] - }, - "example": [] - }, - "connector": { - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - } - }, - "created_at": { - "type": "string", - "format": "date-time", - "example": "2022-05-13T09:16:17.416Z" - }, - "created_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - } - }, - "description": { - "type": "string", - "example": "A case description." - }, - "duration": { - "type": "integer", - "description": "The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero.\n", - "example": 120 - }, - "external_service": { - "$ref": "#/components/schemas/external_service" - }, - "id": { - "type": "string", - "example": "66b9aa00-94fa-11ea-9f74-e7e108796192" - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "settings": { - "$ref": "#/components/schemas/settings" - }, - "severity": { - "$ref": "#/components/schemas/severity_property" - }, - "status": { - "$ref": "#/components/schemas/status" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "example": [ - "tag-1" - ] - }, - "title": { - "type": "string", - "example": "Case title 1" - }, - "totalAlerts": { - "type": "integer", - "example": 0 - }, - "totalComment": { - "type": "integer", - "example": 0 - }, - "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "updated_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "version": { - "type": "string", - "example": "WzUzMiwxXQ==" - } - } - } - }, - "count_closed_cases": { - "type": "integer" - }, - "count_in_progress_cases": { - "type": "integer" - }, - "count_open_cases": { - "type": "integer" - }, - "page": { - "type": "integer" - }, - "per_page": { - "type": "integer" - }, - "total": { - "type": "integer" - } - } - }, - "examples": { - "findCaseResponse": { - "$ref": "#/components/examples/find_case_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/alerts/{alertId}": { - "get": { - "summary": "Returns the cases associated with a specific alert in the default space.", - "operationId": "getCasesByAlertDefaultSpace", - "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.\n", - "x-technical-preview": true, - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/alert_id" - }, - { - "$ref": "#/components/parameters/owner" - } - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "The case identifier." - }, - "title": { - "type": "string", - "description": "The case title." - } - } - }, - "example": [ - { - "id": "06116b80-e1c3-11ec-be9b-9b1838238ee6", - "title": "security_case" - } - ] - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/configure": { - "get": { - "summary": "Retrieves external connection details, such as the closure type and default connector for cases in the default space.", - "operationId": "getCaseConfigurationDefaultSpace", - "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case configuration.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/owner" - } - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "closure_type": { - "$ref": "#/components/schemas/closure_types" - }, - "connector": { - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - } - }, - "created_at": { - "type": "string", - "format": "date-time", - "example": "2022-06-01T17:07:17.767Z" - }, - "created_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - } - } - }, - "error": { - "type": "string", - "example": null - }, - "id": { - "type": "string", - "example": "4a97a440-e1cd-11ec-be9b-9b1838238ee6" - }, - "mappings": { - "type": "array", - "items": { - "type": "object", - "properties": { - "action_type": { - "type": "string", - "example": "overwrite" - }, - "source": { - "type": "string", - "example": "title" - }, - "target": { - "type": "string", - "example": "summary" - } - } - } - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": "2022-06-01T19:58:48.169Z" - }, - "updated_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - } - }, - "nullable": true - }, - "version": { - "type": "string", - "example": "WzIwNzMsMV0=" - } - } - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "post": { - "summary": "Sets external connection details, such as the closure type and default connector for cases in the default space.", - "operationId": "setCaseConfigurationDefaultSpace", - "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case configuration. Connectors are used to interface with external systems. You must create a connector before you can use it in your cases. Refer to the add connectors API. If you set a default connector, it is automatically selected when you create cases in Kibana. If you use the create case API, however, you must still specify all of the connector details.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "closure_type": { - "$ref": "#/components/schemas/closure_types" - }, - "connector": { - "description": "An object that contains the connector configuration.", - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - }, - "required": [ - "fields", - "id", - "name", - "type" - ] - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "settings": { - "description": "An object that contains the case settings.", - "type": "object", - "properties": { - "syncAlerts": { - "description": "Turns alert syncing on or off.", - "type": "boolean", - "example": true - } - }, - "required": [ - "syncAlerts" - ] - } - }, - "required": [ - "closure_type", - "connector", - "owner" - ] - } - } - } - }, - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "closure_type": { - "$ref": "#/components/schemas/closure_types" - }, - "connector": { - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - } - }, - "created_at": { - "type": "string", - "format": "date-time", - "example": "2022-06-01T17:07:17.767Z" - }, - "created_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - } - } - }, - "error": { - "type": "string", - "example": null - }, - "id": { - "type": "string", - "example": "4a97a440-e1cd-11ec-be9b-9b1838238ee6" - }, - "mappings": { - "type": "array", - "items": { - "type": "object", - "properties": { - "action_type": { - "type": "string", - "example": "overwrite" - }, - "source": { - "type": "string", - "example": "title" - }, - "target": { - "type": "string", - "example": "summary" - } - } - } - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": "2022-06-01T19:58:48.169Z" - }, - "updated_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - } - }, - "nullable": true - }, - "version": { - "type": "string", - "example": "WzIwNzMsMV0=" - } - } - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/configure/{configurationId}": { - "patch": { - "summary": "Updates external connection details, such as the closure type and default connector for cases in the default space.", - "operationId": "updateCaseConfigurationDefaultSpace", - "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case configuration. Connectors are used to interface with external systems. You must create a connector before you can use it in your cases. Refer to the add connectors API.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - }, - { - "$ref": "#/components/parameters/configuration_id" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "closure_type": { - "$ref": "#/components/schemas/closure_types" - }, - "connector": { - "description": "An object that contains the connector configuration.", - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - }, - "required": [ - "fields", - "id", - "name", - "type" - ] - }, - "version": { - "description": "The version of the connector. To retrieve the version value, use the get configuration API.\n", - "type": "string", - "example": "WzIwMiwxXQ==" - } - }, - "required": [ - "version" - ] - } - } - } - }, - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "closure_type": { - "$ref": "#/components/schemas/closure_types" - }, - "connector": { - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - } - }, - "created_at": { - "type": "string", - "format": "date-time", - "example": "2022-06-01T17:07:17.767Z" - }, - "created_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - } - } - }, - "error": { - "type": "string", - "example": null - }, - "id": { - "type": "string", - "example": "4a97a440-e1cd-11ec-be9b-9b1838238ee6" - }, - "mappings": { - "type": "array", - "items": { - "type": "object", - "properties": { - "action_type": { - "type": "string", - "example": "overwrite" - }, - "source": { - "type": "string", - "example": "title" - }, - "target": { - "type": "string", - "example": "summary" - } - } - } - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": "2022-06-01T19:58:48.169Z" - }, - "updated_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - } - }, - "nullable": true - }, - "version": { - "type": "string", - "example": "WzIwNzMsMV0=" - } - } - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/configure/connectors/_find": { - "get": { - "summary": "Retrieves information about connectors for cases in the default space.", - "operationId": "getCaseConnectorsDefaultSpace", - "description": "In particular, only the connectors that are supported for use in cases are returned. You must have `read` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges.\n", - "tags": [ - "cases", - "kibana" - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "actionTypeId": { - "$ref": "#/components/schemas/connector_types" - }, - "config": { - "type": "object", - "properties": { - "apiUrl": { - "type": "string" - }, - "projectKey": { - "type": "string" - } - }, - "additionalProperties": true - }, - "id": { - "type": "string" - }, - "isDeprecated": { - "type": "boolean" - }, - "isMissingSecrets": { - "type": "boolean" - }, - "isPreconfigured": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "referencedByCount": { - "type": "integer" - } - } - } - }, - "examples": { - "findCaseResponse": { - "$ref": "#/components/examples/find_connector_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/reporters": { - "get": { - "summary": "Returns information about the users who opened cases in the default space.", - "operationId": "getCaseReportersDefaultSpace", - "description": "You must have read privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases. The API returns information about the users as they existed at the time of the case creation, including their name, full name, and email address. If any of those details change thereafter or if a user is deleted, the information returned by this API is unchanged.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/owner" - } - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - } - } - }, - "examples": { - "getReportersResponse": { - "$ref": "#/components/examples/get_reporters_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/status": { - "get": { - "summary": "Returns the number of cases that are open, closed, and in progress.", - "operationId": "getCaseStatusDefaultSpace", - "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.\n", - "tags": [ - "cases", - "kibana" - ], - "deprecated": true, - "parameters": [ - { - "$ref": "#/components/parameters/owner" - } - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "object", - "properties": { - "count_closed_cases": { - "type": "integer" - }, - "count_in_progress_cases": { - "type": "integer" - }, - "count_open_cases": { - "type": "integer" - } - } - }, - "examples": { - "getStatusResponse": { - "$ref": "#/components/examples/get_status_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/tags": { - "get": { - "summary": "Aggregates and returns a list of case tags in the default space.", - "operationId": "getCaseTagsDefaultSpace", - "description": "You must have read privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "in": "query", - "name": "owner", - "description": "A filter to limit the retrieved case statistics to a specific set of applications. If this parameter is omitted, the response contains tags from all cases that the user has access to read.", - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/owners" - }, - { - "type": "array", - "items": { - "$ref": "#/components/schemas/owners" - } - } - ] - } - } - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "array", - "items": { - "type": "string" - } - }, - "examples": { - "getTagsResponse": { - "$ref": "#/components/examples/get_tags_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/{caseId}": { - "get": { - "summary": "Retrieves information about a case in the default space.", - "operationId": "getCaseDefaultSpace", - "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're seeking.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/case_id" - }, - { - "in": "query", - "name": "includeComments", - "description": "Determines whether case comments are returned.", - "deprecated": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "object", - "properties": { - "closed_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "closed_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "comments": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/alert_comment_response_properties" - }, - { - "$ref": "#/components/schemas/user_comment_response_properties" - } - ] - }, - "example": [] - }, - "connector": { - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - } - }, - "created_at": { - "type": "string", - "format": "date-time", - "example": "2022-05-13T09:16:17.416Z" - }, - "created_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - } - }, - "description": { - "type": "string", - "example": "A case description." - }, - "duration": { - "type": "integer", - "description": "The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero.\n", - "example": 120 - }, - "external_service": { - "$ref": "#/components/schemas/external_service" - }, - "id": { - "type": "string", - "example": "66b9aa00-94fa-11ea-9f74-e7e108796192" - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "settings": { - "$ref": "#/components/schemas/settings" - }, - "severity": { - "$ref": "#/components/schemas/severity_property" - }, - "status": { - "$ref": "#/components/schemas/status" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "example": [ - "tag-1" - ] - }, - "title": { - "type": "string", - "example": "Case title 1" - }, - "totalAlerts": { - "type": "integer", - "example": 0 - }, - "totalComment": { - "type": "integer", - "example": 0 - }, - "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "updated_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "version": { - "type": "string", - "example": "WzUzMiwxXQ==" - } - } - }, - "examples": { - "getCaseResponse": { - "$ref": "#/components/examples/get_case_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/{caseId}/alerts": { - "get": { - "summary": "Gets all alerts attached to a case in the default space.", - "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.\n", - "operationId": "getCaseAlertsDefaultSpace", - "tags": [ - "cases", - "kibana" - ], - "x-technical-preview": true, - "parameters": [ - { - "$ref": "#/components/parameters/case_id" - } - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/alert_response_properties" - } - }, - "examples": { - "createCaseCommentResponse": { - "$ref": "#/components/examples/get_case_alerts_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/{caseId}/comments": { - "post": { - "summary": "Adds a comment or alert to a case in the default space.", - "operationId": "addCaseCommentDefaultSpace", - "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're creating.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - }, - { - "$ref": "#/components/parameters/case_id" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/add_alert_comment_request_properties" - }, - { - "$ref": "#/components/schemas/add_user_comment_request_properties" - } - ] - }, - "examples": { - "createCaseCommentRequest": { - "$ref": "#/components/examples/add_comment_request" - } - } - } - } - }, - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "object", - "properties": { - "closed_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "closed_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "comments": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/alert_comment_response_properties" - }, - { - "$ref": "#/components/schemas/user_comment_response_properties" - } - ] - }, - "example": [] - }, - "connector": { - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - } - }, - "created_at": { - "type": "string", - "format": "date-time", - "example": "2022-05-13T09:16:17.416Z" - }, - "created_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - } - }, - "description": { - "type": "string", - "example": "A case description." - }, - "duration": { - "type": "integer", - "description": "The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero.\n", - "example": 120 - }, - "external_service": { - "$ref": "#/components/schemas/external_service" - }, - "id": { - "type": "string", - "example": "66b9aa00-94fa-11ea-9f74-e7e108796192" - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "settings": { - "$ref": "#/components/schemas/settings" - }, - "severity": { - "$ref": "#/components/schemas/severity_property" - }, - "status": { - "$ref": "#/components/schemas/status" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "example": [ - "tag-1" - ] - }, - "title": { - "type": "string", - "example": "Case title 1" - }, - "totalAlerts": { - "type": "integer", - "example": 0 - }, - "totalComment": { - "type": "integer", - "example": 0 - }, - "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "updated_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "version": { - "type": "string", - "example": "WzUzMiwxXQ==" - } - } - }, - "examples": { - "createCaseCommentResponse": { - "$ref": "#/components/examples/add_comment_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "delete": { - "summary": "Deletes all comments and alerts from a case in the default space.", - "operationId": "deleteCaseCommentsDefaultSpace", - "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're deleting.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - }, - { - "$ref": "#/components/parameters/case_id" - } - ], - "responses": { - "204": { - "description": "Indicates a successful call." - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "patch": { - "summary": "Updates a comment or alert in a case in the default space.", - "operationId": "updateCaseCommentDefaultSpace", - "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're updating. NOTE: You cannot change the comment type or the owner of a comment.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - }, - { - "$ref": "#/components/parameters/case_id" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/update_alert_comment_request_properties" - }, - { - "$ref": "#/components/schemas/update_user_comment_request_properties" - } - ] - }, - "examples": { - "updateCaseCommentRequest": { - "$ref": "#/components/examples/update_comment_request" - } - } - } - } - }, - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "object", - "properties": { - "closed_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "closed_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "comments": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/alert_comment_response_properties" - }, - { - "$ref": "#/components/schemas/user_comment_response_properties" - } - ] - }, - "example": [] - }, - "connector": { - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - } - }, - "created_at": { - "type": "string", - "format": "date-time", - "example": "2022-05-13T09:16:17.416Z" - }, - "created_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - } - }, - "description": { - "type": "string", - "example": "A case description." - }, - "duration": { - "type": "integer", - "description": "The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero.\n", - "example": 120 - }, - "external_service": { - "$ref": "#/components/schemas/external_service" - }, - "id": { - "type": "string", - "example": "66b9aa00-94fa-11ea-9f74-e7e108796192" - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "settings": { - "$ref": "#/components/schemas/settings" - }, - "severity": { - "$ref": "#/components/schemas/severity_property" - }, - "status": { - "$ref": "#/components/schemas/status" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "example": [ - "tag-1" - ] - }, - "title": { - "type": "string", - "example": "Case title 1" - }, - "totalAlerts": { - "type": "integer", - "example": 0 - }, - "totalComment": { - "type": "integer", - "example": 0 - }, - "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "updated_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "version": { - "type": "string", - "example": "WzUzMiwxXQ==" - } - } - }, - "examples": { - "updateCaseCommentResponse": { - "$ref": "#/components/examples/update_comment_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "get": { - "summary": "Retrieves all the comments from a case in the default space.", - "operationId": "getAllCaseCommentsDefaultSpace", - "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases with the comments you're seeking.\n", - "tags": [ - "cases", - "kibana" - ], - "deprecated": true, - "parameters": [ - { - "$ref": "#/components/parameters/case_id" - } - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/components/schemas/alert_comment_response_properties" - }, - { - "$ref": "#/components/schemas/user_comment_response_properties" - } - ] - } - } - }, - "examples": {} - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/{caseId}/comments/{commentId}": { - "delete": { - "summary": "Deletes a comment or alert from a case in the default space.", - "operationId": "deleteCaseCommentDefaultSpace", - "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're deleting.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/kbn_xsrf" - }, - { - "$ref": "#/components/parameters/case_id" - }, - { - "$ref": "#/components/parameters/comment_id" - } - ], - "responses": { - "204": { - "description": "Indicates a successful call." - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "get": { - "summary": "Retrieves a comment from a case in the default space.", - "operationId": "getCaseCommentDefaultSpace", - "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases with the comments you're seeking.\n", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/case_id" - }, - { - "$ref": "#/components/parameters/comment_id" - } - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/alert_comment_response_properties" - }, - { - "$ref": "#/components/schemas/user_comment_response_properties" - } - ] - }, - "examples": { - "getCaseCommentResponse": { - "$ref": "#/components/examples/get_comment_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/{caseId}/connector/{connectorId}/_push": { - "post": { - "summary": "Pushes a case to an external service.", - "description": "You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges. You must also have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're pushing.\n", - "operationId": "pushCaseDefaultSpace", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/case_id" - }, - { - "$ref": "#/components/parameters/connector_id" - }, - { - "$ref": "#/components/parameters/kbn_xsrf" - } - ], - "requestBody": { - "content": { - "application/json": {} - } - }, - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "object", - "properties": { - "closed_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "closed_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "comments": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/alert_comment_response_properties" - }, - { - "$ref": "#/components/schemas/user_comment_response_properties" - } - ] - }, - "example": [] - }, - "connector": { - "type": "object", - "properties": { - "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", - "properties": { - "caseId": { - "description": "The case identifier for Swimlane connectors.", - "type": "string" - }, - "category": { - "description": "The category of the incident for ServiceNow ITSM and ServiceNow SecOps connectors.", - "type": "string" - }, - "destIp": { - "description": "A comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "impact": { - "description": "The effect an incident had on business for ServiceNow ITSM connectors.", - "type": "string" - }, - "issueType": { - "description": "The type of issue for Jira connectors.", - "type": "string" - }, - "issueTypes": { - "description": "The type of incident for IBM Resilient connectors.", - "type": "array", - "items": { - "type": "number" - } - }, - "malwareHash": { - "description": "A comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "string" - }, - "malwareUrl": { - "description": "A comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "string" - }, - "parent": { - "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", - "type": "string" - }, - "priority": { - "description": "The priority of the issue for Jira and ServiceNow SecOps connectors.", - "type": "string" - }, - "severity": { - "description": "The severity of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "severityCode": { - "description": "The severity code of the incident for IBM Resilient connectors.", - "type": "number" - }, - "sourceIp": { - "description": "A comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "string" - }, - "subcategory": { - "description": "The subcategory of the incident for ServiceNow ITSM connectors.", - "type": "string" - }, - "urgency": { - "description": "The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors.", - "type": "string" - } - }, - "example": null - }, - "id": { - "description": "The identifier for the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "name": { - "description": "The name of the connector. To create a case without a connector, use `none`.", - "type": "string", - "example": "none" - }, - "type": { - "$ref": "#/components/schemas/connector_types" - } - } - }, - "created_at": { - "type": "string", - "format": "date-time", - "example": "2022-05-13T09:16:17.416Z" - }, - "created_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - } - }, - "description": { - "type": "string", - "example": "A case description." - }, - "duration": { - "type": "integer", - "description": "The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero.\n", - "example": 120 - }, - "external_service": { - "$ref": "#/components/schemas/external_service" - }, - "id": { - "type": "string", - "example": "66b9aa00-94fa-11ea-9f74-e7e108796192" - }, - "owner": { - "$ref": "#/components/schemas/owners" - }, - "settings": { - "$ref": "#/components/schemas/settings" - }, - "severity": { - "$ref": "#/components/schemas/severity_property" - }, - "status": { - "$ref": "#/components/schemas/status" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "example": [ - "tag-1" - ] - }, - "title": { - "type": "string", - "example": "Case title 1" - }, - "totalAlerts": { - "type": "integer", - "example": 0 - }, - "totalComment": { - "type": "integer", - "example": 0 - }, - "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true, - "example": null - }, - "updated_by": { - "type": "object", - "properties": { - "email": { - "type": "string", - "example": null - }, - "full_name": { - "type": "string", - "example": null - }, - "username": { - "type": "string", - "example": "elastic" - }, - "profile_uid": { - "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" - } - }, - "nullable": true, - "example": null - }, - "version": { - "type": "string", - "example": "WzUzMiwxXQ==" - } - } - }, - "examples": { - "pushCaseResponse": { - "$ref": "#/components/examples/push_case_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "/api/cases/{caseId}/user_actions": { - "get": { - "summary": "Returns all user activity for a case in the default space.", - "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're seeking.\n", - "deprecated": true, - "operationId": "getCaseActivityDefaultSpace", - "tags": [ - "cases", - "kibana" - ], - "parameters": [ - { - "$ref": "#/components/parameters/case_id" - } - ], - "responses": { - "200": { - "description": "Indicates a successful call.", - "content": { - "application/json; charset=utf-8": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/user_actions_response_properties" - } - }, - "examples": { - "getCaseActivityResponse": { - "$ref": "#/components/examples/get_case_activity_response" - } - } - } - } - } - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, - "servers": [ - { - "url": "https://localhost:5601" - } - ] - }, "/s/{spaceId}/api/cases": { "post": { "summary": "Creates a case.", "operationId": "createCase", "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're creating.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -4498,8 +459,7 @@ "operationId": "deleteCase", "description": "You must have `read` or `all` privileges and the `delete` sub-feature privilege for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're deleting.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -4535,8 +495,7 @@ "operationId": "updateCase", "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're updating.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -4979,8 +938,7 @@ "operationId": "getCases", "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -5462,8 +1420,7 @@ "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.\n", "x-technical-preview": true, "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -5525,8 +1482,7 @@ "operationId": "getCaseConfiguration", "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case configuration.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -5737,8 +1693,7 @@ "operationId": "setCaseConfiguration", "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case configuration. Connectors are used to interface with external systems. You must create a connector before you can use it in your cases. Refer to the add connectors API. If you set a default connector, it is automatically selected when you create cases in Kibana. If you use the create case API, however, you must still specify all of the connector details.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -6088,8 +2043,7 @@ "operationId": "updateCaseConfiguration", "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case configuration. Connectors are used to interface with external systems. You must create a connector before you can use it in your cases. Refer to the add connectors API.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -6428,8 +2382,7 @@ "operationId": "getCaseConnectors", "description": "In particular, only the connectors that are supported for use in cases are returned. You must have `read` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -6509,8 +2462,7 @@ "operationId": "getCaseReporters", "description": "You must have read privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases. The API returns information about the users as they existed at the time of the case creation, including their name, full name, and email address. If any of those details change thereafter or if a user is deleted, the information returned by this API is unchanged.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -6577,8 +2529,7 @@ "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.\n", "deprecated": true, "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -6634,8 +2585,7 @@ "operationId": "getCaseTags", "description": "You must have read privileges for the **Cases*** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're seeking.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -6698,8 +2648,7 @@ "operationId": "getCase", "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're seeking.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -6997,8 +2946,7 @@ "x-technical-preview": true, "operationId": "getCaseAlerts", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -7046,8 +2994,7 @@ "operationId": "addCaseComment", "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're creating.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -7351,8 +3298,7 @@ "operationId": "deleteCaseComments", "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're deleting.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -7381,8 +3327,7 @@ "operationId": "updateCaseComment", "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're updating. NOTE: You cannot change the comment type or the owner of a comment.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -7687,8 +3632,7 @@ "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases with the comments you're seeking.\n", "deprecated": true, "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -7739,8 +3683,7 @@ "operationId": "deleteCaseComment", "description": "You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the cases you're deleting.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -7772,8 +3715,7 @@ "operationId": "getCaseComment", "description": "You must have `read` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security*** section of the Kibana feature privileges, depending on the owner of the cases with the comments you're seeking.\n", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -7828,8 +3770,7 @@ "description": "You must have `all` privileges for the **Actions and Connectors** feature in the **Management** section of the Kibana feature privileges. You must also have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case you're pushing.\n", "operationId": "pushCase", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -8128,8 +4069,7 @@ "deprecated": true, "operationId": "getCaseActivity", "tags": [ - "cases", - "kibana" + "cases" ], "parameters": [ { @@ -8193,6 +4133,16 @@ "name": "kbn-xsrf", "required": true }, + "space_id": { + "in": "path", + "name": "spaceId", + "description": "An identifier for the space. If `/s/` and the identifier are omitted from the path, the default space is used.", + "required": true, + "schema": { + "type": "string", + "example": "default" + } + }, "owner": { "in": "query", "name": "owner", @@ -8275,16 +4225,6 @@ "type": "string", "example": "abed3a70-71bd-11ea-a0b2-c51ea50a58e2" } - }, - "space_id": { - "in": "path", - "name": "spaceId", - "description": "An identifier for the space.", - "required": true, - "schema": { - "type": "string", - "example": "default" - } } }, "schemas": { diff --git a/x-pack/plugins/cases/docs/openapi/bundled.yaml b/x-pack/plugins/cases/docs/openapi/bundled.yaml index a328d0282a515..7f02703b161a6 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.yaml +++ b/x-pack/plugins/cases/docs/openapi/bundled.yaml @@ -17,3350 +17,6 @@ servers: - url: http://localhost:5601 description: local paths: - /api/cases: - post: - summary: Creates a case in the default space. - operationId: createCaseDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're creating. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - requestBody: - content: - application/json: - schema: - type: object - properties: - connector: - description: An object that contains the connector configuration. - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create a - case without a connector, specify null. If you want to - omit any individual field, specify null as its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM and - ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: The type of incident for IBM Resilient connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type is - sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and ServiceNow - SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM Resilient - connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for ServiceNow - SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow ITSM - connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can be - delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without a - connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - required: - - fields - - id - - name - - type - description: - description: The description for the case. - type: string - owner: - $ref: '#/components/schemas/owners' - settings: - $ref: '#/components/schemas/settings' - severity: - $ref: '#/components/schemas/severity_property' - tags: - description: >- - The words and phrases that help categorize cases. It can be - an empty array. - type: array - items: - type: string - title: - description: A title for the case. - type: string - required: - - connector - - description - - owner - - settings - - tags - - title - examples: - createCaseRequest: - $ref: '#/components/examples/create_case_request' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - closed_at: - type: string - format: date-time - nullable: true - example: null - closed_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - comments: - type: array - items: - oneOf: - - $ref: >- - #/components/schemas/alert_comment_response_properties - - $ref: >- - #/components/schemas/user_comment_response_properties - example: [] - connector: - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create a - case without a connector, specify null. If you want to - omit any individual field, specify null as its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM - and ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: The type of incident for IBM Resilient connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type - is sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and ServiceNow - SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM - Resilient connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for - ServiceNow SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow - ITSM connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can be - delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without a - connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - created_at: - type: string - format: date-time - example: '2022-05-13T09:16:17.416Z' - created_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - description: - type: string - example: A case description. - duration: - type: integer - description: > - The elapsed time from the creation of the case to its - closure (in seconds). If the case has not been closed, the - duration is set to null. If the case was closed after less - than half a second, the duration is rounded down to zero. - example: 120 - external_service: - $ref: '#/components/schemas/external_service' - id: - type: string - example: 66b9aa00-94fa-11ea-9f74-e7e108796192 - owner: - $ref: '#/components/schemas/owners' - settings: - $ref: '#/components/schemas/settings' - severity: - $ref: '#/components/schemas/severity_property' - status: - $ref: '#/components/schemas/status' - tags: - type: array - items: - type: string - example: - - tag-1 - title: - type: string - example: Case title 1 - totalAlerts: - type: integer - example: 0 - totalComment: - type: integer - example: 0 - updated_at: - type: string - format: date-time - nullable: true - example: null - updated_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - version: - type: string - example: WzUzMiwxXQ== - examples: - createCaseResponse: - $ref: '#/components/examples/create_case_response' - servers: - - url: https://localhost:5601 - delete: - summary: Deletes one or more cases from the default space. - operationId: deleteCaseDefaultSpace - description: > - You must have `read` or `all` privileges and the `delete` sub-feature - privilege for the **Cases** feature in the **Management**, - **Observability**, or **Security** section of the Kibana feature - privileges, depending on the owner of the cases you're deleting. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - name: ids - description: >- - The cases that you want to removed. To retrieve case IDs, use the - find cases API. All non-ASCII characters must be URL encoded. - in: query - required: true - schema: - type: string - example: d4e7abb0-b462-11ec-9a8d-698504725a43 - responses: - '204': - description: Indicates a successful call. - servers: - - url: https://localhost:5601 - patch: - summary: Updates one or more cases in the default space. - operationId: updateCaseDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're updating. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - requestBody: - content: - application/json: - schema: - type: object - properties: - cases: - type: array - items: - type: object - properties: - connector: - description: An object that contains the connector configuration. - type: object - properties: - fields: - description: >- - An object containing the connector fields. To - create a case without a connector, specify null. - If you want to omit any individual field, specify - null as its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow - ITSM and ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: >- - The type of incident for IBM Resilient - connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue - type is sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and - ServiceNow SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow - ITSM connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM - Resilient connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for - ServiceNow SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow - ITSM connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution - can be delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case - without a connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - required: - - fields - - id - - name - - type - description: - description: The description for the case. - type: string - id: - description: The identifier for the case. - type: string - settings: - $ref: '#/components/schemas/settings' - severity: - $ref: '#/components/schemas/severity_property' - status: - $ref: '#/components/schemas/status' - tags: - description: The words and phrases that help categorize cases. - type: array - items: - type: string - title: - description: A title for the case. - type: string - version: - description: The current version of the case. - type: string - required: - - id - - version - examples: - updateCaseRequest: - $ref: '#/components/examples/update_case_request' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - closed_at: - type: string - format: date-time - nullable: true - example: null - closed_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - comments: - type: array - items: - oneOf: - - $ref: >- - #/components/schemas/alert_comment_response_properties - - $ref: >- - #/components/schemas/user_comment_response_properties - example: [] - connector: - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create a - case without a connector, specify null. If you want to - omit any individual field, specify null as its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM - and ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: The type of incident for IBM Resilient connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type - is sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and ServiceNow - SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM - Resilient connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for - ServiceNow SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow - ITSM connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can be - delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without a - connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - created_at: - type: string - format: date-time - example: '2022-05-13T09:16:17.416Z' - created_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - description: - type: string - example: A case description. - duration: - type: integer - description: > - The elapsed time from the creation of the case to its - closure (in seconds). If the case has not been closed, the - duration is set to null. If the case was closed after less - than half a second, the duration is rounded down to zero. - example: 120 - external_service: - $ref: '#/components/schemas/external_service' - id: - type: string - example: 66b9aa00-94fa-11ea-9f74-e7e108796192 - owner: - $ref: '#/components/schemas/owners' - settings: - $ref: '#/components/schemas/settings' - severity: - $ref: '#/components/schemas/severity_property' - status: - $ref: '#/components/schemas/status' - tags: - type: array - items: - type: string - example: - - tag-1 - title: - type: string - example: Case title 1 - totalAlerts: - type: integer - example: 0 - totalComment: - type: integer - example: 0 - updated_at: - type: string - format: date-time - nullable: true - example: null - updated_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - version: - type: string - example: WzUzMiwxXQ== - examples: - updateCaseResponse: - $ref: '#/components/examples/update_case_response' - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/_find: - get: - summary: Retrieves a paginated subset of cases from the default space. - operationId: getCasesDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're seeking. - tags: - - cases - - kibana - parameters: - - name: defaultSearchOperator - in: query - description: The default operator to use for the simple_query_string. - schema: - type: string - default: OR - example: OR - - name: fields - in: query - description: The fields in the entity to return in the response. - schema: - type: array - items: - type: string - - name: from - in: query - description: > - [preview] Returns only cases that were created after a specific - date. The date must be specified as a KQL data range or date match - expression. This functionality is in technical preview and may be - changed or removed in a future release. Elastic will apply best - effort to fix any issues, but features in technical preview are not - subject to the support SLA of official GA features. - schema: - type: string - example: now-1d - x-technical-preview: true - - $ref: '#/components/parameters/owner' - - name: page - in: query - description: The page number to return. - schema: - type: integer - default: 1 - example: 1 - - name: perPage - in: query - description: The number of rules to return per page. - schema: - type: integer - default: 20 - example: 20 - - name: reporters - in: query - description: Filters the returned cases by the user name of the reporter. - schema: - oneOf: - - type: string - - type: array - items: - type: string - example: elastic - - name: search - in: query - description: >- - An Elasticsearch simple_query_string query that filters the objects - in the response. - schema: - type: string - - name: searchFields - in: query - description: The fields to perform the simple_query_string parsed query against. - schema: - oneOf: - - type: string - - type: array - items: - type: string - - $ref: '#/components/parameters/severity' - - name: sortField - in: query - description: Determines which field is used to sort the results. - schema: - type: string - enum: - - createdAt - - updatedAt - default: createdAt - example: updatedAt - - name: sortOrder - in: query - description: Determines the sort order. - schema: - type: string - enum: - - asc - - desc - default: desc - example: asc - - in: query - name: status - description: Filters the returned cases by state. - schema: - type: string - enum: - - closed - - in-progress - - open - example: open - - name: tags - in: query - description: Filters the returned cases by tags. - schema: - oneOf: - - type: string - - type: array - items: - type: string - example: tag-1 - - name: to - in: query - description: >- - Returns only cases that were created before a specific date. The - date must be specified as a KQL data range or date match expression. - schema: - type: string - example: now%2B1d - x-technical-preview: true - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - cases: - type: array - items: - type: object - properties: - closed_at: - type: string - format: date-time - nullable: true - example: null - closed_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - comments: - type: array - items: - oneOf: - - $ref: >- - #/components/schemas/alert_comment_response_properties - - $ref: >- - #/components/schemas/user_comment_response_properties - example: [] - connector: - type: object - properties: - fields: - description: >- - An object containing the connector fields. To - create a case without a connector, specify null. - If you want to omit any individual field, - specify null as its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow - ITSM and ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs - for ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: >- - The type of incident for IBM Resilient - connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue - type is sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and - ServiceNow SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow - ITSM connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM - Resilient connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for - ServiceNow SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for - ServiceNow ITSM connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution - can be delayed for ServiceNow ITSM - connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a - case without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case - without a connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - created_at: - type: string - format: date-time - example: '2022-05-13T09:16:17.416Z' - created_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - description: - type: string - example: A case description. - duration: - type: integer - description: > - The elapsed time from the creation of the case to - its closure (in seconds). If the case has not been - closed, the duration is set to null. If the case was - closed after less than half a second, the duration - is rounded down to zero. - example: 120 - external_service: - $ref: '#/components/schemas/external_service' - id: - type: string - example: 66b9aa00-94fa-11ea-9f74-e7e108796192 - owner: - $ref: '#/components/schemas/owners' - settings: - $ref: '#/components/schemas/settings' - severity: - $ref: '#/components/schemas/severity_property' - status: - $ref: '#/components/schemas/status' - tags: - type: array - items: - type: string - example: - - tag-1 - title: - type: string - example: Case title 1 - totalAlerts: - type: integer - example: 0 - totalComment: - type: integer - example: 0 - updated_at: - type: string - format: date-time - nullable: true - example: null - updated_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - version: - type: string - example: WzUzMiwxXQ== - count_closed_cases: - type: integer - count_in_progress_cases: - type: integer - count_open_cases: - type: integer - page: - type: integer - per_page: - type: integer - total: - type: integer - examples: - findCaseResponse: - $ref: '#/components/examples/find_case_response' - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/alerts/{alertId}: - get: - summary: Returns the cases associated with a specific alert in the default space. - operationId: getCasesByAlertDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're seeking. - x-technical-preview: true - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/alert_id' - - $ref: '#/components/parameters/owner' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - id: - type: string - description: The case identifier. - title: - type: string - description: The case title. - example: - - id: 06116b80-e1c3-11ec-be9b-9b1838238ee6 - title: security_case - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/configure: - get: - summary: >- - Retrieves external connection details, such as the closure type and - default connector for cases in the default space. - operationId: getCaseConfigurationDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case configuration. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/owner' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - closure_type: - $ref: '#/components/schemas/closure_types' - connector: - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create - a case without a connector, specify null. If you - want to omit any individual field, specify null as - its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM - and ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: >- - The type of incident for IBM Resilient - connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type - is sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and - ServiceNow SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM - Resilient connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for - ServiceNow SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow - ITSM connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can - be delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without - a connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - created_at: - type: string - format: date-time - example: '2022-06-01T17:07:17.767Z' - created_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - error: - type: string - example: null - id: - type: string - example: 4a97a440-e1cd-11ec-be9b-9b1838238ee6 - mappings: - type: array - items: - type: object - properties: - action_type: - type: string - example: overwrite - source: - type: string - example: title - target: - type: string - example: summary - owner: - $ref: '#/components/schemas/owners' - updated_at: - type: string - format: date-time - nullable: true - example: '2022-06-01T19:58:48.169Z' - updated_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - nullable: true - version: - type: string - example: WzIwNzMsMV0= - servers: - - url: https://localhost:5601 - post: - summary: >- - Sets external connection details, such as the closure type and default - connector for cases in the default space. - operationId: setCaseConfigurationDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case configuration. - Connectors are used to interface with external systems. You must create - a connector before you can use it in your cases. Refer to the add - connectors API. If you set a default connector, it is automatically - selected when you create cases in Kibana. If you use the create case - API, however, you must still specify all of the connector details. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - requestBody: - content: - application/json: - schema: - type: object - properties: - closure_type: - $ref: '#/components/schemas/closure_types' - connector: - description: An object that contains the connector configuration. - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create a - case without a connector, specify null. If you want to - omit any individual field, specify null as its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM and - ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: The type of incident for IBM Resilient connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type is - sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and ServiceNow - SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM Resilient - connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for ServiceNow - SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow ITSM - connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can be - delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without a - connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - required: - - fields - - id - - name - - type - owner: - $ref: '#/components/schemas/owners' - settings: - description: An object that contains the case settings. - type: object - properties: - syncAlerts: - description: Turns alert syncing on or off. - type: boolean - example: true - required: - - syncAlerts - required: - - closure_type - - connector - - owner - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - closure_type: - $ref: '#/components/schemas/closure_types' - connector: - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create - a case without a connector, specify null. If you - want to omit any individual field, specify null as - its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM - and ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: >- - The type of incident for IBM Resilient - connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type - is sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and - ServiceNow SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM - Resilient connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for - ServiceNow SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow - ITSM connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can - be delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without - a connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - created_at: - type: string - format: date-time - example: '2022-06-01T17:07:17.767Z' - created_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - error: - type: string - example: null - id: - type: string - example: 4a97a440-e1cd-11ec-be9b-9b1838238ee6 - mappings: - type: array - items: - type: object - properties: - action_type: - type: string - example: overwrite - source: - type: string - example: title - target: - type: string - example: summary - owner: - $ref: '#/components/schemas/owners' - updated_at: - type: string - format: date-time - nullable: true - example: '2022-06-01T19:58:48.169Z' - updated_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - nullable: true - version: - type: string - example: WzIwNzMsMV0= - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/configure/{configurationId}: - patch: - summary: >- - Updates external connection details, such as the closure type and - default connector for cases in the default space. - operationId: updateCaseConfigurationDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case configuration. - Connectors are used to interface with external systems. You must create - a connector before you can use it in your cases. Refer to the add - connectors API. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - $ref: '#/components/parameters/configuration_id' - requestBody: - content: - application/json: - schema: - type: object - properties: - closure_type: - $ref: '#/components/schemas/closure_types' - connector: - description: An object that contains the connector configuration. - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create a - case without a connector, specify null. If you want to - omit any individual field, specify null as its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM and - ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: The type of incident for IBM Resilient connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type is - sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and ServiceNow - SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM Resilient - connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for ServiceNow - SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow ITSM - connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can be - delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without a - connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - required: - - fields - - id - - name - - type - version: - description: > - The version of the connector. To retrieve the version value, - use the get configuration API. - type: string - example: WzIwMiwxXQ== - required: - - version - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - closure_type: - $ref: '#/components/schemas/closure_types' - connector: - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create - a case without a connector, specify null. If you - want to omit any individual field, specify null as - its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM - and ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: >- - The type of incident for IBM Resilient - connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type - is sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and - ServiceNow SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM - Resilient connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for - ServiceNow SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow - ITSM connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can - be delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without - a connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - created_at: - type: string - format: date-time - example: '2022-06-01T17:07:17.767Z' - created_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - error: - type: string - example: null - id: - type: string - example: 4a97a440-e1cd-11ec-be9b-9b1838238ee6 - mappings: - type: array - items: - type: object - properties: - action_type: - type: string - example: overwrite - source: - type: string - example: title - target: - type: string - example: summary - owner: - $ref: '#/components/schemas/owners' - updated_at: - type: string - format: date-time - nullable: true - example: '2022-06-01T19:58:48.169Z' - updated_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - nullable: true - version: - type: string - example: WzIwNzMsMV0= - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/configure/connectors/_find: - get: - summary: Retrieves information about connectors for cases in the default space. - operationId: getCaseConnectorsDefaultSpace - description: > - In particular, only the connectors that are supported for use in cases - are returned. You must have `read` privileges for the **Actions and - Connectors** feature in the **Management** section of the Kibana feature - privileges. - tags: - - cases - - kibana - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - actionTypeId: - $ref: '#/components/schemas/connector_types' - config: - type: object - properties: - apiUrl: - type: string - projectKey: - type: string - additionalProperties: true - id: - type: string - isDeprecated: - type: boolean - isMissingSecrets: - type: boolean - isPreconfigured: - type: boolean - name: - type: string - referencedByCount: - type: integer - examples: - findCaseResponse: - $ref: '#/components/examples/find_connector_response' - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/reporters: - get: - summary: >- - Returns information about the users who opened cases in the default - space. - operationId: getCaseReportersDefaultSpace - description: > - You must have read privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases. The API returns - information about the users as they existed at the time of the case - creation, including their name, full name, and email address. If any of - those details change thereafter or if a user is deleted, the information - returned by this API is unchanged. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/owner' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - examples: - getReportersResponse: - $ref: '#/components/examples/get_reporters_response' - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/status: - get: - summary: Returns the number of cases that are open, closed, and in progress. - operationId: getCaseStatusDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're seeking. - tags: - - cases - - kibana - deprecated: true - parameters: - - $ref: '#/components/parameters/owner' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - count_closed_cases: - type: integer - count_in_progress_cases: - type: integer - count_open_cases: - type: integer - examples: - getStatusResponse: - $ref: '#/components/examples/get_status_response' - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/tags: - get: - summary: Aggregates and returns a list of case tags in the default space. - operationId: getCaseTagsDefaultSpace - description: > - You must have read privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're seeking. - tags: - - cases - - kibana - parameters: - - in: query - name: owner - description: >- - A filter to limit the retrieved case statistics to a specific set of - applications. If this parameter is omitted, the response contains - tags from all cases that the user has access to read. - schema: - oneOf: - - $ref: '#/components/schemas/owners' - - type: array - items: - $ref: '#/components/schemas/owners' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: string - examples: - getTagsResponse: - $ref: '#/components/examples/get_tags_response' - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/{caseId}: - get: - summary: Retrieves information about a case in the default space. - operationId: getCaseDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're seeking. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/case_id' - - in: query - name: includeComments - description: Determines whether case comments are returned. - deprecated: true - schema: - type: boolean - default: true - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - closed_at: - type: string - format: date-time - nullable: true - example: null - closed_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - comments: - type: array - items: - oneOf: - - $ref: >- - #/components/schemas/alert_comment_response_properties - - $ref: >- - #/components/schemas/user_comment_response_properties - example: [] - connector: - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create a - case without a connector, specify null. If you want to - omit any individual field, specify null as its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM - and ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: The type of incident for IBM Resilient connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type - is sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and ServiceNow - SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM - Resilient connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for - ServiceNow SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow - ITSM connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can be - delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without a - connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - created_at: - type: string - format: date-time - example: '2022-05-13T09:16:17.416Z' - created_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - description: - type: string - example: A case description. - duration: - type: integer - description: > - The elapsed time from the creation of the case to its - closure (in seconds). If the case has not been closed, the - duration is set to null. If the case was closed after less - than half a second, the duration is rounded down to zero. - example: 120 - external_service: - $ref: '#/components/schemas/external_service' - id: - type: string - example: 66b9aa00-94fa-11ea-9f74-e7e108796192 - owner: - $ref: '#/components/schemas/owners' - settings: - $ref: '#/components/schemas/settings' - severity: - $ref: '#/components/schemas/severity_property' - status: - $ref: '#/components/schemas/status' - tags: - type: array - items: - type: string - example: - - tag-1 - title: - type: string - example: Case title 1 - totalAlerts: - type: integer - example: 0 - totalComment: - type: integer - example: 0 - updated_at: - type: string - format: date-time - nullable: true - example: null - updated_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - version: - type: string - example: WzUzMiwxXQ== - examples: - getCaseResponse: - $ref: '#/components/examples/get_case_response' - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/{caseId}/alerts: - get: - summary: Gets all alerts attached to a case in the default space. - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're seeking. - operationId: getCaseAlertsDefaultSpace - tags: - - cases - - kibana - x-technical-preview: true - parameters: - - $ref: '#/components/parameters/case_id' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - $ref: '#/components/schemas/alert_response_properties' - examples: - createCaseCommentResponse: - $ref: '#/components/examples/get_case_alerts_response' - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/{caseId}/comments: - post: - summary: Adds a comment or alert to a case in the default space. - operationId: addCaseCommentDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're creating. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - $ref: '#/components/parameters/case_id' - requestBody: - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/add_alert_comment_request_properties' - - $ref: '#/components/schemas/add_user_comment_request_properties' - examples: - createCaseCommentRequest: - $ref: '#/components/examples/add_comment_request' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - closed_at: - type: string - format: date-time - nullable: true - example: null - closed_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - comments: - type: array - items: - oneOf: - - $ref: >- - #/components/schemas/alert_comment_response_properties - - $ref: >- - #/components/schemas/user_comment_response_properties - example: [] - connector: - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create a - case without a connector, specify null. If you want to - omit any individual field, specify null as its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM - and ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: The type of incident for IBM Resilient connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type - is sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and ServiceNow - SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM - Resilient connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for - ServiceNow SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow - ITSM connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can be - delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without a - connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - created_at: - type: string - format: date-time - example: '2022-05-13T09:16:17.416Z' - created_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - description: - type: string - example: A case description. - duration: - type: integer - description: > - The elapsed time from the creation of the case to its - closure (in seconds). If the case has not been closed, the - duration is set to null. If the case was closed after less - than half a second, the duration is rounded down to zero. - example: 120 - external_service: - $ref: '#/components/schemas/external_service' - id: - type: string - example: 66b9aa00-94fa-11ea-9f74-e7e108796192 - owner: - $ref: '#/components/schemas/owners' - settings: - $ref: '#/components/schemas/settings' - severity: - $ref: '#/components/schemas/severity_property' - status: - $ref: '#/components/schemas/status' - tags: - type: array - items: - type: string - example: - - tag-1 - title: - type: string - example: Case title 1 - totalAlerts: - type: integer - example: 0 - totalComment: - type: integer - example: 0 - updated_at: - type: string - format: date-time - nullable: true - example: null - updated_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - version: - type: string - example: WzUzMiwxXQ== - examples: - createCaseCommentResponse: - $ref: '#/components/examples/add_comment_response' - servers: - - url: https://localhost:5601 - delete: - summary: Deletes all comments and alerts from a case in the default space. - operationId: deleteCaseCommentsDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're deleting. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - $ref: '#/components/parameters/case_id' - responses: - '204': - description: Indicates a successful call. - servers: - - url: https://localhost:5601 - patch: - summary: Updates a comment or alert in a case in the default space. - operationId: updateCaseCommentDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're updating. - NOTE: You cannot change the comment type or the owner of a comment. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - $ref: '#/components/parameters/case_id' - requestBody: - content: - application/json: - schema: - oneOf: - - $ref: '#/components/schemas/update_alert_comment_request_properties' - - $ref: '#/components/schemas/update_user_comment_request_properties' - examples: - updateCaseCommentRequest: - $ref: '#/components/examples/update_comment_request' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - closed_at: - type: string - format: date-time - nullable: true - example: null - closed_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - comments: - type: array - items: - oneOf: - - $ref: >- - #/components/schemas/alert_comment_response_properties - - $ref: >- - #/components/schemas/user_comment_response_properties - example: [] - connector: - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create a - case without a connector, specify null. If you want to - omit any individual field, specify null as its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM - and ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: The type of incident for IBM Resilient connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type - is sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and ServiceNow - SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM - Resilient connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for - ServiceNow SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow - ITSM connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can be - delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without a - connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - created_at: - type: string - format: date-time - example: '2022-05-13T09:16:17.416Z' - created_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - description: - type: string - example: A case description. - duration: - type: integer - description: > - The elapsed time from the creation of the case to its - closure (in seconds). If the case has not been closed, the - duration is set to null. If the case was closed after less - than half a second, the duration is rounded down to zero. - example: 120 - external_service: - $ref: '#/components/schemas/external_service' - id: - type: string - example: 66b9aa00-94fa-11ea-9f74-e7e108796192 - owner: - $ref: '#/components/schemas/owners' - settings: - $ref: '#/components/schemas/settings' - severity: - $ref: '#/components/schemas/severity_property' - status: - $ref: '#/components/schemas/status' - tags: - type: array - items: - type: string - example: - - tag-1 - title: - type: string - example: Case title 1 - totalAlerts: - type: integer - example: 0 - totalComment: - type: integer - example: 0 - updated_at: - type: string - format: date-time - nullable: true - example: null - updated_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - version: - type: string - example: WzUzMiwxXQ== - examples: - updateCaseCommentResponse: - $ref: '#/components/examples/update_comment_response' - servers: - - url: https://localhost:5601 - get: - summary: Retrieves all the comments from a case in the default space. - operationId: getAllCaseCommentsDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases with the - comments you're seeking. - tags: - - cases - - kibana - deprecated: true - parameters: - - $ref: '#/components/parameters/case_id' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - anyOf: - - $ref: '#/components/schemas/alert_comment_response_properties' - - $ref: '#/components/schemas/user_comment_response_properties' - examples: {} - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/{caseId}/comments/{commentId}: - delete: - summary: Deletes a comment or alert from a case in the default space. - operationId: deleteCaseCommentDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're deleting. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - $ref: '#/components/parameters/case_id' - - $ref: '#/components/parameters/comment_id' - responses: - '204': - description: Indicates a successful call. - servers: - - url: https://localhost:5601 - get: - summary: Retrieves a comment from a case in the default space. - operationId: getCaseCommentDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases with the - comments you're seeking. - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/case_id' - - $ref: '#/components/parameters/comment_id' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - oneOf: - - $ref: '#/components/schemas/alert_comment_response_properties' - - $ref: '#/components/schemas/user_comment_response_properties' - examples: - getCaseCommentResponse: - $ref: '#/components/examples/get_comment_response' - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/{caseId}/connector/{connectorId}/_push: - post: - summary: Pushes a case to an external service. - description: > - You must have `all` privileges for the **Actions and Connectors** - feature in the **Management** section of the Kibana feature privileges. - You must also have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're pushing. - operationId: pushCaseDefaultSpace - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/case_id' - - $ref: '#/components/parameters/connector_id' - - $ref: '#/components/parameters/kbn_xsrf' - requestBody: - content: - application/json: {} - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - closed_at: - type: string - format: date-time - nullable: true - example: null - closed_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - comments: - type: array - items: - oneOf: - - $ref: >- - #/components/schemas/alert_comment_response_properties - - $ref: >- - #/components/schemas/user_comment_response_properties - example: [] - connector: - type: object - properties: - fields: - description: >- - An object containing the connector fields. To create a - case without a connector, specify null. If you want to - omit any individual field, specify null as its value. - nullable: true - type: object - properties: - caseId: - description: The case identifier for Swimlane connectors. - type: string - category: - description: >- - The category of the incident for ServiceNow ITSM - and ServiceNow SecOps connectors. - type: string - destIp: - description: >- - A comma-separated list of destination IPs for - ServiceNow SecOps connectors. - type: string - impact: - description: >- - The effect an incident had on business for - ServiceNow ITSM connectors. - type: string - issueType: - description: The type of issue for Jira connectors. - type: string - issueTypes: - description: The type of incident for IBM Resilient connectors. - type: array - items: - type: number - malwareHash: - description: >- - A comma-separated list of malware hashes for - ServiceNow SecOps connectors. - type: string - malwareUrl: - description: >- - A comma-separated list of malware URLs for - ServiceNow SecOps connectors. - type: string - parent: - description: >- - The key of the parent issue, when the issue type - is sub-task for Jira connectors. - type: string - priority: - description: >- - The priority of the issue for Jira and ServiceNow - SecOps connectors. - type: string - severity: - description: >- - The severity of the incident for ServiceNow ITSM - connectors. - type: string - severityCode: - description: >- - The severity code of the incident for IBM - Resilient connectors. - type: number - sourceIp: - description: >- - A comma-separated list of source IPs for - ServiceNow SecOps connectors. - type: string - subcategory: - description: >- - The subcategory of the incident for ServiceNow - ITSM connectors. - type: string - urgency: - description: >- - The extent to which the incident resolution can be - delayed for ServiceNow ITSM connectors. - type: string - example: null - id: - description: >- - The identifier for the connector. To create a case - without a connector, use `none`. - type: string - example: none - name: - description: >- - The name of the connector. To create a case without a - connector, use `none`. - type: string - example: none - type: - $ref: '#/components/schemas/connector_types' - created_at: - type: string - format: date-time - example: '2022-05-13T09:16:17.416Z' - created_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - description: - type: string - example: A case description. - duration: - type: integer - description: > - The elapsed time from the creation of the case to its - closure (in seconds). If the case has not been closed, the - duration is set to null. If the case was closed after less - than half a second, the duration is rounded down to zero. - example: 120 - external_service: - $ref: '#/components/schemas/external_service' - id: - type: string - example: 66b9aa00-94fa-11ea-9f74-e7e108796192 - owner: - $ref: '#/components/schemas/owners' - settings: - $ref: '#/components/schemas/settings' - severity: - $ref: '#/components/schemas/severity_property' - status: - $ref: '#/components/schemas/status' - tags: - type: array - items: - type: string - example: - - tag-1 - title: - type: string - example: Case title 1 - totalAlerts: - type: integer - example: 0 - totalComment: - type: integer - example: 0 - updated_at: - type: string - format: date-time - nullable: true - example: null - updated_by: - type: object - properties: - email: - type: string - example: null - full_name: - type: string - example: null - username: - type: string - example: elastic - profile_uid: - type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true - example: null - version: - type: string - example: WzUzMiwxXQ== - examples: - pushCaseResponse: - $ref: '#/components/examples/push_case_response' - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 - /api/cases/{caseId}/user_actions: - get: - summary: Returns all user activity for a case in the default space. - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're seeking. - deprecated: true - operationId: getCaseActivityDefaultSpace - tags: - - cases - - kibana - parameters: - - $ref: '#/components/parameters/case_id' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - $ref: '#/components/schemas/user_actions_response_properties' - examples: - getCaseActivityResponse: - $ref: '#/components/examples/get_case_activity_response' - servers: - - url: https://localhost:5601 - servers: - - url: https://localhost:5601 /s/{spaceId}/api/cases: post: summary: Creates a case. @@ -3372,7 +28,6 @@ paths: creating. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/kbn_xsrf' - $ref: '#/components/parameters/space_id' @@ -3748,7 +403,6 @@ paths: privileges, depending on the owner of the cases you're deleting. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/kbn_xsrf' - $ref: '#/components/parameters/space_id' @@ -3776,7 +430,6 @@ paths: updating. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/kbn_xsrf' - $ref: '#/components/parameters/space_id' @@ -4162,7 +815,6 @@ paths: feature privileges, depending on the owner of the cases you're seeking. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/space_id' - name: defaultSearchOperator @@ -4544,7 +1196,6 @@ paths: x-technical-preview: true tags: - cases - - kibana parameters: - $ref: '#/components/parameters/alert_id' - $ref: '#/components/parameters/space_id' @@ -4584,7 +1235,6 @@ paths: feature privileges, depending on the owner of the case configuration. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/space_id' - $ref: '#/components/parameters/owner' @@ -4777,7 +1427,6 @@ paths: API, however, you must still specify all of the connector details. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/kbn_xsrf' - $ref: '#/components/parameters/space_id' @@ -5098,7 +1747,6 @@ paths: connectors API. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/kbn_xsrf' - $ref: '#/components/parameters/configuration_id' @@ -5408,7 +2056,6 @@ paths: privileges. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/space_id' responses: @@ -5464,7 +2111,6 @@ paths: returned by this API is unchanged. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/space_id' - $ref: '#/components/parameters/owner' @@ -5508,7 +2154,6 @@ paths: deprecated: true tags: - cases - - kibana parameters: - $ref: '#/components/parameters/space_id' - $ref: '#/components/parameters/owner' @@ -5543,7 +2188,6 @@ paths: feature privileges, depending on the owner of the cases you're seeking. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/space_id' - in: query @@ -5584,7 +2228,6 @@ paths: feature privileges, depending on the owner of the case you're seeking. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/case_id' - $ref: '#/components/parameters/space_id' @@ -5832,7 +2475,6 @@ paths: operationId: getCaseAlerts tags: - cases - - kibana parameters: - $ref: '#/components/parameters/case_id' - $ref: '#/components/parameters/space_id' @@ -5862,7 +2504,6 @@ paths: feature privileges, depending on the owner of the case you're creating. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/kbn_xsrf' - $ref: '#/components/parameters/case_id' @@ -6110,7 +2751,6 @@ paths: feature privileges, depending on the owner of the cases you're deleting. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/kbn_xsrf' - $ref: '#/components/parameters/case_id' @@ -6130,7 +2770,6 @@ paths: NOTE: You cannot change the comment type or the owner of a comment. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/kbn_xsrf' - $ref: '#/components/parameters/case_id' @@ -6380,7 +3019,6 @@ paths: deprecated: true tags: - cases - - kibana parameters: - $ref: '#/components/parameters/case_id' - $ref: '#/components/parameters/space_id' @@ -6410,7 +3048,6 @@ paths: feature privileges, depending on the owner of the cases you're deleting. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/kbn_xsrf' - $ref: '#/components/parameters/case_id' @@ -6431,7 +3068,6 @@ paths: comments you're seeking. tags: - cases - - kibana parameters: - $ref: '#/components/parameters/case_id' - $ref: '#/components/parameters/comment_id' @@ -6464,7 +3100,6 @@ paths: operationId: pushCase tags: - cases - - kibana parameters: - $ref: '#/components/parameters/case_id' - $ref: '#/components/parameters/connector_id' @@ -6710,7 +3345,6 @@ paths: operationId: getCaseActivity tags: - cases - - kibana parameters: - $ref: '#/components/parameters/case_id' - $ref: '#/components/parameters/space_id' @@ -6746,6 +3380,16 @@ components: in: header name: kbn-xsrf required: true + space_id: + in: path + name: spaceId + description: >- + An identifier for the space. If `/s/` and the identifier are omitted + from the path, the default space is used. + required: true + schema: + type: string + example: default owner: in: query name: owner @@ -6817,14 +3461,6 @@ components: schema: type: string example: abed3a70-71bd-11ea-a0b2-c51ea50a58e2 - space_id: - in: path - name: spaceId - description: An identifier for the space. - required: true - schema: - type: string - example: default schemas: connector_types: type: string diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/space_id.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/space_id.yaml index 0ff325b08a082..0a9fba457e3e7 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/space_id.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/space_id.yaml @@ -1,6 +1,6 @@ in: path name: spaceId -description: An identifier for the space. +description: An identifier for the space. If `/s/` and the identifier are omitted from the path, the default space is used. required: true schema: type: string diff --git a/x-pack/plugins/cases/docs/openapi/entrypoint.yaml b/x-pack/plugins/cases/docs/openapi/entrypoint.yaml index 3866c4fe4edcb..6995d1482e0a9 100644 --- a/x-pack/plugins/cases/docs/openapi/entrypoint.yaml +++ b/x-pack/plugins/cases/docs/openapi/entrypoint.yaml @@ -17,37 +17,6 @@ servers: - url: 'http://localhost:5601' description: local paths: - /api/cases: - $ref: paths/api@cases.yaml - /api/cases/_find: - $ref: paths/api@cases@_find.yaml - '/api/cases/alerts/{alertId}': - $ref: 'paths/api@cases@alerts@{alertid}.yaml' - '/api/cases/configure': - $ref: paths/api@cases@configure.yaml - '/api/cases/configure/{configurationId}': - $ref: paths/api@cases@configure@{configurationid}.yaml - '/api/cases/configure/connectors/_find': - $ref: paths/api@cases@configure@connectors@_find.yaml - '/api/cases/reporters': - $ref: 'paths/api@cases@reporters.yaml' - '/api/cases/status': - $ref: 'paths/api@cases@status.yaml' - '/api/cases/tags': - $ref: 'paths/api@cases@tags.yaml' - '/api/cases/{caseId}': - $ref: 'paths/api@cases@{caseid}.yaml' - '/api/cases/{caseId}/alerts': - $ref: 'paths/api@cases@{caseid}@alerts.yaml' - '/api/cases/{caseId}/comments': - $ref: 'paths/api@cases@{caseid}@comments.yaml' - '/api/cases/{caseId}/comments/{commentId}': - $ref: 'paths/api@cases@{caseid}@comments@{commentid}.yaml' - '/api/cases/{caseId}/connector/{connectorId}/_push': - $ref: 'paths/api@cases@{caseid}@connector@{connectorid}@_push.yaml' - '/api/cases/{caseId}/user_actions': - $ref: 'paths/api@cases@{caseid}@user_actions.yaml' - '/s/{spaceId}/api/cases': $ref: 'paths/s@{spaceid}@api@cases.yaml' '/s/{spaceId}/api/cases/_find': diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases.yaml deleted file mode 100644 index 96a9c473557c5..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases.yaml +++ /dev/null @@ -1,175 +0,0 @@ -post: - summary: Creates a case in the default space. - operationId: createCaseDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're creating. - tags: - - cases - - kibana - parameters: - - $ref: ../components/headers/kbn_xsrf.yaml - requestBody: - content: - application/json: - schema: - type: object - properties: - connector: - description: An object that contains the connector configuration. - type: object - properties: - $ref: '../components/schemas/connector_properties.yaml' - required: - - fields - - id - - name - - type - description: - description: The description for the case. - type: string - owner: - $ref: '../components/schemas/owners.yaml' - settings: - $ref: '../components/schemas/settings.yaml' - severity: - $ref: '../components/schemas/severity_property.yaml' - tags: - description: The words and phrases that help categorize cases. It can be an empty array. - type: array - items: - type: string - title: - description: A title for the case. - type: string - required: - - connector - - description - - owner - - settings - - tags - - title - examples: - createCaseRequest: - $ref: '../components/examples/create_case_request.yaml' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - $ref: '../components/schemas/case_response_properties.yaml' - examples: - createCaseResponse: - $ref: '../components/examples/create_case_response.yaml' - servers: - - url: https://localhost:5601 - -delete: - summary: Deletes one or more cases from the default space. - operationId: deleteCaseDefaultSpace - description: > - You must have `read` or `all` privileges and the `delete` sub-feature - privilege for the **Cases** feature in the **Management**, **Observability**, - or **Security** section of the Kibana feature privileges, depending on the - owner of the cases you're deleting. - tags: - - cases - - kibana - parameters: - - $ref: ../components/headers/kbn_xsrf.yaml - - name: ids - description: The cases that you want to removed. To retrieve case IDs, use the find cases API. All non-ASCII characters must be URL encoded. - in: query - required: true - schema: - type: string - example: d4e7abb0-b462-11ec-9a8d-698504725a43 - responses: - '204': - description: Indicates a successful call. - servers: - - url: https://localhost:5601 - -patch: - summary: Updates one or more cases in the default space. - operationId: updateCaseDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're updating. - tags: - - cases - - kibana - parameters: - - $ref: ../components/headers/kbn_xsrf.yaml - requestBody: - content: - application/json: - schema: - type: object - properties: - cases: - type: array - items: - type: object - properties: - connector: - description: An object that contains the connector configuration. - type: object - properties: - $ref: '../components/schemas/connector_properties.yaml' - required: - - fields - - id - - name - - type - description: - description: The description for the case. - type: string - id: - description: The identifier for the case. - type: string - settings: - $ref: '../components/schemas/settings.yaml' - severity: - $ref: '../components/schemas/severity_property.yaml' - status: - $ref: '../components/schemas/status.yaml' - tags: - description: The words and phrases that help categorize cases. - type: array - items: - type: string - title: - description: A title for the case. - type: string - version: - description: The current version of the case. - type: string - required: - - id - - version - examples: - updateCaseRequest: - $ref: '../components/examples/update_case_request.yaml' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - $ref: '../components/schemas/case_response_properties.yaml' - examples: - updateCaseResponse: - $ref: '../components/examples/update_case_response.yaml' - servers: - - url: https://localhost:5601 - -servers: - - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@_find.yaml deleted file mode 100644 index 266e00101aad5..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@_find.yaml +++ /dev/null @@ -1,158 +0,0 @@ -get: - summary: Retrieves a paginated subset of cases from the default space. - operationId: getCasesDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're seeking. - tags: - - cases - - kibana - parameters: - - name: defaultSearchOperator - in: query - description: The default operator to use for the simple_query_string. - schema: - type: string - default: OR - example: OR - - name: fields - in: query - description: The fields in the entity to return in the response. - schema: - type: array - items: - type: string - - name: from - in: query - description: > - [preview] Returns only cases that were created after a specific date. - The date must be specified as a KQL data range or date match expression. - This functionality is in technical preview and may be changed or removed - in a future release. Elastic will apply best effort to fix any issues, - but features in technical preview are not subject to the support SLA of - official GA features. - schema: - type: string - example: now-1d - x-technical-preview: true - - $ref: '../components/parameters/owner.yaml' - - name: page - in: query - description: The page number to return. - schema: - type: integer - default: 1 - example: 1 - - name: perPage - in: query - description: The number of rules to return per page. - schema: - type: integer - default: 20 - example: 20 - - name: reporters - in: query - description: Filters the returned cases by the user name of the reporter. - schema: - oneOf: - - type: string - - type: array - items: - type: string - example: elastic - - name: search - in: query - description: An Elasticsearch simple_query_string query that filters the objects in the response. - schema: - type: string - - name: searchFields - in: query - description: The fields to perform the simple_query_string parsed query against. - schema: - oneOf: - - type: string - - type: array - items: - type: string - - $ref: '../components/parameters/severity.yaml' - - name: sortField - in: query - description: Determines which field is used to sort the results. - schema: - type: string - enum: - - createdAt - - updatedAt - default: createdAt - example: updatedAt - - name: sortOrder - in: query - description: Determines the sort order. - schema: - type: string - enum: - - asc - - desc - default: desc - example: asc - - in: query - name: status - description: Filters the returned cases by state. - schema: - type: string - enum: - - closed - - in-progress - - open - example: open - - name: tags - in: query - description: Filters the returned cases by tags. - schema: - oneOf: - - type: string - - type: array - items: - type: string - example: tag-1 - - name: to - in: query - description: Returns only cases that were created before a specific date. The date must be specified as a KQL data range or date match expression. - schema: - type: string - example: now%2B1d - x-technical-preview: true - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - cases: - type: array - items: - type: object - properties: - $ref: '../components/schemas/case_response_properties.yaml' - count_closed_cases: - type: integer - count_in_progress_cases: - type: integer - count_open_cases: - type: integer - page: - type: integer - per_page: - type: integer - total: - type: integer - examples: - findCaseResponse: - $ref: '../components/examples/find_case_response.yaml' - servers: - - url: https://localhost:5601 -servers: - - url: https://localhost:5601 diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@alerts@{alertid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@alerts@{alertid}.yaml deleted file mode 100644 index e020ae577cd96..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@alerts@{alertid}.yaml +++ /dev/null @@ -1,37 +0,0 @@ -get: - summary: Returns the cases associated with a specific alert in the default space. - operationId: getCasesByAlertDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're seeking. - x-technical-preview: true - tags: - - cases - - kibana - parameters: - - $ref: ../components/parameters/alert_id.yaml - - $ref: '../components/parameters/owner.yaml' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - id: - type: string - description: The case identifier. - title: - type: string - description: The case title. - example: - - id: 06116b80-e1c3-11ec-be9b-9b1838238ee6 - title: security_case - servers: - - url: https://localhost:5601 -servers: - - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@configure.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@configure.yaml deleted file mode 100644 index 527f67b3cbf22..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@configure.yaml +++ /dev/null @@ -1,93 +0,0 @@ -get: - summary: Retrieves external connection details, such as the closure type and default connector for cases in the default space. - operationId: getCaseConfigurationDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case configuration. - tags: - - cases - - kibana - parameters: - - $ref: '../components/parameters/owner.yaml' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - $ref: '../components/schemas/case_configure_response_properties.yaml' - servers: - - url: https://localhost:5601 - -post: - summary: Sets external connection details, such as the closure type and default connector for cases in the default space. - operationId: setCaseConfigurationDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case configuration. - Connectors are used to interface with external systems. You must create a - connector before you can use it in your cases. Refer to the add connectors - API. If you set a default connector, it is automatically selected when you - create cases in Kibana. If you use the create case API, however, you must - still specify all of the connector details. - tags: - - cases - - kibana - parameters: - - $ref: ../components/headers/kbn_xsrf.yaml - requestBody: - content: - application/json: - schema: - type: object - properties: - closure_type: - $ref: '../components/schemas/closure_types.yaml' - connector: - description: An object that contains the connector configuration. - type: object - properties: - $ref: '../components/schemas/connector_properties.yaml' - required: - - fields - - id - - name - - type - owner: - $ref: '../components/schemas/owners.yaml' - settings: - description: An object that contains the case settings. - type: object - properties: - syncAlerts: - description: Turns alert syncing on or off. - type: boolean - example: true - required: - - syncAlerts - required: - - closure_type - - connector - - owner - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - $ref: '../components/schemas/case_configure_response_properties.yaml' - servers: - - url: https://localhost:5601 - -servers: - - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@configure@connectors@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@configure@connectors@_find.yaml deleted file mode 100644 index 8e6bddd6c681d..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@configure@connectors@_find.yaml +++ /dev/null @@ -1,28 +0,0 @@ -get: - summary: Retrieves information about connectors for cases in the default space. - operationId: getCaseConnectorsDefaultSpace - description: > - In particular, only the connectors that are supported for use in cases are - returned. You must have `read` privileges for the **Actions and Connectors** - feature in the **Management** section of the Kibana feature privileges. - tags: - - cases - - kibana - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - $ref: '../components/schemas/connector_response_properties.yaml' - examples: - findCaseResponse: - $ref: '../components/examples/find_connector_response.yaml' - servers: - - url: https://localhost:5601 -servers: - - url: https://localhost:5601 diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@configure@{configurationid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@configure@{configurationid}.yaml deleted file mode 100644 index 204541dced9c1..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@configure@{configurationid}.yaml +++ /dev/null @@ -1,57 +0,0 @@ -patch: - summary: Updates external connection details, such as the closure type and default connector for cases in the default space. - operationId: updateCaseConfigurationDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case configuration. - Connectors are used to interface with external systems. You must create a - connector before you can use it in your cases. Refer to the add connectors - API. - tags: - - cases - - kibana - parameters: - - $ref: ../components/headers/kbn_xsrf.yaml - - $ref: ../components/parameters/configuration_id.yaml - requestBody: - content: - application/json: - schema: - type: object - properties: - closure_type: - $ref: '../components/schemas/closure_types.yaml' - connector: - description: An object that contains the connector configuration. - type: object - properties: - $ref: '../components/schemas/connector_properties.yaml' - required: - - fields - - id - - name - - type - version: - description: > - The version of the connector. To retrieve the version value, use - the get configuration API. - type: string - example: WzIwMiwxXQ== - required: - - version - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - $ref: '../components/schemas/case_configure_response_properties.yaml' - servers: - - url: https://localhost:5601 -servers: - - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@reporters.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@reporters.yaml deleted file mode 100644 index 2578f59c0ec6d..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@reporters.yaml +++ /dev/null @@ -1,34 +0,0 @@ -get: - summary: Returns information about the users who opened cases in the default space. - operationId: getCaseReportersDefaultSpace - description: > - You must have read privileges for the **Cases** feature in the **Management**, - **Observability**, or **Security** section of the Kibana feature privileges, - depending on the owner of the cases. - The API returns information about the users as they existed at the time of - the case creation, including their name, full name, and email address. If - any of those details change thereafter or if a user is deleted, the - information returned by this API is unchanged. - tags: - - cases - - kibana - parameters: - - $ref: '../components/parameters/owner.yaml' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: object - properties: - $ref: '../components/schemas/user_properties.yaml' - examples: - getReportersResponse: - $ref: '../components/examples/get_reporters_response.yaml' - servers: - - url: https://localhost:5601 -servers: - - url: https://localhost:5601 diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@status.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@status.yaml deleted file mode 100644 index 580248e0d99c1..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@status.yaml +++ /dev/null @@ -1,34 +0,0 @@ -get: - summary: Returns the number of cases that are open, closed, and in progress. - operationId: getCaseStatusDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're seeking. - tags: - - cases - - kibana - deprecated: true - parameters: - - $ref: '../components/parameters/owner.yaml' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - count_closed_cases: - type: integer - count_in_progress_cases: - type: integer - count_open_cases: - type: integer - examples: - getStatusResponse: - $ref: '../components/examples/get_status_response.yaml' - servers: - - url: https://localhost:5601 -servers: - - url: https://localhost:5601 diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@tags.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@tags.yaml deleted file mode 100644 index f74dabea5bd0c..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@tags.yaml +++ /dev/null @@ -1,36 +0,0 @@ -get: - summary: Aggregates and returns a list of case tags in the default space. - operationId: getCaseTagsDefaultSpace - description: > - You must have read privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're seeking. - tags: - - cases - - kibana - parameters: - - in: query - name: owner - description: A filter to limit the retrieved case statistics to a specific set of applications. If this parameter is omitted, the response contains tags from all cases that the user has access to read. - schema: - oneOf: - - $ref: '../components/schemas/owners.yaml' - - type: array - items: - $ref: '../components/schemas/owners.yaml' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - type: string - examples: - getTagsResponse: - $ref: '../components/examples/get_tags_response.yaml' - servers: - - url: https://localhost:5601 -servers: - - url: https://localhost:5601 diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}.yaml deleted file mode 100644 index 7290e5f5fdfba..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}.yaml +++ /dev/null @@ -1,35 +0,0 @@ -get: - summary: Retrieves information about a case in the default space. - operationId: getCaseDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're seeking. - tags: - - cases - - kibana - parameters: - - $ref: ../components/parameters/case_id.yaml - - in: query - name: includeComments - description: Determines whether case comments are returned. - deprecated: true - schema: - type: boolean - default: true - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - $ref: '../components/schemas/case_response_properties.yaml' - examples: - getCaseResponse: - $ref: '../components/examples/get_case_response.yaml' - servers: - - url: https://localhost:5601 -servers: - - url: https://localhost:5601 diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@alerts.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@alerts.yaml deleted file mode 100644 index e6b3ffbd8faad..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@alerts.yaml +++ /dev/null @@ -1,29 +0,0 @@ -get: - summary: Gets all alerts attached to a case in the default space. - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're seeking. - operationId: getCaseAlertsDefaultSpace - tags: - - cases - - kibana - x-technical-preview: true - parameters: - - $ref: ../components/parameters/case_id.yaml - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - $ref: '../components/schemas/alert_response_properties.yaml' - examples: - createCaseCommentResponse: - $ref: '../components/examples/get_case_alerts_response.yaml' - servers: - - url: https://localhost:5601 -servers: - - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@comments.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@comments.yaml deleted file mode 100644 index 95e49981d729d..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@comments.yaml +++ /dev/null @@ -1,126 +0,0 @@ -post: - summary: Adds a comment or alert to a case in the default space. - operationId: addCaseCommentDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're creating. - tags: - - cases - - kibana - parameters: - - $ref: '../components/headers/kbn_xsrf.yaml' - - $ref: '../components/parameters/case_id.yaml' - requestBody: - content: - application/json: - schema: - oneOf: - - $ref: '../components/schemas/add_alert_comment_request_properties.yaml' - - $ref: '../components/schemas/add_user_comment_request_properties.yaml' - examples: - createCaseCommentRequest: - $ref: '../components/examples/add_comment_request.yaml' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - $ref: '../components/schemas/case_response_properties.yaml' - examples: - createCaseCommentResponse: - $ref: '../components/examples/add_comment_response.yaml' - servers: - - url: https://localhost:5601 - -delete: - summary: Deletes all comments and alerts from a case in the default space. - operationId: deleteCaseCommentsDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're deleting. - tags: - - cases - - kibana - parameters: - - $ref: '../components/headers/kbn_xsrf.yaml' - - $ref: '../components/parameters/case_id.yaml' - responses: - '204': - description: Indicates a successful call. - servers: - - url: https://localhost:5601 - -patch: - summary: Updates a comment or alert in a case in the default space. - operationId: updateCaseCommentDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're updating. - NOTE: You cannot change the comment type or the owner of a comment. - tags: - - cases - - kibana - parameters: - - $ref: '../components/headers/kbn_xsrf.yaml' - - $ref: '../components/parameters/case_id.yaml' - requestBody: - content: - application/json: - schema: - oneOf: - - $ref: '../components/schemas/update_alert_comment_request_properties.yaml' - - $ref: '../components/schemas/update_user_comment_request_properties.yaml' - examples: - updateCaseCommentRequest: - $ref: '../components/examples/update_comment_request.yaml' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - $ref: '../components/schemas/case_response_properties.yaml' - examples: - updateCaseCommentResponse: - $ref: '../components/examples/update_comment_response.yaml' - servers: - - url: https://localhost:5601 - -get: - summary: Retrieves all the comments from a case in the default space. - operationId: getAllCaseCommentsDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the **Management**, - **Observability**, or **Security** section of the Kibana feature privileges, - depending on the owner of the cases with the comments you're seeking. - tags: - - cases - - kibana - deprecated: true - parameters: - - $ref: ../components/parameters/case_id.yaml - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - anyOf: - - $ref: '../components/schemas/alert_comment_response_properties.yaml' - - $ref: '../components/schemas/user_comment_response_properties.yaml' - examples: {} - servers: - - url: https://localhost:5601 - -servers: - - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@comments@{commentid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@comments@{commentid}.yaml deleted file mode 100644 index f76bd93cd8510..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@comments@{commentid}.yaml +++ /dev/null @@ -1,50 +0,0 @@ -delete: - summary: Deletes a comment or alert from a case in the default space. - operationId: deleteCaseCommentDefaultSpace - description: > - You must have `all` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the cases you're deleting. - tags: - - cases - - kibana - parameters: - - $ref: '../components/headers/kbn_xsrf.yaml' - - $ref: '../components/parameters/case_id.yaml' - - $ref: '../components/parameters/comment_id.yaml' - responses: - '204': - description: Indicates a successful call. - servers: - - url: https://localhost:5601 - -get: - summary: Retrieves a comment from a case in the default space. - operationId: getCaseCommentDefaultSpace - description: > - You must have `read` privileges for the **Cases** feature in the **Management**, - **Observability**, or **Security** section of the Kibana feature privileges, - depending on the owner of the cases with the comments you're seeking. - tags: - - cases - - kibana - parameters: - - $ref: '../components/parameters/case_id.yaml' - - $ref: '../components/parameters/comment_id.yaml' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - oneOf: - - $ref: '../components/schemas/alert_comment_response_properties.yaml' - - $ref: '../components/schemas/user_comment_response_properties.yaml' - examples: - getCaseCommentResponse: - $ref: '../components/examples/get_comment_response.yaml' - servers: - - url: https://localhost:5601 - -servers: - - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@connector@{connectorid}@_push.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@connector@{connectorid}@_push.yaml deleted file mode 100644 index 7fc3a73db00b5..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@connector@{connectorid}@_push.yaml +++ /dev/null @@ -1,35 +0,0 @@ -post: - summary: Pushes a case to an external service. - description: > - You must have `all` privileges for the **Actions and Connectors** feature in - the **Management** section of the Kibana feature privileges. You must also - have `all` privileges for the **Cases** feature in the **Management**, - **Observability**, or **Security** section of the Kibana feature privileges, - depending on the owner of the case you're pushing. - operationId: pushCaseDefaultSpace - tags: - - cases - - kibana - parameters: - - $ref: '../components/parameters/case_id.yaml' - - $ref: '../components/parameters/connector_id.yaml' - - $ref: '../components/headers/kbn_xsrf.yaml' - requestBody: - content: - application/json: {} - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: object - properties: - $ref: '../components/schemas/case_response_properties.yaml' - examples: - pushCaseResponse: - $ref: '../components/examples/push_case_response.yaml' - servers: - - url: https://localhost:5601 -servers: - - url: https://localhost:5601 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@user_actions.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@user_actions.yaml deleted file mode 100644 index 66a3d389aee14..0000000000000 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@user_actions.yaml +++ /dev/null @@ -1,29 +0,0 @@ -get: - summary: Returns all user activity for a case in the default space. - description: > - You must have `read` privileges for the **Cases** feature in the - **Management**, **Observability**, or **Security** section of the Kibana - feature privileges, depending on the owner of the case you're seeking. - deprecated: true - operationId: getCaseActivityDefaultSpace - tags: - - cases - - kibana - parameters: - - $ref: '../components/parameters/case_id.yaml' - responses: - '200': - description: Indicates a successful call. - content: - application/json; charset=utf-8: - schema: - type: array - items: - $ref: '../components/schemas/user_actions_response_properties.yaml' - examples: - getCaseActivityResponse: - $ref: '../components/examples/get_case_activity_response.yaml' - servers: - - url: https://localhost:5601 -servers: - - url: https://localhost:5601 diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml index 5e891285ac8ba..59abb58531821 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases.yaml @@ -7,7 +7,6 @@ post: feature privileges, depending on the owner of the case you're creating. tags: - cases - - kibana parameters: - $ref: ../components/headers/kbn_xsrf.yaml - $ref: '../components/parameters/space_id.yaml' @@ -79,7 +78,6 @@ delete: depending on the owner of the cases you're deleting. tags: - cases - - kibana parameters: - $ref: ../components/headers/kbn_xsrf.yaml - $ref: '../components/parameters/space_id.yaml' @@ -105,7 +103,6 @@ patch: feature privileges, depending on the owner of the case you're updating. tags: - cases - - kibana parameters: - $ref: ../components/headers/kbn_xsrf.yaml - $ref: '../components/parameters/space_id.yaml' diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml index 48801a11dea66..a260321248357 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml @@ -7,7 +7,6 @@ get: feature privileges, depending on the owner of the cases you're seeking. tags: - cases - - kibana parameters: - $ref: '../components/parameters/space_id.yaml' - name: defaultSearchOperator diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml index 20c365947e351..24615d772b3ef 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml @@ -8,7 +8,6 @@ get: x-technical-preview: true tags: - cases - - kibana parameters: - $ref: ../components/parameters/alert_id.yaml - $ref: '../components/parameters/space_id.yaml' diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml index 2df6edb39c1ce..97306b5490956 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure.yaml @@ -7,7 +7,6 @@ get: feature privileges, depending on the owner of the case configuration. tags: - cases - - kibana parameters: - $ref: '../components/parameters/space_id.yaml' - $ref: '../components/parameters/owner.yaml' @@ -39,7 +38,6 @@ post: still specify all of the connector details. tags: - cases - - kibana parameters: - $ref: ../components/headers/kbn_xsrf.yaml - $ref: '../components/parameters/space_id.yaml' diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml index dfbbc498d836d..0755225bad71a 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@connectors@_find.yaml @@ -7,7 +7,6 @@ get: feature in the **Management** section of the Kibana feature privileges. tags: - cases - - kibana parameters: - $ref: '../components/parameters/space_id.yaml' responses: diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml index 18336746e830b..f727cbb0b4274 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@configure@{configurationid}.yaml @@ -9,7 +9,6 @@ patch: connector before you can use it in your cases. Refer to the add connectors API. tags: - cases - - kibana parameters: - $ref: ../components/headers/kbn_xsrf.yaml - $ref: ../components/parameters/configuration_id.yaml diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml index e35c2ceaf5063..93b7ac3863c99 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@reporters.yaml @@ -11,7 +11,6 @@ get: information returned by this API is unchanged. tags: - cases - - kibana parameters: - $ref: '../components/parameters/space_id.yaml' - $ref: '../components/parameters/owner.yaml' diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml index 5d8aa302fd76f..dad05ad967728 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@status.yaml @@ -8,7 +8,6 @@ get: deprecated: true tags: - cases - - kibana parameters: - $ref: '../components/parameters/space_id.yaml' - $ref: '../components/parameters/owner.yaml' diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml index 58f1e7369d718..6787c075cb19f 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@tags.yaml @@ -7,7 +7,6 @@ get: feature privileges, depending on the owner of the cases you're seeking. tags: - cases - - kibana parameters: - $ref: '../components/parameters/space_id.yaml' - in: query diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml index 30c33a27a37f6..9e8ca4660c44d 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}.yaml @@ -7,7 +7,6 @@ get: feature privileges, depending on the owner of the case you're seeking. tags: - cases - - kibana parameters: - $ref: ../components/parameters/case_id.yaml - $ref: '../components/parameters/space_id.yaml' diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml index 6236078853e71..66430fd219d25 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@alerts.yaml @@ -8,7 +8,6 @@ get: operationId: getCaseAlerts tags: - cases - - kibana parameters: - $ref: ../components/parameters/case_id.yaml - $ref: '../components/parameters/space_id.yaml' diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml index 9d139bed703e4..c8a045267a492 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments.yaml @@ -7,7 +7,6 @@ post: feature privileges, depending on the owner of the case you're creating. tags: - cases - - kibana parameters: - $ref: '../components/headers/kbn_xsrf.yaml' - $ref: '../components/parameters/case_id.yaml' @@ -46,7 +45,6 @@ delete: feature privileges, depending on the owner of the cases you're deleting. tags: - cases - - kibana parameters: - $ref: '../components/headers/kbn_xsrf.yaml' - $ref: '../components/parameters/case_id.yaml' @@ -67,7 +65,6 @@ patch: NOTE: You cannot change the comment type or the owner of a comment. tags: - cases - - kibana parameters: - $ref: '../components/headers/kbn_xsrf.yaml' - $ref: '../components/parameters/case_id.yaml' @@ -107,7 +104,6 @@ get: deprecated: true tags: - cases - - kibana parameters: - $ref: '../components/parameters/case_id.yaml' - $ref: '../components/parameters/space_id.yaml' diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml index 2ed9456aed4db..3aac8f33bc68b 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@comments@{commentid}.yaml @@ -7,7 +7,6 @@ delete: feature privileges, depending on the owner of the cases you're deleting. tags: - cases - - kibana parameters: - $ref: '../components/headers/kbn_xsrf.yaml' - $ref: '../components/parameters/case_id.yaml' @@ -28,7 +27,6 @@ get: depending on the owner of the cases with the comments you're seeking. tags: - cases - - kibana parameters: - $ref: '../components/parameters/case_id.yaml' - $ref: '../components/parameters/comment_id.yaml' diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml index d2291b59ec088..32caad2bc4086 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml @@ -9,7 +9,6 @@ post: operationId: pushCase tags: - cases - - kibana parameters: - $ref: '../components/parameters/case_id.yaml' - $ref: '../components/parameters/connector_id.yaml' diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml index 723265cfbe495..71301cf67a731 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions.yaml @@ -8,7 +8,6 @@ get: operationId: getCaseActivity tags: - cases - - kibana parameters: - $ref: '../components/parameters/case_id.yaml' - $ref: '../components/parameters/space_id.yaml' From fbf343a4e92733553bf5c025b6a65e3d3a16a422 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 26 Sep 2022 12:17:59 -0600 Subject: [PATCH 29/51] [Maps] hide/show all layers (#141495) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../maps/public/actions/layer_actions.ts | 26 +++++ .../__snapshots__/layer_control.test.tsx.snap | 102 ++++++++++++++++++ .../layer_control/index.ts | 15 ++- .../layer_control/layer_control.test.tsx | 2 + .../layer_control/layer_control.tsx | 38 +++++++ 5 files changed, 182 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index 7a4377f0bfc27..317f6e09053e5 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -284,6 +284,32 @@ export function toggleLayerVisible(layerId: string) { }; } +export function hideAllLayers() { + return ( + dispatch: ThunkDispatch, + getState: () => MapStoreState + ) => { + getLayerList(getState()).forEach((layer: ILayer, index: number) => { + if (layer.isVisible() && !layer.isBasemap(index)) { + dispatch(setLayerVisibility(layer.getId(), false)); + } + }); + }; +} + +export function showAllLayers() { + return ( + dispatch: ThunkDispatch, + getState: () => MapStoreState + ) => { + getLayerList(getState()).forEach((layer: ILayer, index: number) => { + if (!layer.isVisible()) { + dispatch(setLayerVisibility(layer.getId(), true)); + } + }); + }; +} + export function showThisLayerOnly(layerId: string) { return ( dispatch: ThunkDispatch, diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/__snapshots__/layer_control.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/__snapshots__/layer_control.test.tsx.snap index 7d0c67ff41797..e043a8d723e14 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/__snapshots__/layer_control.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/__snapshots__/layer_control.test.tsx.snap @@ -31,6 +31,40 @@ exports[`LayerControl is rendered 1`] = `
+

Access

+
    +
  1. APIKey KeyParamName:ApiKey KeyInQuery:false KeyInHeader:true
  2. +
  3. HTTP Basic Authentication
  4. +
+ +

Methods

+ [ Jump to Models ] + +

Table of Contents

+
+

Ml

+ + +

Ml

+
+
+ Up +
get /s/{spaceId}/api/ml/saved_objects/sync
+
Synchronizes Kibana saved objects for machine learning jobs and trained models. (mlSync)
+
You must have all privileges for the Machine Learning feature in the Analytics section of the Kibana feature privileges. This API runs automatically when you start Kibana and periodically thereafter.
+ +

Path parameters

+
+
spaceId (required)
+ +
Path Parameter — An identifier for the space. If /s/ and the identifier are omitted from the path, the default space is used. default: null
+
+ + + + +

Query parameters

+
+
simulate (optional)
+ +
Query Parameter — When true, simulates the synchronization by returning only the list actions that would be performed. default: null
+
+ + +

Return type

+ + + + +

Example data

+
Content-Type: application/json
+
{
+  "datafeedsAdded" : {
+    "key" : {
+      "success" : true
+    }
+  },
+  "savedObjectsCreated" : {
+    "anomaly-detector" : {
+      "key" : {
+        "success" : true
+      }
+    },
+    "data-frame-analytics" : {
+      "key" : {
+        "success" : true
+      }
+    },
+    "trained-model" : {
+      "key" : {
+        "success" : true
+      }
+    }
+  },
+  "savedObjectsDeleted" : {
+    "anomaly-detector" : {
+      "key" : {
+        "success" : true
+      }
+    },
+    "data-frame-analytics" : {
+      "key" : {
+        "success" : true
+      }
+    },
+    "trained-model" : {
+      "key" : {
+        "success" : true
+      }
+    }
+  },
+  "datafeedsRemoved" : {
+    "key" : {
+      "success" : true
+    }
+  }
+}
+ +

Produces

+ This API call produces the following media types according to the Accept request header; + the media type will be conveyed by the Content-Type response header. +
    +
  • application/json
  • +
+ +

Responses

+

200

+ Indicates a successful call + mlSyncResponse +
+
+ +

Models

+ [ Jump to Methods ] + +

Table of Contents

+
    +
  1. mlSyncResponse - Sync API response
  2. +
  3. mlSyncResponseAnomalyDetectors - Sync API response for anomaly detection jobs
  4. +
  5. mlSyncResponseDataFrameAnalytics - Sync API response for data frame analytics jobs
  6. +
  7. mlSyncResponseDatafeeds - Sync API response for datafeeds
  8. +
  9. mlSyncResponseSavedObjectsCreated - Sync API response for created saved objects
  10. +
  11. mlSyncResponseSavedObjectsDeleted - Sync API response for deleted saved objects
  12. +
  13. mlSyncResponseTrainedModels - Sync API response for trained models
  14. +
+ +
+

mlSyncResponse - Sync API response Up

+
+
+
datafeedsAdded (optional)
map[String, mlSyncResponseDatafeeds] If a saved object for an anomaly detection job is missing a datafeed identifier, it is added when you run the sync machine learning saved objects API.
+
datafeedsRemoved (optional)
map[String, mlSyncResponseDatafeeds] If a saved object for an anomaly detection job references a datafeed that no longer exists, it is deleted when you run the sync machine learning saved objects API.
+
savedObjectsCreated (optional)
+
savedObjectsDeleted (optional)
+
+
+
+

mlSyncResponseAnomalyDetectors - Sync API response for anomaly detection jobs Up

+
The sync machine learning saved objects API response contains this object when there are anomaly detection jobs affected by the synchronization. There is an object for each relevant job, which contains the synchronization status.
+
+
success (optional)
Boolean The success or failure of the synchronization.
+
+
+
+

mlSyncResponseDataFrameAnalytics - Sync API response for data frame analytics jobs Up

+
The sync machine learning saved objects API response contains this object when there are data frame analytics jobs affected by the synchronization. There is an object for each relevant job, which contains the synchronization status.
+
+
success (optional)
Boolean The success or failure of the synchronization.
+
+
+
+

mlSyncResponseDatafeeds - Sync API response for datafeeds Up

+
The sync machine learning saved objects API response contains this object when there are datafeeds affected by the synchronization. There is an object for each relevant datafeed, which contains the synchronization status.
+
+
success (optional)
Boolean The success or failure of the synchronization.
+
+
+
+

mlSyncResponseSavedObjectsCreated - Sync API response for created saved objects Up

+
If saved objects are missing for machine learning jobs or trained models, they are created when you run the sync machine learning saved objects API.
+
+
anomalyMinusdetector (optional)
map[String, mlSyncResponseAnomalyDetectors] If saved objects are missing for anomaly detection jobs, they are created.
+
dataMinusframeMinusanalytics (optional)
map[String, mlSyncResponseDataFrameAnalytics] If saved objects are missing for data frame analytics jobs, they are created.
+
trainedMinusmodel (optional)
map[String, mlSyncResponseTrainedModels] If saved objects are missing for trained models, they are created.
+
+
+
+

mlSyncResponseSavedObjectsDeleted - Sync API response for deleted saved objects Up

+
If saved objects exist for machine learning jobs or trained models that no longer exist, they are deleted when you run the sync machine learning saved objects API.
+
+
anomalyMinusdetector (optional)
map[String, mlSyncResponseAnomalyDetectors] If there are saved objects exist for nonexistent anomaly detection jobs, they are deleted.
+
dataMinusframeMinusanalytics (optional)
map[String, mlSyncResponseDataFrameAnalytics] If there are saved objects exist for nonexistent data frame analytics jobs, they are deleted.
+
trainedMinusmodel (optional)
map[String, mlSyncResponseTrainedModels] If there are saved objects exist for nonexistent trained models, they are deleted.
+
+
+
+

mlSyncResponseTrainedModels - Sync API response for trained models Up

+
The sync machine learning saved objects API response contains this object when there are trained models affected by the synchronization. There is an object for each relevant trained model, which contains the synchronization status.
+
+
success (optional)
Boolean The success or failure of the synchronization.
+
+
+
+ + + + + + + + + + @@ -184,6 +218,40 @@ exports[`LayerControl isReadOnly 1`] = ` + + + + + + + + + + @@ -245,6 +313,40 @@ exports[`LayerControl should disable buttons when flyout is open 1`] = ` + + + + + + + + + + diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/index.ts b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/index.ts index c525523047c40..d5dc63ecb8e8b 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/index.ts +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/index.ts @@ -11,7 +11,14 @@ import { connect } from 'react-redux'; import { LayerControl } from './layer_control'; import { FLYOUT_STATE } from '../../../reducers/ui'; -import { setSelectedLayer, updateFlyout, setIsLayerTOCOpen, setDrawMode } from '../../../actions'; +import { + hideAllLayers, + setSelectedLayer, + updateFlyout, + setIsLayerTOCOpen, + setDrawMode, + showAllLayers, +} from '../../../actions'; import { getIsReadOnly, getIsLayerTOCOpen, @@ -43,6 +50,12 @@ function mapDispatchToProps(dispatch: ThunkDispatch { dispatch(setIsLayerTOCOpen(true)); }, + hideAllLayers: () => { + dispatch(hideAllLayers()); + }, + showAllLayers: () => { + dispatch(showAllLayers()); + }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_control.test.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_control.test.tsx index 649999ab49a9d..1fc9fa6b9755e 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_control.test.tsx @@ -28,6 +28,8 @@ const defaultProps = { showAddLayerWizard: async () => {}, closeLayerTOC: () => {}, openLayerTOC: () => {}, + hideAllLayers: () => {}, + showAllLayers: () => {}, isLayerTOCOpen: true, layerList: [], isFlyoutOpen: false, diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_control.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_control.tsx index d131bf9b98026..297d7ccfd5063 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_control.tsx @@ -31,6 +31,8 @@ export interface Props { showAddLayerWizard: () => Promise; closeLayerTOC: () => void; openLayerTOC: () => void; + hideAllLayers: () => void; + showAllLayers: () => void; } function renderExpandButton({ @@ -81,6 +83,8 @@ export function LayerControl({ openLayerTOC, layerList, isFlyoutOpen, + hideAllLayers, + showAllLayers, }: Props) { if (!isLayerTOCOpen) { if (isScreenshotMode()) { @@ -152,6 +156,40 @@ export function LayerControl({ + + + + + + + + + + Date: Mon, 26 Sep 2022 19:24:21 +0100 Subject: [PATCH 30/51] [Enterprise Search] [Behavioural analytics] BUG hide UI settings option (#141786) * hides behavioural analytics ui setting * update test for uiSettings call --- .../public/applications/analytics/index.tsx | 3 +-- .../applications/shared/layout/nav.test.tsx | 5 ++++- .../public/applications/shared/layout/nav.tsx | 3 +-- .../enterprise_search/public/plugin.ts | 3 ++- .../enterprise_search/server/ui_settings.ts | 22 +------------------ 5 files changed, 9 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/analytics/index.tsx b/x-pack/plugins/enterprise_search/public/applications/analytics/index.tsx index eaed153a01b7f..f1228682fe888 100644 --- a/x-pack/plugins/enterprise_search/public/applications/analytics/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/analytics/index.tsx @@ -29,8 +29,7 @@ export const Analytics: React.FC = (props) => { const incompatibleVersions = isVersionMismatch(enterpriseSearchVersion, kibanaVersion); const { uiSettings } = useValues(KibanaLogic); - const analyticsSectionEnabled = - uiSettings?.get(enableBehavioralAnalyticsSection) ?? false; + const analyticsSectionEnabled = uiSettings?.get(enableBehavioralAnalyticsSection, false); if (!analyticsSectionEnabled) { return ; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx index 743efc3274a44..67fb93ae643f6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx @@ -86,7 +86,10 @@ describe('useEnterpriseSearchContentNav', () => { name: 'Search', }, ]); - expect(mockKibanaValues.uiSettings.get).toHaveBeenCalledWith(enableBehavioralAnalyticsSection); + expect(mockKibanaValues.uiSettings.get).toHaveBeenCalledWith( + enableBehavioralAnalyticsSection, + false + ); }); it('excludes legacy products when the user has no access to them', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx index f5a2d17d7dd94..967095d9674ba 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx @@ -27,8 +27,7 @@ import { generateNavLink } from './nav_link_helpers'; export const useEnterpriseSearchNav = () => { const { productAccess, uiSettings } = useValues(KibanaLogic); - const analyticsSectionEnabled = - uiSettings?.get(enableBehavioralAnalyticsSection) ?? false; + const analyticsSectionEnabled = uiSettings?.get(enableBehavioralAnalyticsSection, false); const navItems: Array> = [ { diff --git a/x-pack/plugins/enterprise_search/public/plugin.ts b/x-pack/plugins/enterprise_search/public/plugin.ts index ac7581814242e..f193016e73f0d 100644 --- a/x-pack/plugins/enterprise_search/public/plugin.ts +++ b/x-pack/plugins/enterprise_search/public/plugin.ts @@ -72,7 +72,8 @@ export class EnterpriseSearchPlugin implements Plugin { const { cloud } = plugins; const bahavioralAnalyticsEnabled = core.uiSettings?.get( - enableBehavioralAnalyticsSection + enableBehavioralAnalyticsSection, + false ); core.application.register({ diff --git a/x-pack/plugins/enterprise_search/server/ui_settings.ts b/x-pack/plugins/enterprise_search/server/ui_settings.ts index 3334e625bc08f..99fb5906a3050 100644 --- a/x-pack/plugins/enterprise_search/server/ui_settings.ts +++ b/x-pack/plugins/enterprise_search/server/ui_settings.ts @@ -5,29 +5,9 @@ * 2.0. */ -import { schema } from '@kbn/config-schema'; import { UiSettingsParams } from '@kbn/core/types'; -import { i18n } from '@kbn/i18n'; - -import { - enterpriseSearchFeatureId, - enableBehavioralAnalyticsSection, -} from '../common/ui_settings_keys'; /** * uiSettings definitions for Enterprise Search */ -export const uiSettings: Record> = { - [enableBehavioralAnalyticsSection]: { - category: [enterpriseSearchFeatureId], - description: i18n.translate('xpack.enterpriseSearch.uiSettings.analytics.description', { - defaultMessage: 'Enable the new Analytics section in Enterprise Search.', - }), - name: i18n.translate('xpack.enterpriseSearch.uiSettings.analytics.name', { - defaultMessage: 'Enable Behavioral Analytics', - }), - requiresPageReload: true, - schema: schema.boolean(), - value: false, - }, -}; +export const uiSettings: Record> = {}; From fd3a688cec29c656e55e94b29a99f6874845cc54 Mon Sep 17 00:00:00 2001 From: Davis Plumlee <56367316+dplumlee@users.noreply.github.com> Date: Mon, 26 Sep 2022 20:25:45 +0200 Subject: [PATCH 31/51] [Security Solution] Fixes unprocessed exceptions logging (#141523) --- .../new_terms/create_new_terms_alert_type.ts | 9 ++++++--- .../detection_engine/signals/executors/eql.test.ts | 11 ++++++----- .../lib/detection_engine/signals/executors/eql.ts | 8 +++++--- .../signals/executors/threshold.test.ts | 11 ++++++----- .../detection_engine/signals/executors/threshold.ts | 7 +++++-- .../lib/detection_engine/signals/utils.test.ts | 11 +++++------ .../server/lib/detection_engine/signals/utils.ts | 13 ++++++------- 7 files changed, 39 insertions(+), 31 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts index d1fa77857c1f7..2e22d3a5798bf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts @@ -32,7 +32,7 @@ import { parseDateString, validateHistoryWindowStart } from './utils'; import { addToSearchAfterReturn, createSearchAfterReturnType, - logUnprocessedExceptionsWarnings, + getUnprocessedExceptionsWarnings, } from '../../signals/utils'; import { createEnrichEventsFunction } from '../../signals/enrichments'; @@ -114,8 +114,6 @@ export const createNewTermsAlertType = ( from: params.from, }); - logUnprocessedExceptionsWarnings(unprocessedExceptions, ruleExecutionLogger); - const esFilter = await getFilter({ filters: params.filters, index: inputIndex, @@ -137,6 +135,11 @@ export const createNewTermsAlertType = ( const result = createSearchAfterReturnType(); + const exceptionsWarning = getUnprocessedExceptionsWarnings(unprocessedExceptions); + if (exceptionsWarning) { + result.warningMessages.push(exceptionsWarning); + } + // There are 2 conditions that mean we're finished: either there were still too many alerts to create // after deduplication and the array of alerts was truncated before being submitted to ES, or there were // exactly enough new alerts to hit maxSignals without truncating the array of alerts. We check both because diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts index d19e7cabe6769..93e37c41c8ab3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts @@ -45,7 +45,7 @@ describe('eql_executor', () => { describe('eqlExecutor', () => { it('should set a warning when exception list for eql rule contains value list exceptions', async () => { - await eqlExecutor({ + const result = await eqlExecutor({ inputIndex: DEFAULT_INDEX_PATTERN, runtimeMappings: {}, completeRule: eqlCompleteRule, @@ -60,10 +60,11 @@ describe('eql_executor', () => { exceptionFilter: undefined, unprocessedExceptions: [getExceptionListItemSchemaMock()], }); - expect(ruleExecutionLogger.warn).toHaveBeenCalled(); - expect(ruleExecutionLogger.warn.mock.calls[0][0]).toContain( - "The following exceptions won't be applied to rule execution" - ); + expect(result.warningMessages).toEqual([ + `The following exceptions won't be applied to rule execution: ${ + getExceptionListItemSchemaMock().name + }`, + ]); }); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts index 9622e09d37374..436ebec9c27c1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts @@ -29,7 +29,7 @@ import { addToSearchAfterReturn, createSearchAfterReturnType, makeFloatString, - logUnprocessedExceptionsWarnings, + getUnprocessedExceptionsWarnings, } from '../utils'; import { buildReasonMessageForEqlAlert } from '../reason_formatters'; import type { CompleteRule, EqlRuleParams } from '../../schemas/rule_schemas'; @@ -93,8 +93,10 @@ export const eqlExecutor = async ({ }); ruleExecutionLogger.debug(`EQL query request: ${JSON.stringify(request)}`); - logUnprocessedExceptionsWarnings(unprocessedExceptions, ruleExecutionLogger); - + const exceptionsWarning = getUnprocessedExceptionsWarnings(unprocessedExceptions); + if (exceptionsWarning) { + result.warningMessages.push(exceptionsWarning); + } const eqlSignalSearchStart = performance.now(); const response = await services.scopedClusterClient.asCurrentUser.eql.search( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.test.ts index dd62af6bfea13..832ffa1e5b5c4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.test.ts @@ -141,7 +141,7 @@ describe('threshold_executor', () => { [`${getThresholdTermsHash(terms2)}`]: signalHistoryRecord2, }, }; - await thresholdExecutor({ + const result = await thresholdExecutor({ completeRule: thresholdCompleteRule, tuple, services: alertServices, @@ -165,10 +165,11 @@ describe('threshold_executor', () => { exceptionFilter: undefined, unprocessedExceptions: [getExceptionListItemSchemaMock()], }); - expect(ruleExecutionLogger.warn).toHaveBeenCalled(); - expect(ruleExecutionLogger.warn.mock.calls[0][0]).toContain( - "The following exceptions won't be applied to rule execution" - ); + expect(result.warningMessages).toEqual([ + `The following exceptions won't be applied to rule execution: ${ + getExceptionListItemSchemaMock().name + }`, + ]); }); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts index 398bce577689b..ed82f7cdb1f8a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts @@ -34,7 +34,7 @@ import type { import { addToSearchAfterReturn, createSearchAfterReturnType, - logUnprocessedExceptionsWarnings, + getUnprocessedExceptionsWarnings, } from '../utils'; import { withSecuritySpan } from '../../../../utils/with_security_span'; import { buildThresholdSignalHistory } from '../threshold/build_signal_history'; @@ -81,7 +81,10 @@ export const thresholdExecutor = async ({ const ruleParams = completeRule.ruleParams; return withSecuritySpan('thresholdExecutor', async () => { - logUnprocessedExceptionsWarnings(unprocessedExceptions, ruleExecutionLogger); + const exceptionsWarning = getUnprocessedExceptionsWarnings(unprocessedExceptions); + if (exceptionsWarning) { + result.warningMessages.push(exceptionsWarning); + } // Get state or build initial state (on upgrade) const { signalHistory, searchErrors: previousSearchErrors } = state.initialized diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts index afbcb355da05f..d5603130400c7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts @@ -45,7 +45,7 @@ import { isDetectionAlert, getField, addToSearchAfterReturn, - logUnprocessedExceptionsWarnings, + getUnprocessedExceptionsWarnings, } from './utils'; import type { BulkResponseErrorAggregation, SearchAfterAndBulkCreateReturnType } from './types'; import { @@ -1667,14 +1667,13 @@ describe('utils', () => { describe('logUnprocessedExceptionsWarnings', () => { test('does not log anything when the array is empty', () => { - logUnprocessedExceptionsWarnings([], ruleExecutionLogger); - expect(ruleExecutionLogger.warn).not.toHaveBeenCalled(); + const result = getUnprocessedExceptionsWarnings([]); + expect(result).toBeUndefined(); }); test('logs the exception names when there are unprocessed exceptions', () => { - logUnprocessedExceptionsWarnings([getExceptionListItemSchemaMock()], ruleExecutionLogger); - expect(ruleExecutionLogger.warn).toHaveBeenCalled(); - expect(ruleExecutionLogger.warn.mock.calls[0][0]).toContain( + const result = getUnprocessedExceptionsWarnings([getExceptionListItemSchemaMock()]); + expect(result).toEqual( `The following exceptions won't be applied to rule execution: ${ getExceptionListItemSchemaMock().name }` diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts index a7fe9dfaf6c30..6030400da2b75 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts @@ -972,14 +972,13 @@ export const getField = (event: SimpleHit, field: string): SearchTypes | undefin } }; -export const logUnprocessedExceptionsWarnings = ( - unprocessedExceptions: ExceptionListItemSchema[], - ruleExecutionLogger: IRuleExecutionLogForExecutors -) => { +export const getUnprocessedExceptionsWarnings = ( + unprocessedExceptions: ExceptionListItemSchema[] +): string | undefined => { if (unprocessedExceptions.length > 0) { const exceptionNames = unprocessedExceptions.map((exception) => exception.name); - ruleExecutionLogger.warn( - `The following exceptions won't be applied to rule execution: ${exceptionNames.join(', ')}` - ); + return `The following exceptions won't be applied to rule execution: ${exceptionNames.join( + ', ' + )}`; } }; From 16589af4ca67c7136d5511fa22a9a37d8929c317 Mon Sep 17 00:00:00 2001 From: John Dorlus Date: Mon, 26 Sep 2022 15:01:20 -0400 Subject: [PATCH 32/51] Observability a11y tests (#141266) * Updated test to use uiSettings. * Added initial files for observability a11y tests. * Observability test for the guided setup. * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * fixed dashboard merge conflict. * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * Changed the wait condition to reduce flakiness. * Removed .only(). * Skipped a11y test after finding violation. Co-authored-by: cuffs Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../overview_page/overview_page.tsx | 5 ++- .../test/accessibility/apps/observability.ts | 42 +++++++++++++++++++ x-pack/test/accessibility/config.ts | 1 + 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 x-pack/test/accessibility/apps/observability.ts diff --git a/x-pack/plugins/observability/public/pages/overview/containers/overview_page/overview_page.tsx b/x-pack/plugins/observability/public/pages/overview/containers/overview_page/overview_page.tsx index 1f09cfc38cf4c..e8a90cac969c6 100644 --- a/x-pack/plugins/observability/public/pages/overview/containers/overview_page/overview_page.tsx +++ b/x-pack/plugins/observability/public/pages/overview/containers/overview_page/overview_page.tsx @@ -226,7 +226,10 @@ export function OverviewPage() { > -

+

{ + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'); + await PageObjects.common.navigateToApp('observability'); + }); + + describe('Overview', async () => { + before(async () => { + await observability.overview.common.openAlertsSectionAndWaitToAppear(); + await a11y.testAppSnapshot(); + }); + it('Guided Setup', async () => { + await PageObjects.infraHome.clickGuidedSetupButton(); + await retry.waitFor('Guided setup header to be visible', async () => { + return await testSubjects.isDisplayed('statusVisualizationFlyoutTitle'); + }); + await a11y.testAppSnapshot(); + }); + }); + }); +} diff --git a/x-pack/test/accessibility/config.ts b/x-pack/test/accessibility/config.ts index be4fe6c531bed..524608b130779 100644 --- a/x-pack/test/accessibility/config.ts +++ b/x-pack/test/accessibility/config.ts @@ -54,6 +54,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { require.resolve('./apps/stack_monitoring'), require.resolve('./apps/watcher'), require.resolve('./apps/rollup_jobs'), + require.resolve('./apps/observability'), ], pageObjects, From d1498ac1fb3ea0e29632b540cf23ef1d092b35f4 Mon Sep 17 00:00:00 2001 From: Andrew Tate Date: Mon, 26 Sep 2022 14:16:31 -0500 Subject: [PATCH 33/51] [Lens] optimize duplicate formula functions (#140859) --- src/plugins/data/public/index.ts | 2 + .../dedupe_aggs.test.ts | 108 ++++++ .../indexpattern_datasource/dedupe_aggs.ts | 98 +++++ .../indexpattern.test.ts | 347 ++++++++++++------ .../definitions/cardinality.test.ts | 111 ++++++ .../operations/definitions/cardinality.tsx | 8 + .../operations/definitions/count.test.ts | 122 ++++++ .../operations/definitions/count.tsx | 9 + .../definitions/get_group_by_key.ts | 81 ++++ .../operations/definitions/index.ts | 23 ++ .../definitions/last_value.test.tsx | 105 ++++++ .../operations/definitions/last_value.tsx | 9 + .../operations/definitions/metrics.test.ts | 132 +++++++ .../operations/definitions/metrics.tsx | 9 + .../definitions/percentile.test.tsx | 109 +++++- .../operations/definitions/percentile.tsx | 15 + .../definitions/terms/helpers.test.ts | 134 ------- .../operations/definitions/terms/helpers.ts | 26 -- .../operations/definitions/terms/index.tsx | 11 +- .../definitions/terms/terms.test.tsx | 43 --- .../indexpattern_datasource/to_expression.ts | 21 +- 21 files changed, 1173 insertions(+), 350 deletions(-) create mode 100644 x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.test.ts create mode 100644 x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.ts create mode 100644 x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.test.ts create mode 100644 x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.test.ts create mode 100644 x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/get_group_by_key.ts create mode 100644 x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.test.ts diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index c8eefbdd92c6e..fa545d7648df1 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -139,6 +139,8 @@ export type { ParsedInterval, // expressions ExecutionContextSearch, + ExpressionFunctionKql, + ExpressionFunctionLucene, ExpressionFunctionKibana, ExpressionFunctionKibanaContext, ExpressionValueSearchContext, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.test.ts new file mode 100644 index 0000000000000..eb98d7411491c --- /dev/null +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.test.ts @@ -0,0 +1,108 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + buildExpression, + ExpressionAstExpressionBuilder, + parseExpression, +} from '@kbn/expressions-plugin/common'; +import { dedupeAggs } from './dedupe_aggs'; +import { operationDefinitionMap } from './operations'; +import { OriginalColumn } from './to_expression'; + +describe('dedupeAggs', () => { + const buildMapsFromAggBuilders = (aggs: ExpressionAstExpressionBuilder[]) => { + const esAggsIdMap: Record = {}; + const aggsToIdsMap = new Map(); + aggs.forEach((builder, i) => { + const esAggsId = `col-${i}-${i}`; + esAggsIdMap[esAggsId] = [{ id: `original-${i}` } as OriginalColumn]; + aggsToIdsMap.set(builder, esAggsId); + }); + return { + esAggsIdMap, + aggsToIdsMap, + }; + }; + + it('removes duplicate aggregations', () => { + const aggs = [ + 'aggSum id="0" enabled=true schema="metric" field="bytes" emptyAsNull=false', + 'aggSum id="1" enabled=true schema="metric" field="bytes" emptyAsNull=false', + 'aggFilteredMetric id="2" enabled=true schema="metric" \n customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="hour_of_day: *"}} \n customMetric={aggTopMetrics id="2-metric" enabled=true schema="metric" field="hour_of_day" size=1 sortOrder="desc" sortField="timestamp"}', + 'aggFilteredMetric id="3" enabled=true schema="metric" \n customBucket={aggFilter id="3-filter" enabled=true schema="bucket" filter={kql q="hour_of_day: *"}} \n customMetric={aggTopMetrics id="3-metric" enabled=true schema="metric" field="hour_of_day" size=1 sortOrder="desc" sortField="timestamp"}', + 'aggAvg id="4" enabled=true schema="metric" field="bytes"', + 'aggAvg id="5" enabled=true schema="metric" field="bytes"', + ].map((expression) => buildExpression(parseExpression(expression))); + + const { esAggsIdMap, aggsToIdsMap } = buildMapsFromAggBuilders(aggs); + + // eslint-disable-next-line @typescript-eslint/naming-convention + const { sum, last_value, average } = operationDefinitionMap; + + const operations = [sum, last_value, average]; + + operations.forEach((op) => expect(op.getGroupByKey).toBeDefined()); + + const { esAggsIdMap: newIdMap, aggs: newAggs } = dedupeAggs( + aggs, + esAggsIdMap, + aggsToIdsMap, + operations + ); + + expect(newAggs).toHaveLength(3); + + expect(newIdMap).toMatchInlineSnapshot(` + Object { + "col-0-0": Array [ + Object { + "id": "original-0", + }, + Object { + "id": "original-1", + }, + ], + "col-2-2": Array [ + Object { + "id": "original-2", + }, + Object { + "id": "original-3", + }, + ], + "col-4-4": Array [ + Object { + "id": "original-4", + }, + Object { + "id": "original-5", + }, + ], + } + `); + }); + + it('should update any terms order-by reference', () => { + const aggs = [ + 'aggTerms id="0" enabled=true schema="segment" field="clientip" orderBy="3" order="desc" size=5 includeIsRegex=false excludeIsRegex=false otherBucket=true otherBucketLabel="Other" missingBucket=false missingBucketLabel="(missing value)"', + 'aggMedian id="1" enabled=true schema="metric" field="bytes"', + 'aggMedian id="2" enabled=true schema="metric" field="bytes"', + 'aggMedian id="3" enabled=true schema="metric" field="bytes"', + ].map((expression) => buildExpression(parseExpression(expression))); + + const { esAggsIdMap, aggsToIdsMap } = buildMapsFromAggBuilders(aggs); + + const { aggs: newAggs } = dedupeAggs(aggs, esAggsIdMap, aggsToIdsMap, [ + operationDefinitionMap.median, + ]); + + expect(newAggs).toHaveLength(2); + + expect(newAggs[0].functions[0].getArgument('orderBy')?.[0]).toBe('1'); + }); +}); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.ts b/x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.ts new file mode 100644 index 0000000000000..ce5b2b0f41f23 --- /dev/null +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.ts @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AggFunctionsMapping } from '@kbn/data-plugin/public'; +import { + ExpressionAstExpressionBuilder, + ExpressionAstFunctionBuilder, +} from '@kbn/expressions-plugin/common'; +import { GenericOperationDefinition } from './operations'; +import { extractAggId, OriginalColumn } from './to_expression'; + +function groupByKey(items: T[], getKey: (item: T) => string | undefined): Record { + const groups: Record = {}; + + items.forEach((item) => { + const key = getKey(item); + if (key) { + if (!(key in groups)) { + groups[key] = []; + } + groups[key].push(item); + } + }); + + return groups; +} + +/** + * Consolidates duplicate agg expression builders to increase performance + */ +export function dedupeAggs( + _aggs: ExpressionAstExpressionBuilder[], + _esAggsIdMap: Record, + aggExpressionToEsAggsIdMap: Map, + allOperations: GenericOperationDefinition[] +): { + aggs: ExpressionAstExpressionBuilder[]; + esAggsIdMap: Record; +} { + let aggs = [..._aggs]; + const esAggsIdMap = { ..._esAggsIdMap }; + + const aggsByArgs = groupByKey(aggs, (expressionBuilder) => { + for (const operation of allOperations) { + const groupKey = operation.getGroupByKey?.(expressionBuilder); + if (groupKey) { + return `${operation.type}-${groupKey}`; + } + } + }); + + const termsFuncs = aggs + .map((agg) => agg.functions[0]) + .filter((func) => func.name === 'aggTerms') as Array< + ExpressionAstFunctionBuilder + >; + + // collapse each group into a single agg expression builder + Object.values(aggsByArgs).forEach((expressionBuilders) => { + if (expressionBuilders.length <= 1) { + // don't need to optimize if there aren't more than one + return; + } + + const [firstExpressionBuilder, ...restExpressionBuilders] = expressionBuilders; + + // throw away all but the first expression builder + aggs = aggs.filter((aggBuilder) => !restExpressionBuilders.includes(aggBuilder)); + + const firstEsAggsId = aggExpressionToEsAggsIdMap.get(firstExpressionBuilder); + if (firstEsAggsId === undefined) { + throw new Error('Could not find current column ID for expression builder'); + } + + restExpressionBuilders.forEach((expressionBuilder) => { + const currentEsAggsId = aggExpressionToEsAggsIdMap.get(expressionBuilder); + if (currentEsAggsId === undefined) { + throw new Error('Could not find current column ID for expression builder'); + } + + esAggsIdMap[firstEsAggsId].push(...esAggsIdMap[currentEsAggsId]); + + delete esAggsIdMap[currentEsAggsId]; + + termsFuncs.forEach((func) => { + if (func.getArgument('orderBy')?.[0] === extractAggId(currentEsAggsId)) { + func.replaceArgument('orderBy', [extractAggId(firstEsAggsId)]); + } + }); + }); + }); + + return { aggs, esAggsIdMap }; +} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts index c19338dd156f0..481701b1e7824 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts @@ -1220,138 +1220,261 @@ describe('IndexPattern Data Source', () => { expect(ast.chain[1].arguments.timeFields).not.toContain('timefield'); }); - it('should call optimizeEsAggs once per operation for which it is available', () => { - const queryBaseState: IndexPatternPrivateState = { - currentIndexPatternId: '1', - layers: { - first: { - indexPatternId: '1', - columns: { - col1: { - label: 'timestamp', - dataType: 'date', - operationType: 'date_histogram', - sourceField: 'timestamp', - isBucketed: true, - scale: 'interval', - params: { - interval: 'auto', - includeEmptyRows: true, - dropPartials: false, - }, - } as DateHistogramIndexPatternColumn, - col2: { - label: '95th percentile of bytes', - dataType: 'number', - operationType: 'percentile', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { - percentile: 95, + describe('optimizations', () => { + it('should call optimizeEsAggs once per operation for which it is available', () => { + const queryBaseState: IndexPatternPrivateState = { + currentIndexPatternId: '1', + layers: { + first: { + indexPatternId: '1', + columns: { + col1: { + label: 'timestamp', + dataType: 'date', + operationType: 'date_histogram', + sourceField: 'timestamp', + isBucketed: true, + scale: 'interval', + params: { + interval: 'auto', + includeEmptyRows: true, + dropPartials: false, + }, + } as DateHistogramIndexPatternColumn, + col2: { + label: '95th percentile of bytes', + dataType: 'number', + operationType: 'percentile', + sourceField: 'bytes', + isBucketed: false, + scale: 'ratio', + params: { + percentile: 95, + }, + } as PercentileIndexPatternColumn, + col3: { + label: '95th percentile of bytes', + dataType: 'number', + operationType: 'percentile', + sourceField: 'bytes', + isBucketed: false, + scale: 'ratio', + params: { + percentile: 95, + }, + } as PercentileIndexPatternColumn, + }, + columnOrder: ['col1', 'col2', 'col3'], + incompleteColumns: {}, + }, + }, + }; + + const optimizeMock = jest.spyOn(operationDefinitionMap.percentile, 'optimizeEsAggs'); + + indexPatternDatasource.toExpression(queryBaseState, 'first', indexPatterns); + + expect(operationDefinitionMap.percentile.optimizeEsAggs).toHaveBeenCalledTimes(1); + + optimizeMock.mockRestore(); + }); + + it('should update anticipated esAggs column IDs based on the order of the optimized agg expression builders', () => { + const queryBaseState: IndexPatternPrivateState = { + currentIndexPatternId: '1', + layers: { + first: { + indexPatternId: '1', + columns: { + col1: { + label: 'timestamp', + dataType: 'date', + operationType: 'date_histogram', + sourceField: 'timestamp', + isBucketed: true, + scale: 'interval', + params: { + interval: 'auto', + includeEmptyRows: true, + dropPartials: false, + }, + } as DateHistogramIndexPatternColumn, + col2: { + label: '95th percentile of bytes', + dataType: 'number', + operationType: 'percentile', + sourceField: 'bytes', + isBucketed: false, + scale: 'ratio', + params: { + percentile: 95, + }, + } as PercentileIndexPatternColumn, + col3: { + label: 'Count of records', + dataType: 'number', + isBucketed: false, + sourceField: '___records___', + operationType: 'count', + timeScale: 'h', }, - } as PercentileIndexPatternColumn, - col3: { - label: '95th percentile of bytes', - dataType: 'number', - operationType: 'percentile', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { - percentile: 95, + col4: { + label: 'Count of records2', + dataType: 'number', + isBucketed: false, + sourceField: 'bytes', + operationType: 'count', + timeScale: 'h', }, - } as PercentileIndexPatternColumn, + }, + columnOrder: ['col1', 'col2', 'col3', 'col4'], + incompleteColumns: {}, }, - columnOrder: ['col1', 'col2', 'col3'], - incompleteColumns: {}, }, - }, - }; + }; - const optimizeMock = jest.spyOn(operationDefinitionMap.percentile, 'optimizeEsAggs'); + const optimizeMock = jest + .spyOn(operationDefinitionMap.percentile, 'optimizeEsAggs') + .mockImplementation((aggs, esAggsIdMap) => { + // change the order of the aggregations + return { aggs: aggs.reverse(), esAggsIdMap }; + }); - indexPatternDatasource.toExpression(queryBaseState, 'first', indexPatterns); + const ast = indexPatternDatasource.toExpression( + queryBaseState, + 'first', + indexPatterns + ) as Ast; - expect(operationDefinitionMap.percentile.optimizeEsAggs).toHaveBeenCalledTimes(1); + expect(operationDefinitionMap.percentile.optimizeEsAggs).toHaveBeenCalledTimes(1); - optimizeMock.mockRestore(); - }); + const idMap = JSON.parse(ast.chain[2].arguments.idMap as unknown as string); - it('should update anticipated esAggs column IDs based on the order of the optimized agg expression builders', () => { - const queryBaseState: IndexPatternPrivateState = { - currentIndexPatternId: '1', - layers: { - first: { - indexPatternId: '1', - columns: { - col1: { - label: 'timestamp', - dataType: 'date', - operationType: 'date_histogram', - sourceField: 'timestamp', - isBucketed: true, - scale: 'interval', - params: { - interval: 'auto', - includeEmptyRows: true, - dropPartials: false, + expect(Object.keys(idMap)).toEqual(['col-0-3', 'col-1-2', 'col-2-1', 'col-3-0']); + + optimizeMock.mockRestore(); + }); + + it('should deduplicate aggs for supported operations', () => { + const queryBaseState: IndexPatternPrivateState = { + currentIndexPatternId: '1', + layers: { + first: { + indexPatternId: '1', + columns: { + col1: { + label: 'My Op', + dataType: 'string', + isBucketed: true, + operationType: 'terms', + sourceField: 'op', + params: { + size: 5, + orderBy: { + type: 'column', + columnId: 'col4', // col4 will disappear + }, + orderDirection: 'asc', + }, + } as TermsIndexPatternColumn, + col2: { + label: 'Count of records', + dataType: 'number', + isBucketed: false, + sourceField: '___records___', + operationType: 'count', + timeScale: 'h', }, - } as DateHistogramIndexPatternColumn, - col2: { - label: '95th percentile of bytes', - dataType: 'number', - operationType: 'percentile', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { - percentile: 95, + col3: { + label: 'Count of records', + dataType: 'number', + isBucketed: false, + sourceField: '___records___', + operationType: 'count', + timeScale: 'h', + }, + col4: { + label: 'Count of records', + dataType: 'number', + isBucketed: false, + sourceField: '___records___', + operationType: 'count', + timeScale: 'h', }, - } as PercentileIndexPatternColumn, - col3: { - label: 'Count of records', - dataType: 'number', - isBucketed: false, - sourceField: '___records___', - operationType: 'count', - timeScale: 'h', - }, - col4: { - label: 'Count of records2', - dataType: 'number', - isBucketed: false, - sourceField: '___records___', - operationType: 'count', - timeScale: 'h', }, + columnOrder: ['col1', 'col2', 'col3', 'col4'], + incompleteColumns: {}, }, - columnOrder: ['col1', 'col2', 'col3', 'col4'], - incompleteColumns: {}, }, - }, - }; + }; - const optimizeMock = jest - .spyOn(operationDefinitionMap.percentile, 'optimizeEsAggs') - .mockImplementation((aggs, esAggsIdMap) => { - // change the order of the aggregations - return { aggs: aggs.reverse(), esAggsIdMap }; - }); + const ast = indexPatternDatasource.toExpression( + queryBaseState, + 'first', + indexPatterns + ) as Ast; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const idMap = JSON.parse(ast.chain[2].arguments.idMap as unknown as string); - expect(operationDefinitionMap.percentile.optimizeEsAggs).toHaveBeenCalledTimes(1); + const aggs = ast.chain[1].arguments.aggs; - const idMap = JSON.parse(ast.chain[2].arguments.idMap as unknown as string); + expect(aggs).toHaveLength(2); - expect(Object.keys(idMap)).toEqual(['col-0-3', 'col-1-2', 'col-2-1', 'col-3-0']); + // orderby reference updated + expect((aggs[0] as Ast).chain[0].arguments.orderBy[0]).toBe('1'); - optimizeMock.mockRestore(); + expect(idMap).toMatchInlineSnapshot(` + Object { + "col-0-0": Array [ + Object { + "dataType": "string", + "id": "col1", + "isBucketed": true, + "label": "My Op", + "operationType": "terms", + "params": Object { + "orderBy": Object { + "columnId": "col4", + "type": "column", + }, + "orderDirection": "asc", + "size": 5, + }, + "sourceField": "op", + }, + ], + "col-1-1": Array [ + Object { + "dataType": "number", + "id": "col2", + "isBucketed": false, + "label": "Count of records", + "operationType": "count", + "sourceField": "___records___", + "timeScale": "h", + }, + Object { + "dataType": "number", + "id": "col3", + "isBucketed": false, + "label": "Count of records", + "operationType": "count", + "sourceField": "___records___", + "timeScale": "h", + }, + Object { + "dataType": "number", + "id": "col4", + "isBucketed": false, + "label": "Count of records", + "operationType": "count", + "sourceField": "___records___", + "timeScale": "h", + }, + ], + } + `); + }); }); describe('references', () => { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.test.ts new file mode 100644 index 0000000000000..10d26cc3dbbd2 --- /dev/null +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.test.ts @@ -0,0 +1,111 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { buildExpression, parseExpression } from '@kbn/expressions-plugin/common'; +import { operationDefinitionMap } from '.'; + +describe('unique values function', () => { + describe('getGroupByKey', () => { + const getKey = operationDefinitionMap.unique_count.getGroupByKey!; + const expressionToKey = (expression: string) => + getKey(buildExpression(parseExpression(expression))) as string; + describe('generates unique keys based on configuration', () => { + const keys = [ + // group 1 + [ + 'aggCardinality id="0" enabled=true schema="metric" field="bytes" emptyAsNull=false', + 'aggCardinality id="1" enabled=true schema="metric" field="bytes" emptyAsNull=false', + ], + // group 2 + [ + 'aggFilteredMetric id="2" enabled=true schema="metric" \n customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggCardinality id="2-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="3" enabled=true schema="metric" \n customBucket={aggFilter id="3-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggCardinality id="3-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + // group 3 + [ + 'aggFilteredMetric id="4" enabled=true schema="metric" \n customBucket={aggFilter id="4-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "}} \n customMetric={aggCardinality id="4-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="5" enabled=true schema="metric" \n customBucket={aggFilter id="5-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "}} \n customMetric={aggCardinality id="5-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + // group 4 + [ + 'aggFilteredMetric id="6" enabled=true schema="metric" \n customBucket={aggFilter id="6-filter" enabled=true schema="bucket" filter={lucene q="\\"geo.dest: \\\\\\"AL\\\\\\" \\""}} \n customMetric={aggCardinality id="6-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="7" enabled=true schema="metric" \n customBucket={aggFilter id="7-filter" enabled=true schema="bucket" filter={lucene q="\\"geo.dest: \\\\\\"AL\\\\\\" \\""}} \n customMetric={aggCardinality id="7-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + // group 5 + [ + 'aggFilteredMetric id="8" enabled=true schema="metric" \n customBucket={aggFilter id="8-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "} timeWindow="1m"} \n customMetric={aggCardinality id="8-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="9" enabled=true schema="metric" \n customBucket={aggFilter id="9-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "} timeWindow="1m"} \n customMetric={aggCardinality id="9-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + // check emptyAsNull cases + [ + 'aggCardinality id="10" enabled=true schema="metric" field="bytes" emptyAsNull=true', + 'aggCardinality id="11" enabled=true schema="metric" field="bytes" emptyAsNull=true', + ], + [ + 'aggFilteredMetric id="12" enabled=true schema="metric" \n customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggCardinality id="2-metric" enabled=true schema="metric" field="bytes" emptyAsNull=true}', + 'aggFilteredMetric id="13" enabled=true schema="metric" \n customBucket={aggFilter id="3-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggCardinality id="3-metric" enabled=true schema="metric" field="bytes" emptyAsNull=true}', + ], + ].map((group) => group.map(expressionToKey)); + + it.each(keys.map((group, i) => ({ group })))('%#', ({ group: thisGroup }) => { + expect(thisGroup[0]).toEqual(thisGroup[1]); + const otherGroups = keys.filter((group) => group !== thisGroup); + for (const otherGroup of otherGroups) { + expect(thisGroup[0]).not.toEqual(otherGroup[0]); + } + }); + + it('snapshot', () => { + expect(keys).toMatchInlineSnapshot(` + Array [ + Array [ + "aggCardinality-bytes-false-undefined", + "aggCardinality-bytes-false-undefined", + ], + Array [ + "aggCardinality-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"GA\\" ", + "aggCardinality-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"GA\\" ", + ], + Array [ + "aggCardinality-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"AL\\" ", + "aggCardinality-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"AL\\" ", + ], + Array [ + "aggCardinality-filtered-bytes-false-undefined-undefined-lucene-\\"geo.dest: \\\\\\"AL\\\\\\" \\"", + "aggCardinality-filtered-bytes-false-undefined-undefined-lucene-\\"geo.dest: \\\\\\"AL\\\\\\" \\"", + ], + Array [ + "aggCardinality-filtered-bytes-false-1m-undefined-kql-geo.dest: \\"AL\\" ", + "aggCardinality-filtered-bytes-false-1m-undefined-kql-geo.dest: \\"AL\\" ", + ], + Array [ + "aggCardinality-bytes-true-undefined", + "aggCardinality-bytes-true-undefined", + ], + Array [ + "aggCardinality-filtered-bytes-true-undefined-undefined-kql-geo.dest: \\"GA\\" ", + "aggCardinality-filtered-bytes-true-undefined-undefined-kql-geo.dest: \\"GA\\" ", + ], + ] + `); + }); + }); + + it('returns undefined for aggs from different operation classes', () => { + expect( + expressionToKey( + 'aggSum id="0" enabled=true schema="metric" field="bytes" emptyAsNull=false' + ) + ).toBeUndefined(); + expect( + expressionToKey( + 'aggFilteredMetric id="2" enabled=true schema="metric" \n customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggSum id="2-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}' + ) + ).toBeUndefined(); + }); + }); +}); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx index 44474fba14dac..b08fbf8f6c89a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx @@ -26,6 +26,7 @@ import { adjustTimeScaleLabelSuffix } from '../time_scale_utils'; import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils'; import { updateColumnParam } from '../layer_helpers'; import { getColumnReducedTimeRangeError } from '../../reduced_time_range_utils'; +import { getGroupByKey } from './get_group_by_key'; const supportedTypes = new Set([ 'string', @@ -186,6 +187,13 @@ export const cardinalityOperation: OperationDefinition< emptyAsNull: column.params?.emptyAsNull, }).toAst(); }, + getGroupByKey: (agg) => { + return getGroupByKey( + agg, + ['aggCardinality'], + [{ name: 'field' }, { name: 'emptyAsNull', transformer: (val) => String(Boolean(val)) }] + ); + }, onFieldChange: (oldColumn, field) => { return { ...oldColumn, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.test.ts new file mode 100644 index 0000000000000..9f89834548837 --- /dev/null +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.test.ts @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { buildExpression, parseExpression } from '@kbn/expressions-plugin/common'; +import { operationDefinitionMap } from '.'; + +describe('count operation', () => { + describe('getGroupByKey', () => { + const getKey = operationDefinitionMap.count.getGroupByKey!; + const expressionToKey = (expression: string) => + getKey(buildExpression(parseExpression(expression))) as string; + + describe('generates unique keys based on configuration', () => { + const keys = [ + [ + 'aggValueCount id="0" enabled=true schema="metric" field="bytes" emptyAsNull=false', + 'aggValueCount id="1" enabled=true schema="metric" field="bytes" emptyAsNull=false', + ], + [ + 'aggFilteredMetric id="2" enabled=true schema="metric" \n customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggValueCount id="2-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="3" enabled=true schema="metric" \n customBucket={aggFilter id="3-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggValueCount id="3-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + [ + 'aggFilteredMetric id="4" enabled=true schema="metric" \n customBucket={aggFilter id="4-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "}} \n customMetric={aggValueCount id="4-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="5" enabled=true schema="metric" \n customBucket={aggFilter id="5-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "}} \n customMetric={aggValueCount id="5-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + [ + 'aggFilteredMetric id="6" enabled=true schema="metric" \n customBucket={aggFilter id="6-filter" enabled=true schema="bucket" filter={lucene q="\\"geo.dest: \\\\\\"AL\\\\\\" \\""}} \n customMetric={aggValueCount id="6-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="7" enabled=true schema="metric" \n customBucket={aggFilter id="7-filter" enabled=true schema="bucket" filter={lucene q="\\"geo.dest: \\\\\\"AL\\\\\\" \\""}} \n customMetric={aggValueCount id="7-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + [ + 'aggFilteredMetric id="8" enabled=true schema="metric" \n customBucket={aggFilter id="8-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "} timeWindow="1m"} \n customMetric={aggValueCount id="8-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="9" enabled=true schema="metric" \n customBucket={aggFilter id="9-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "} timeWindow="1m"} \n customMetric={aggValueCount id="9-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + [ + 'aggCount id="10" enabled=true schema="metric" emptyAsNull=true', + 'aggCount id="11" enabled=true schema="metric" emptyAsNull=true', + ], + [ + 'aggCount id="10" enabled=true schema="metric" emptyAsNull=false', + 'aggCount id="11" enabled=true schema="metric" emptyAsNull=false', + ], + [ + 'aggValueCount id="12" enabled=true schema="metric" field="agent.keyword" emptyAsNull=false', + 'aggValueCount id="13" enabled=true schema="metric" field="agent.keyword" emptyAsNull=false', + ], + [ + 'aggValueCount id="12" enabled=true schema="metric" field="agent.keyword" emptyAsNull=true', + 'aggValueCount id="13" enabled=true schema="metric" field="agent.keyword" emptyAsNull=true', + ], + ].map((group) => group.map(expressionToKey)); + + it.each(keys.map((group, i) => ({ group })))('%#', ({ group: thisGroup }) => { + expect(thisGroup[0]).toEqual(thisGroup[1]); + const otherGroups = keys.filter((group) => group !== thisGroup); + for (const otherGroup of otherGroups) { + expect(thisGroup[0]).not.toEqual(otherGroup[0]); + } + }); + + it('snapshot', () => { + expect(keys).toMatchInlineSnapshot(` + Array [ + Array [ + "aggValueCount-bytes-false-undefined", + "aggValueCount-bytes-false-undefined", + ], + Array [ + "aggValueCount-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"GA\\" ", + "aggValueCount-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"GA\\" ", + ], + Array [ + "aggValueCount-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"AL\\" ", + "aggValueCount-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"AL\\" ", + ], + Array [ + "aggValueCount-filtered-bytes-false-undefined-undefined-lucene-\\"geo.dest: \\\\\\"AL\\\\\\" \\"", + "aggValueCount-filtered-bytes-false-undefined-undefined-lucene-\\"geo.dest: \\\\\\"AL\\\\\\" \\"", + ], + Array [ + "aggValueCount-filtered-bytes-false-1m-undefined-kql-geo.dest: \\"AL\\" ", + "aggValueCount-filtered-bytes-false-1m-undefined-kql-geo.dest: \\"AL\\" ", + ], + Array [ + "aggCount-undefined-true-undefined", + "aggCount-undefined-true-undefined", + ], + Array [ + "aggCount-undefined-false-undefined", + "aggCount-undefined-false-undefined", + ], + Array [ + "aggValueCount-agent.keyword-false-undefined", + "aggValueCount-agent.keyword-false-undefined", + ], + Array [ + "aggValueCount-agent.keyword-true-undefined", + "aggValueCount-agent.keyword-true-undefined", + ], + ] + `); + }); + }); + + it('returns undefined for aggs from different operation classes', () => { + expect( + expressionToKey( + 'aggSum id="0" enabled=true schema="metric" field="bytes" emptyAsNull=false' + ) + ).toBeUndefined(); + expect( + expressionToKey( + 'aggFilteredMetric id="2" enabled=true schema="metric" \n customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggSum id="2-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}' + ) + ).toBeUndefined(); + }); + }); +}); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx index e2eedc5a2d3c6..4c325e604f64c 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx @@ -26,6 +26,7 @@ import { adjustTimeScaleLabelSuffix } from '../time_scale_utils'; import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils'; import { updateColumnParam } from '../layer_helpers'; import { getColumnReducedTimeRangeError } from '../../reduced_time_range_utils'; +import { getGroupByKey } from './get_group_by_key'; const countLabel = i18n.translate('xpack.lens.indexPattern.countOf', { defaultMessage: 'Count of records', @@ -206,6 +207,14 @@ export const countOperation: OperationDefinition { + return getGroupByKey( + agg, + ['aggCount', 'aggValueCount'], + [{ name: 'field' }, { name: 'emptyAsNull', transformer: (val) => String(Boolean(val)) }] + ); + }, + isTransferable: (column, newIndexPattern) => { const newField = newIndexPattern.getFieldByName(column.sourceField); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/get_group_by_key.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/get_group_by_key.ts new file mode 100644 index 0000000000000..92bcfdb2e7450 --- /dev/null +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/get_group_by_key.ts @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + AggFunctionsMapping, + ExpressionFunctionKql, + ExpressionFunctionLucene, +} from '@kbn/data-plugin/public'; +import { + AnyExpressionFunctionDefinition, + ExpressionAstExpressionBuilder, + ExpressionAstFunctionBuilder, +} from '@kbn/expressions-plugin/common'; +import { Primitive } from 'utility-types'; + +/** + * Computes a group-by key for an agg expression builder based on distinctive expression function arguments + */ +export const getGroupByKey = ( + agg: ExpressionAstExpressionBuilder, + aggNames: string[], + importantExpressionArgs: Array<{ name: string; transformer?: (value: Primitive) => string }> +) => { + const { + functions: [fnBuilder], + } = agg; + + const pieces = []; + + if (aggNames.includes(fnBuilder.name)) { + pieces.push(fnBuilder.name); + + importantExpressionArgs.forEach(({ name, transformer }) => { + const arg = fnBuilder.getArgument(name)?.[0]; + pieces.push(transformer ? transformer(arg) : arg); + }); + + pieces.push(fnBuilder.getArgument('timeShift')?.[0]); + } + + if (fnBuilder.name === 'aggFilteredMetric') { + const metricFnBuilder = fnBuilder.getArgument('customMetric')?.[0].functions[0] as + | ExpressionAstFunctionBuilder + | undefined; + + if (metricFnBuilder && aggNames.includes(metricFnBuilder.name)) { + pieces.push(metricFnBuilder.name); + pieces.push('filtered'); + + const aggFilterFnBuilder = ( + fnBuilder.getArgument('customBucket')?.[0] as ExpressionAstExpressionBuilder + ).functions[0] as ExpressionAstFunctionBuilder; + + importantExpressionArgs.forEach(({ name, transformer }) => { + const arg = metricFnBuilder.getArgument(name)?.[0]; + pieces.push(transformer ? transformer(arg) : arg); + }); + + pieces.push(aggFilterFnBuilder.getArgument('timeWindow')); + pieces.push(fnBuilder.getArgument('timeShift')); + + const filterExpression = aggFilterFnBuilder.getArgument('filter')?.[0] as + | ExpressionAstExpressionBuilder + | undefined; + + if (filterExpression) { + const filterFnBuilder = filterExpression.functions[0] as + | ExpressionAstFunctionBuilder + | undefined; + + pieces.push(filterFnBuilder?.name, filterFnBuilder?.getArgument('q')?.[0]); + } + } + } + + return pieces.length ? pieces.map(String).join('-') : undefined; +}; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts index 31292218078e2..5ce13adbf5ca8 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts @@ -408,6 +408,29 @@ interface BaseOperationDefinitionProps< * Title for the help component */ helpComponentTitle?: string; + + /** + * Used to remove duplicate aggregations for performance reasons. + * + * This method should return a key only if the provided agg is generated by this particular operation. + * The key should represent the important configurations of the operation, such that + * + * const column1 = ...; + * const column2 = ...; // different configuration! + * + * const agg1 = operation.toEsAggsFn(column1); + * const agg2 = operation.toEsAggsFn(column1); + * const agg3 = operation.toEsAggsFn(column2); + * + * const key1 = operation.getGroupByKey(agg1); + * const key2 = operation.getGroupByKey(agg2); + * const key3 = operation.getGroupByKey(agg3); + * + * key1 === key2 + * key1 !== key3 + */ + getGroupByKey?: (agg: ExpressionAstExpressionBuilder) => string | undefined; + /** * Optimizes EsAggs expression. Invoked only once per operation type. */ diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.test.tsx index df219c1e851be..05386492544f4 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.test.tsx @@ -21,6 +21,7 @@ import type { IndexPatternLayer } from '../../types'; import type { IndexPattern } from '../../../types'; import { TermsIndexPatternColumn } from './terms'; import { EuiSwitch, EuiSwitchEvent } from '@elastic/eui'; +import { buildExpression, parseExpression } from '@kbn/expressions-plugin/common'; const uiSettingsMock = {} as IUiSettingsClient; @@ -917,4 +918,108 @@ describe('last_value', () => { ]); }); }); + + describe('getGroupByKey', () => { + const getKey = lastValueOperation.getGroupByKey!; + const expressionToKey = (expression: string) => + getKey(buildExpression(parseExpression(expression))); + + describe('collapses duplicate aggs', () => { + const keys = [ + [ + 'aggFilteredMetric id="0" enabled=true schema="metric" \n customBucket={aggFilter id="0-filter" enabled=true schema="bucket" filter={kql q="bytes: *"}} \n customMetric={aggTopMetrics id="0-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp"}', + 'aggFilteredMetric id="1" enabled=true schema="metric" \n customBucket={aggFilter id="1-filter" enabled=true schema="bucket" filter={kql q="bytes: *"}} \n customMetric={aggTopMetrics id="1-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp"}', + ], + [ + 'aggFilteredMetric id="2" enabled=true schema="metric" \n customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="machine.ram: *"}} \n customMetric={aggTopMetrics id="2-metric" enabled=true schema="metric" field="machine.ram" size=1 sortOrder="desc" sortField="timestamp"}', + 'aggFilteredMetric id="3" enabled=true schema="metric" \n customBucket={aggFilter id="3-filter" enabled=true schema="bucket" filter={kql q="machine.ram: *"}} \n customMetric={aggTopMetrics id="3-metric" enabled=true schema="metric" field="machine.ram" size=1 sortOrder="desc" sortField="timestamp"}', + ], + [ + 'aggFilteredMetric id="4" enabled=true schema="metric" \n customBucket={aggFilter id="4-filter" enabled=true schema="bucket" filter={kql q="machine.ram: *"} timeShift="1h"} \n customMetric={aggTopMetrics id="4-metric" enabled=true schema="metric" field="machine.ram" size=1 sortOrder="desc" sortField="timestamp"} timeShift="1h"', + 'aggFilteredMetric id="5" enabled=true schema="metric" \n customBucket={aggFilter id="5-filter" enabled=true schema="bucket" filter={kql q="machine.ram: *"} timeShift="1h"} \n customMetric={aggTopMetrics id="5-metric" enabled=true schema="metric" field="machine.ram" size=1 sortOrder="desc" sortField="timestamp"} timeShift="1h"', + ], + [ + 'aggFilteredMetric id="6" enabled=true schema="metric" \n customBucket={aggFilter id="6-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggTopMetrics id="6-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp"}', + 'aggFilteredMetric id="7" enabled=true schema="metric" \n customBucket={aggFilter id="7-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggTopMetrics id="7-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp"}', + ], + [ + 'aggFilteredMetric id="8" enabled=true schema="metric" \n customBucket={aggFilter id="8-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "}} \n customMetric={aggTopMetrics id="8-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp"}', + 'aggFilteredMetric id="9" enabled=true schema="metric" \n customBucket={aggFilter id="9-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "}} \n customMetric={aggTopMetrics id="9-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp"}', + ], + [ + 'aggFilteredMetric id="10" enabled=true schema="metric" \n customBucket={aggFilter id="10-filter" enabled=true schema="bucket" filter={lucene q="\\"geo.dest: \\\\\\"AL\\\\\\" \\""}} \n customMetric={aggTopMetrics id="10-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp"}', + 'aggFilteredMetric id="11" enabled=true schema="metric" \n customBucket={aggFilter id="11-filter" enabled=true schema="bucket" filter={lucene q="\\"geo.dest: \\\\\\"AL\\\\\\" \\""}} \n customMetric={aggTopMetrics id="11-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp"}', + ], + [ + 'aggFilteredMetric id="12" enabled=true schema="metric" \n customBucket={aggFilter id="12-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "} timeWindow="1m"} \n customMetric={aggTopMetrics id="12-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp"}', + 'aggFilteredMetric id="13" enabled=true schema="metric" \n customBucket={aggFilter id="13-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "} timeWindow="1m"} \n customMetric={aggTopMetrics id="13-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp"}', + ], + // uses aggTopHit + [ + 'aggFilteredMetric id="14" enabled=true schema="metric" \n customBucket={aggFilter id="14-filter" enabled=true schema="bucket" filter={kql q="bytes: *"}} \n customMetric={aggTopHit id="14-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp" aggregate="concat"}', + 'aggFilteredMetric id="15" enabled=true schema="metric" \n customBucket={aggFilter id="15-filter" enabled=true schema="bucket" filter={kql q="bytes: *"}} \n customMetric={aggTopHit id="15-metric" enabled=true schema="metric" field="bytes" size=1 sortOrder="desc" sortField="timestamp" aggregate="concat"}', + ], + ].map((group) => group.map(expressionToKey)); + + it.each(keys.map((group, i) => ({ group })))('%#', ({ group: thisGroup }) => { + expect(thisGroup[0]).toEqual(thisGroup[1]); + const otherGroups = keys.filter((group) => group !== thisGroup); + for (const otherGroup of otherGroups) { + expect(thisGroup[0]).not.toEqual(otherGroup[0]); + } + }); + + it('snapshot', () => { + expect(keys).toMatchInlineSnapshot(` + Array [ + Array [ + "aggTopMetrics-filtered-bytes-timestamp-undefined-undefined-kql-bytes: *", + "aggTopMetrics-filtered-bytes-timestamp-undefined-undefined-kql-bytes: *", + ], + Array [ + "aggTopMetrics-filtered-machine.ram-timestamp-undefined-undefined-kql-machine.ram: *", + "aggTopMetrics-filtered-machine.ram-timestamp-undefined-undefined-kql-machine.ram: *", + ], + Array [ + "aggTopMetrics-filtered-machine.ram-timestamp-undefined-1h-kql-machine.ram: *", + "aggTopMetrics-filtered-machine.ram-timestamp-undefined-1h-kql-machine.ram: *", + ], + Array [ + "aggTopMetrics-filtered-bytes-timestamp-undefined-undefined-kql-geo.dest: \\"GA\\" ", + "aggTopMetrics-filtered-bytes-timestamp-undefined-undefined-kql-geo.dest: \\"GA\\" ", + ], + Array [ + "aggTopMetrics-filtered-bytes-timestamp-undefined-undefined-kql-geo.dest: \\"AL\\" ", + "aggTopMetrics-filtered-bytes-timestamp-undefined-undefined-kql-geo.dest: \\"AL\\" ", + ], + Array [ + "aggTopMetrics-filtered-bytes-timestamp-undefined-undefined-lucene-\\"geo.dest: \\\\\\"AL\\\\\\" \\"", + "aggTopMetrics-filtered-bytes-timestamp-undefined-undefined-lucene-\\"geo.dest: \\\\\\"AL\\\\\\" \\"", + ], + Array [ + "aggTopMetrics-filtered-bytes-timestamp-1m-undefined-kql-geo.dest: \\"AL\\" ", + "aggTopMetrics-filtered-bytes-timestamp-1m-undefined-kql-geo.dest: \\"AL\\" ", + ], + Array [ + "aggTopHit-filtered-bytes-timestamp-undefined-undefined-kql-bytes: *", + "aggTopHit-filtered-bytes-timestamp-undefined-undefined-kql-bytes: *", + ], + ] + `); + }); + }); + + it('returns undefined for aggs from different operation classes', () => { + expect( + expressionToKey( + 'aggSum id="0" enabled=true schema="metric" field="bytes" emptyAsNull=false' + ) + ).toBeUndefined(); + expect( + expressionToKey( + 'aggFilteredMetric id="2" enabled=true schema="metric" \n customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggSum id="2-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}' + ) + ).toBeUndefined(); + }); + }); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx index b7fd3a40fdbff..2709d22b2a323 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx @@ -33,6 +33,7 @@ import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils'; import { isScriptedField } from './terms/helpers'; import { FormRow } from './shared_components/form_row'; import { getColumnReducedTimeRangeError } from '../../reduced_time_range_utils'; +import { getGroupByKey } from './get_group_by_key'; function ofName(name: string, timeShift: string | undefined, reducedTimeRange: string | undefined) { return adjustTimeScaleLabelSuffix( @@ -258,6 +259,14 @@ export const lastValueOperation: OperationDefinition< ).toAst(); }, + getGroupByKey: (agg) => { + return getGroupByKey( + agg, + ['aggTopHit', 'aggTopMetrics'], + [{ name: 'field' }, { name: 'sortField' }] + ); + }, + isTransferable: (column, newIndexPattern) => { const newField = newIndexPattern.getFieldByName(column.sourceField); const newTimeField = newIndexPattern.getFieldByName(column.params.sortField); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.test.ts new file mode 100644 index 0000000000000..b98125d0bbd2b --- /dev/null +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.test.ts @@ -0,0 +1,132 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { buildExpression, parseExpression } from '@kbn/expressions-plugin/common'; +import { operationDefinitionMap } from '.'; + +const sumOperation = operationDefinitionMap.sum; + +describe('metrics', () => { + describe('getGroupByKey', () => { + const getKey = sumOperation.getGroupByKey!; + const expressionToKey = (expression: string) => + getKey(buildExpression(parseExpression(expression))); + + describe('should collapse filtered aggs with matching parameters', () => { + const keys = [ + [ + 'aggSum id="0" enabled=true schema="metric" field="bytes" emptyAsNull=false', + 'aggSum id="1" enabled=true schema="metric" field="bytes" emptyAsNull=false', + ], + [ + 'aggSum id="2" enabled=true schema="metric" field="bytes" emptyAsNull=true', + 'aggSum id="3" enabled=true schema="metric" field="bytes" emptyAsNull=true', + ], + [ + 'aggSum id="4" enabled=true schema="metric" field="hour_of_day" emptyAsNull=false', + 'aggSum id="5" enabled=true schema="metric" field="hour_of_day" emptyAsNull=false', + ], + [ + 'aggSum id="6" enabled=true schema="metric" field="machine.ram" timeShift="1h" emptyAsNull=false', + 'aggSum id="7" enabled=true schema="metric" field="machine.ram" timeShift="1h" emptyAsNull=false', + ], + [ + 'aggSum id="8" enabled=true schema="metric" field="machine.ram" timeShift="2h" emptyAsNull=false', + 'aggSum id="9" enabled=true schema="metric" field="machine.ram" timeShift="2h" emptyAsNull=false', + ], + [ + 'aggFilteredMetric id="10" enabled=true schema="metric" \n customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggSum id="2-metric" enabled=true schema="metric" field="bytes" emptyAsNull=true}', + 'aggFilteredMetric id="11" enabled=true schema="metric" \n customBucket={aggFilter id="3-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggSum id="3-metric" enabled=true schema="metric" field="bytes" emptyAsNull=true}', + ], + [ + 'aggFilteredMetric id="12" enabled=true schema="metric" \n customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggSum id="2-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="13" enabled=true schema="metric" \n customBucket={aggFilter id="3-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggSum id="3-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + [ + 'aggFilteredMetric id="14" enabled=true schema="metric" \n customBucket={aggFilter id="4-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "}} \n customMetric={aggSum id="4-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="15" enabled=true schema="metric" \n customBucket={aggFilter id="5-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "}} \n customMetric={aggSum id="5-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + [ + 'aggFilteredMetric id="16" enabled=true schema="metric" \n customBucket={aggFilter id="6-filter" enabled=true schema="bucket" filter={lucene q="\\"geo.dest: \\\\\\"AL\\\\\\" \\""}} \n customMetric={aggSum id="6-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="17" enabled=true schema="metric" \n customBucket={aggFilter id="7-filter" enabled=true schema="bucket" filter={lucene q="\\"geo.dest: \\\\\\"AL\\\\\\" \\""}} \n customMetric={aggSum id="7-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + [ + 'aggFilteredMetric id="18" enabled=true schema="metric" \n customBucket={aggFilter id="8-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "} timeWindow="1m"} \n customMetric={aggSum id="8-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + 'aggFilteredMetric id="19" enabled=true schema="metric" \n customBucket={aggFilter id="9-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"AL\\" "} timeWindow="1m"} \n customMetric={aggSum id="9-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}', + ], + ].map((group) => group.map(expressionToKey)); + + it.each(keys.map((group, i) => ({ group })))('%#', ({ group: thisGroup }) => { + expect(thisGroup[0]).toEqual(thisGroup[1]); + const otherGroups = keys.filter((group) => group !== thisGroup); + for (const otherGroup of otherGroups) { + expect(thisGroup[0]).not.toEqual(otherGroup[0]); + } + }); + + it('snapshot', () => { + expect(keys).toMatchInlineSnapshot(` + Array [ + Array [ + "aggSum-bytes-false-undefined", + "aggSum-bytes-false-undefined", + ], + Array [ + "aggSum-bytes-true-undefined", + "aggSum-bytes-true-undefined", + ], + Array [ + "aggSum-hour_of_day-false-undefined", + "aggSum-hour_of_day-false-undefined", + ], + Array [ + "aggSum-machine.ram-false-1h", + "aggSum-machine.ram-false-1h", + ], + Array [ + "aggSum-machine.ram-false-2h", + "aggSum-machine.ram-false-2h", + ], + Array [ + "aggSum-filtered-bytes-true-undefined-undefined-kql-geo.dest: \\"GA\\" ", + "aggSum-filtered-bytes-true-undefined-undefined-kql-geo.dest: \\"GA\\" ", + ], + Array [ + "aggSum-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"GA\\" ", + "aggSum-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"GA\\" ", + ], + Array [ + "aggSum-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"AL\\" ", + "aggSum-filtered-bytes-false-undefined-undefined-kql-geo.dest: \\"AL\\" ", + ], + Array [ + "aggSum-filtered-bytes-false-undefined-undefined-lucene-\\"geo.dest: \\\\\\"AL\\\\\\" \\"", + "aggSum-filtered-bytes-false-undefined-undefined-lucene-\\"geo.dest: \\\\\\"AL\\\\\\" \\"", + ], + Array [ + "aggSum-filtered-bytes-false-1m-undefined-kql-geo.dest: \\"AL\\" ", + "aggSum-filtered-bytes-false-1m-undefined-kql-geo.dest: \\"AL\\" ", + ], + ] + `); + }); + }); + + it('returns undefined for aggs from different operation classes', () => { + expect( + expressionToKey( + 'aggCardinality id="0" enabled=true schema="metric" field="bytes" emptyAsNull=false' + ) + ).toBeUndefined(); + expect( + expressionToKey( + 'aggFilteredMetric id="2" enabled=true schema="metric" \n customBucket={aggFilter id="2-filter" enabled=true schema="bucket" filter={kql q="geo.dest: \\"GA\\" "}} \n customMetric={aggCardinality id="2-metric" enabled=true schema="metric" field="bytes" emptyAsNull=false}' + ) + ).toBeUndefined(); + }); + }); +}); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx index 9b8f790e51b90..09dc8576a042a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx @@ -28,6 +28,7 @@ import { adjustTimeScaleLabelSuffix } from '../time_scale_utils'; import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils'; import { updateColumnParam } from '../layer_helpers'; import { getColumnReducedTimeRangeError } from '../../reduced_time_range_utils'; +import { getGroupByKey } from './get_group_by_key'; type MetricColumn = FieldBasedIndexPatternColumn & { operationType: T; @@ -198,6 +199,14 @@ function buildMetricOperation>({ ...aggConfigParams, }).toAst(); }, + getGroupByKey: (agg) => { + return getGroupByKey( + agg, + [typeToFn[type]], + [{ name: 'field' }, { name: 'emptyAsNull', transformer: (val) => String(Boolean(val)) }] + ); + }, + getErrorMessage: (layer, columnId, indexPattern) => combineErrorMessages([ getInvalidFieldMessage( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.test.tsx index f72342f79bfc6..77434d7ecc7ad 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.test.tsx @@ -28,6 +28,7 @@ import { } from '@kbn/expressions-plugin/public'; import type { OriginalColumn } from '../../to_expression'; import { IndexPattern } from '../../../types'; +import faker from 'faker'; jest.mock('lodash', () => { const original = jest.requireActual('lodash'); @@ -234,7 +235,7 @@ describe('percentile', () => { const aggs = [ // group 1 makeEsAggBuilder('aggSinglePercentile', { - id: 1, + id: '1', enabled: true, schema: 'metric', field: field1, @@ -242,7 +243,7 @@ describe('percentile', () => { timeShift: undefined, }), makeEsAggBuilder('aggSinglePercentile', { - id: 2, + id: '2', enabled: true, schema: 'metric', field: field1, @@ -250,7 +251,7 @@ describe('percentile', () => { timeShift: undefined, }), makeEsAggBuilder('aggSinglePercentile', { - id: 3, + id: '3', enabled: true, schema: 'metric', field: field1, @@ -259,7 +260,7 @@ describe('percentile', () => { }), // group 2 makeEsAggBuilder('aggSinglePercentile', { - id: 4, + id: '4', enabled: true, schema: 'metric', field: field2, @@ -267,7 +268,7 @@ describe('percentile', () => { timeShift: undefined, }), makeEsAggBuilder('aggSinglePercentile', { - id: 5, + id: '5', enabled: true, schema: 'metric', field: field2, @@ -276,7 +277,7 @@ describe('percentile', () => { }), // group 3 makeEsAggBuilder('aggSinglePercentile', { - id: 6, + id: '6', enabled: true, schema: 'metric', field: field2, @@ -284,7 +285,7 @@ describe('percentile', () => { timeShift: timeShift1, }), makeEsAggBuilder('aggSinglePercentile', { - id: 7, + id: '7', enabled: true, schema: 'metric', field: field2, @@ -293,7 +294,7 @@ describe('percentile', () => { }), // group 4 makeEsAggBuilder('aggSinglePercentile', { - id: 8, + id: '8', enabled: true, schema: 'metric', field: field2, @@ -301,7 +302,7 @@ describe('percentile', () => { timeShift: timeShift2, }), makeEsAggBuilder('aggSinglePercentile', { - id: 9, + id: '9', enabled: true, schema: 'metric', field: field2, @@ -344,7 +345,7 @@ describe('percentile', () => { "foo", ], "id": Array [ - 1, + "1", ], "percents": Array [ 10, @@ -381,7 +382,7 @@ describe('percentile', () => { "bar", ], "id": Array [ - 4, + "4", ], "percents": Array [ 10, @@ -417,7 +418,7 @@ describe('percentile', () => { "bar", ], "id": Array [ - 6, + "6", ], "percents": Array [ 50, @@ -456,7 +457,7 @@ describe('percentile', () => { "bar", ], "id": Array [ - 8, + "8", ], "percents": Array [ 70, @@ -544,7 +545,7 @@ describe('percentile', () => { const aggs = [ // group 1 makeEsAggBuilder('aggSinglePercentile', { - id: 1, + id: '1', enabled: true, schema: 'metric', field: field1, @@ -552,7 +553,7 @@ describe('percentile', () => { timeShift: undefined, }), makeEsAggBuilder('aggSinglePercentile', { - id: 2, + id: '2', enabled: true, schema: 'metric', field: field1, @@ -560,7 +561,7 @@ describe('percentile', () => { timeShift: undefined, }), makeEsAggBuilder('aggSinglePercentile', { - id: 4, + id: '4', enabled: true, schema: 'metric', field: field2, @@ -568,7 +569,7 @@ describe('percentile', () => { timeShift: undefined, }), makeEsAggBuilder('aggSinglePercentile', { - id: 3, + id: '3', enabled: true, schema: 'metric', field: field1, @@ -609,17 +610,87 @@ describe('percentile', () => { `); }); + it('should update order-by references for any terms columns', () => { + const field1 = 'foo'; + const field2 = 'bar'; + const percentile = faker.random.number(100); + + const aggs = [ + makeEsAggBuilder('aggTerms', { + id: '1', + enabled: true, + schema: 'metric', + field: field1, + orderBy: '4', + timeShift: undefined, + }), + makeEsAggBuilder('aggTerms', { + id: '2', + enabled: true, + schema: 'metric', + field: field1, + orderBy: '6', + timeShift: undefined, + }), + makeEsAggBuilder('aggSinglePercentile', { + id: '3', + enabled: true, + schema: 'metric', + field: field1, + percentile, + timeShift: undefined, + }), + makeEsAggBuilder('aggSinglePercentile', { + id: '4', + enabled: true, + schema: 'metric', + field: field1, + percentile, + timeShift: undefined, + }), + makeEsAggBuilder('aggSinglePercentile', { + id: '5', + enabled: true, + schema: 'metric', + field: field2, + percentile, + timeShift: undefined, + }), + makeEsAggBuilder('aggSinglePercentile', { + id: '6', + enabled: true, + schema: 'metric', + field: field2, + percentile, + timeShift: undefined, + }), + ]; + + const { esAggsIdMap, aggsToIdsMap } = buildMapsFromAggBuilders(aggs); + + const { aggs: newAggs } = percentileOperation.optimizeEsAggs!( + aggs, + esAggsIdMap, + aggsToIdsMap + ); + + expect(newAggs.length).toBe(4); + + expect(newAggs[0].functions[0].getArgument('orderBy')?.[0]).toBe(`3.${percentile}`); + expect(newAggs[1].functions[0].getArgument('orderBy')?.[0]).toBe(`5.${percentile}`); + }); + it("shouldn't touch non-percentile aggs or single percentiles with no siblings", () => { const aggs = [ makeEsAggBuilder('aggSinglePercentile', { - id: 1, + id: '1', enabled: true, schema: 'metric', field: 'foo', percentile: 30, }), makeEsAggBuilder('aggMax', { - id: 1, + id: '1', enabled: true, schema: 'metric', field: 'bar', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx index 88b941b2bb7c9..3bc91b91ed3d6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx @@ -13,6 +13,7 @@ import { buildExpression, buildExpressionFunction, ExpressionAstExpressionBuilder, + ExpressionAstFunctionBuilder, } from '@kbn/expressions-plugin/public'; import { AggExpressionFunctionArgs } from '@kbn/data-plugin/common'; import { OperationDefinition } from '.'; @@ -195,6 +196,12 @@ export const percentileOperation: OperationDefinition< } }); + const termsFuncs = aggs + .map((agg) => agg.functions[0]) + .filter((func) => func.name === 'aggTerms') as Array< + ExpressionAstFunctionBuilder + >; + // collapse them into a single esAggs expression builder Object.values(percentileExpressionsByArgs).forEach((expressionBuilders) => { if (expressionBuilders.length <= 1) { @@ -224,6 +231,7 @@ export const percentileOperation: OperationDefinition< const percentileToBuilder: Record = {}; for (const builder of expressionBuilders) { const percentile = builder.functions[0].getArgument('percentile')![0] as number; + if (percentile in percentileToBuilder) { // found a duplicate percentile so let's optimize @@ -248,6 +256,13 @@ export const percentileOperation: OperationDefinition< percentileToBuilder[percentile] = builder; aggPercentilesConfig.percents!.push(percentile); } + + // update any terms order-bys + termsFuncs.forEach((func) => { + if (func.getArgument('orderBy')?.[0] === builder.functions[0].getArgument('id')?.[0]) { + func.replaceArgument('orderBy', [`${esAggsColumnId}.${percentile}`]); + } + }); } const multiPercentilesAst = buildExpressionFunction( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.test.ts index 703156418b364..c544121a935f5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.test.ts @@ -16,11 +16,9 @@ import { getDisallowedTermsMessage, getMultiTermsScriptedFieldErrorMessage, isSortableByColumn, - computeOrderForMultiplePercentiles, } from './helpers'; import { ReferenceBasedIndexPatternColumn } from '../column_types'; import type { PercentileRanksIndexPatternColumn } from '../percentile_ranks'; -import type { PercentileIndexPatternColumn } from '../percentile'; import { MULTI_KEY_VISUAL_SEPARATOR } from './constants'; import { MovingAverageIndexPatternColumn } from '../calculations'; @@ -410,138 +408,6 @@ describe('getDisallowedTermsMessage()', () => { }); }); -describe('computeOrderForMultiplePercentiles()', () => { - it('should return null for no percentile orderColumn', () => { - expect( - computeOrderForMultiplePercentiles( - { - label: 'Percentile rank (1024.5) of bytes', - dataType: 'number', - operationType: 'percentile_rank', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { value: 1024.5 }, - } as PercentileRanksIndexPatternColumn, - getLayer(getStringBasedOperationColumn(), [ - { - label: 'Percentile rank (1024.5) of bytes', - dataType: 'number', - operationType: 'percentile_rank', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { value: 1024.5 }, - } as PercentileRanksIndexPatternColumn, - ]), - ['col1', 'col2'] - ) - ).toBeNull(); - }); - - it('should return null for single percentile', () => { - expect( - computeOrderForMultiplePercentiles( - { - label: 'Percentile 95 of bytes', - dataType: 'number', - operationType: 'percentile', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { percentile: 95 }, - } as PercentileIndexPatternColumn, - getLayer(getStringBasedOperationColumn(), [ - { - label: 'Percentile 95 of bytes', - dataType: 'number', - operationType: 'percentile', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { percentile: 95 }, - } as PercentileIndexPatternColumn, - ]), - ['col1', 'col2'] - ) - ).toBeNull(); - }); - - it('should return correct orderBy for multiple percentile on the same field', () => { - expect( - computeOrderForMultiplePercentiles( - { - label: 'Percentile 95 of bytes', - dataType: 'number', - operationType: 'percentile', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { percentile: 95 }, - } as PercentileIndexPatternColumn, - getLayer(getStringBasedOperationColumn(), [ - { - label: 'Percentile 95 of bytes', - dataType: 'number', - operationType: 'percentile', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { percentile: 95 }, - } as PercentileIndexPatternColumn, - { - label: 'Percentile 65 of bytes', - dataType: 'number', - operationType: 'percentile', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { percentile: 65 }, - } as PercentileIndexPatternColumn, - ]), - ['col1', 'col2', 'col3'] - ) - ).toBe('1.95'); - }); - - it('should return null for multiple percentile on different field', () => { - expect( - computeOrderForMultiplePercentiles( - { - label: 'Percentile 95 of bytes', - dataType: 'number', - operationType: 'percentile', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { percentile: 95 }, - } as PercentileIndexPatternColumn, - getLayer(getStringBasedOperationColumn(), [ - { - label: 'Percentile 95 of bytes', - dataType: 'number', - operationType: 'percentile', - sourceField: 'bytes', - isBucketed: false, - scale: 'ratio', - params: { percentile: 95 }, - } as PercentileIndexPatternColumn, - { - label: 'Percentile 65 of geo', - dataType: 'number', - operationType: 'percentile', - sourceField: 'geo', - isBucketed: false, - scale: 'ratio', - params: { percentile: 65 }, - } as PercentileIndexPatternColumn, - ]), - ['col1', 'col2', 'col3'] - ) - ).toBeNull(); - }); -}); - describe('isSortableByColumn()', () => { it('should sort by the given column', () => { expect( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.ts index 7139a8effd4ca..77d52664c0e54 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/helpers.ts @@ -21,7 +21,6 @@ import type { FiltersIndexPatternColumn } from '..'; import type { TermsIndexPatternColumn } from './types'; import type { LastValueIndexPatternColumn } from '../last_value'; import type { PercentileRanksIndexPatternColumn } from '../percentile_ranks'; -import type { PercentileIndexPatternColumn } from '../percentile'; import type { IndexPatternLayer } from '../../../types'; import { MULTI_KEY_VISUAL_SEPARATOR, supportedTypes } from './constants'; @@ -241,31 +240,6 @@ export function isPercentileRankSortable(column: GenericIndexPatternColumn) { ); } -export function computeOrderForMultiplePercentiles( - column: GenericIndexPatternColumn, - layer: IndexPatternLayer, - orderedColumnIds: string[] -) { - // compute the percentiles orderBy correctly for multiple percentiles - if (column.operationType === 'percentile') { - const percentileColumns = []; - for (const [key, value] of Object.entries(layer.columns)) { - if ( - value.operationType === 'percentile' && - (value as PercentileIndexPatternColumn).sourceField === - (column as PercentileIndexPatternColumn).sourceField - ) { - percentileColumns.push(key); - } - } - if (percentileColumns.length > 1) { - const parentColumn = String(orderedColumnIds.indexOf(percentileColumns[0])); - return `${parentColumn}.${(column as PercentileIndexPatternColumn).params?.percentile}`; - } - } - return null; -} - export function isSortableByColumn(layer: IndexPatternLayer, columnId: string) { const column = layer.columns[columnId]; return ( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx index 3f8496d31f678..9017e91bff089 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx @@ -49,7 +49,6 @@ import { getFieldsByValidationState, isSortableByColumn, isPercentileRankSortable, - computeOrderForMultiplePercentiles, } from './helpers'; import { DEFAULT_MAX_DOC_COUNT, @@ -266,7 +265,7 @@ export const termsOperation: OperationDefinition< max_doc_count: column.params.orderBy.maxDocCount, }).toAst(); } - let orderBy: string = '_key'; + let orderBy = '_key'; if (column.params?.orderBy.type === 'column') { const orderColumn = layer.columns[column.params.orderBy.columnId]; @@ -275,14 +274,6 @@ export const termsOperation: OperationDefinition< if (!isPercentileRankSortable(orderColumn)) { orderBy = '_key'; } - - const orderByMultiplePercentiles = computeOrderForMultiplePercentiles( - orderColumn, - layer, - orderedColumnIds - ); - - orderBy = orderByMultiplePercentiles ?? orderBy; } // To get more accurate results, we set shard_size to a minimum of 1000 diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx index 8c3b7f90d57d3..584498189fd06 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx @@ -350,49 +350,6 @@ describe('terms', () => { ); }); - it('should reflect correct orderBy for multiple percentiles', () => { - const newLayer = { - ...layer, - columns: { - ...layer.columns, - col2: { - ...layer.columns.col2, - operationType: 'percentile', - params: { - percentile: 95, - }, - }, - col3: { - ...layer.columns.col2, - operationType: 'percentile', - params: { - percentile: 65, - }, - }, - }, - }; - const termsColumn = layer.columns.col1 as TermsIndexPatternColumn; - const esAggsFn = termsOperation.toEsAggsFn( - { - ...termsColumn, - params: { ...termsColumn.params, orderBy: { type: 'column', columnId: 'col3' } }, - }, - 'col1', - {} as IndexPattern, - newLayer, - uiSettingsMock, - ['col1', 'col2', 'col3'] - ); - expect(esAggsFn).toEqual( - expect.objectContaining({ - function: 'aggTerms', - arguments: expect.objectContaining({ - orderBy: ['1.65'], - }), - }) - ); - }); - it('should not enable missing bucket if other bucket is not set', () => { const termsColumn = layer.columns.col1 as TermsIndexPatternColumn; const esAggsFn = termsOperation.toEsAggsFn( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts b/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts index bf816e5891486..72cb2a2ab729e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts @@ -27,6 +27,7 @@ import { DateHistogramIndexPatternColumn, RangeIndexPatternColumn } from './oper import { FormattedIndexPatternColumn } from './operations/definitions/column_types'; import { isColumnFormatted, isColumnOfType } from './operations/definitions/helpers'; import type { IndexPattern, IndexPatternMap } from '../types'; +import { dedupeAggs } from './dedupe_aggs'; export type OriginalColumn = { id: string } & GenericIndexPatternColumn; @@ -40,7 +41,7 @@ declare global { } // esAggs column ID manipulation functions -const extractEsAggId = (id: string) => id.split('.')[0].split('-')[2]; +export const extractAggId = (id: string) => id.split('.')[0].split('-')[2]; const updatePositionIndex = (currentId: string, newIndex: number) => { const [fullId, percentile] = currentId.split('.'); const idParts = fullId.split('-'); @@ -214,10 +215,18 @@ function getExpressionForLayer( ); } - uniq(esAggEntries.map(([_, column]) => column.operationType)).forEach((type) => { - const optimizeAggs = operationDefinitionMap[type].optimizeEsAggs?.bind( - operationDefinitionMap[type] - ); + const allOperations = uniq( + esAggEntries.map(([_, column]) => operationDefinitionMap[column.operationType]) + ); + + // De-duplicate aggs for supported operations + const dedupedResult = dedupeAggs(aggs, esAggsIdMap, aggExpressionToEsAggsIdMap, allOperations); + aggs = dedupedResult.aggs; + esAggsIdMap = dedupedResult.esAggsIdMap; + + // Apply any operation-specific custom optimizations + allOperations.forEach((operation) => { + const optimizeAggs = operation.optimizeEsAggs?.bind(operation); if (optimizeAggs) { const { aggs: newAggs, esAggsIdMap: newIdMap } = optimizeAggs( aggs, @@ -257,7 +266,7 @@ function getExpressionForLayer( const esAggsIds = Object.keys(esAggsIdMap); aggs.forEach((builder) => { const esAggId = builder.functions[0].getArgument('id')?.[0]; - const matchingEsAggColumnIds = esAggsIds.filter((id) => extractEsAggId(id) === esAggId); + const matchingEsAggColumnIds = esAggsIds.filter((id) => extractAggId(id) === esAggId); matchingEsAggColumnIds.forEach((currentId) => { const currentColumn = esAggsIdMap[currentId][0]; From 0edfb0b1f3407d9802069a2ddfddbed5f6597dfd Mon Sep 17 00:00:00 2001 From: Kaarina Tungseth Date: Mon, 26 Sep 2022 14:34:32 -0500 Subject: [PATCH 34/51] [DOCS] Moves advanced settings page (#141834) --- docs/user/management.asciidoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/user/management.asciidoc b/docs/user/management.asciidoc index 908cdc792431c..02261d062e826 100644 --- a/docs/user/management.asciidoc +++ b/docs/user/management.asciidoc @@ -176,8 +176,6 @@ see the https://www.elastic.co/subscriptions[subscription page]. -- -include::{kib-repo-dir}/management/advanced-options.asciidoc[] - include::{kib-repo-dir}/management/cases/index.asciidoc[] include::{kib-repo-dir}/management/action-types.asciidoc[] @@ -196,6 +194,10 @@ include::security/index.asciidoc[] include::{kib-repo-dir}/spaces/index.asciidoc[] +include::{kib-repo-dir}/management/advanced-options.asciidoc[] + include::{kib-repo-dir}/management/managing-tags.asciidoc[] include::{kib-repo-dir}/management/watcher-ui/index.asciidoc[] + + From c494c0402f6bbd2f8b12fcca572ba96ce541a2f8 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 26 Sep 2022 14:50:28 -0500 Subject: [PATCH 35/51] [stack_functional_integration] remove esArchiver service (#141842) --- .../services/es_archiver.ts | 1 + .../lib/config/schema.ts | 7 ++++ ...onfig.stack_functional_integration_base.js | 9 +++-- .../services/es_archiver.js | 40 ------------------- .../services/index.js | 14 ------- 5 files changed, 14 insertions(+), 57 deletions(-) delete mode 100644 x-pack/test/stack_functional_integration/services/es_archiver.js delete mode 100644 x-pack/test/stack_functional_integration/services/index.js diff --git a/packages/kbn-ftr-common-functional-services/services/es_archiver.ts b/packages/kbn-ftr-common-functional-services/services/es_archiver.ts index 8a81297bf1784..abb0b89544bc1 100644 --- a/packages/kbn-ftr-common-functional-services/services/es_archiver.ts +++ b/packages/kbn-ftr-common-functional-services/services/es_archiver.ts @@ -18,6 +18,7 @@ export function EsArchiverProvider({ getService }: FtrProviderContext): EsArchiv const retry = getService('retry'); const esArchiver = new EsArchiver({ + baseDir: config.get('esArchiver.baseDirectory'), client, log, kbnClient: kibanaServer, diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts index ce44dd3cc0496..6d5dc75b8d969 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts @@ -260,6 +260,13 @@ export const schema = Joi.object() // definition of apps that work with `common.navigateToApp()` apps: Joi.object().pattern(ID_PATTERN, appUrlPartsSchema()).default(), + // settings for the saved objects svc + esArchiver: Joi.object() + .keys({ + baseDirectory: Joi.string().optional(), + }) + .default(), + // settings for the saved objects svc kbnArchiver: Joi.object() .keys({ diff --git a/x-pack/test/stack_functional_integration/configs/config.stack_functional_integration_base.js b/x-pack/test/stack_functional_integration/configs/config.stack_functional_integration_base.js index 1658bcbf6cd35..00dd89acbc9ef 100644 --- a/x-pack/test/stack_functional_integration/configs/config.stack_functional_integration_base.js +++ b/x-pack/test/stack_functional_integration/configs/config.stack_functional_integration_base.js @@ -12,7 +12,6 @@ import { REPO_ROOT } from '@kbn/utils'; import chalk from 'chalk'; import { esTestConfig, kbnTestConfig } from '@kbn/test'; import { TriggersActionsPageProvider } from '../../functional_with_es_ssl/page_objects/triggers_actions_ui_page'; -import { services } from '../services'; const log = new ToolingLog({ level: 'info', @@ -28,13 +27,14 @@ export default async ({ readConfigFile }) => { const xpackFunctionalConfig = await readConfigFile( require.resolve('../../functional/config.base.js') ); - const externalConf = consumeState(resolve(__dirname, stateFilePath)); + const externalConf = consumeState(resolve(__dirname, stateFilePath)) ?? { + TESTS_LIST: 'alerts', + }; process.env.stack_functional_integration = true; logAll(log); const settings = { ...xpackFunctionalConfig.getAll(), - services, pageObjects: { triggersActionsUI: TriggersActionsPageProvider, ...xpackFunctionalConfig.get('pageObjects'), @@ -53,6 +53,9 @@ export default async ({ readConfigFile }) => { ...xpackFunctionalConfig.get('kbnTestServer'), serverArgs: [...xpackFunctionalConfig.get('kbnTestServer.serverArgs')], }, + esArchiver: { + baseDirectory: INTEGRATION_TEST_ROOT, + }, testFiles: tests(externalConf.TESTS_LIST).map(prepend).map(logTest), // testFiles: ['alerts'].map(prepend).map(logTest), // If we need to do things like disable animations, we can do it in configure_start_kibana.sh, in the provisioner...which lives in the integration-test private repo diff --git a/x-pack/test/stack_functional_integration/services/es_archiver.js b/x-pack/test/stack_functional_integration/services/es_archiver.js deleted file mode 100644 index 821cf72e2c6bc..0000000000000 --- a/x-pack/test/stack_functional_integration/services/es_archiver.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import Path from 'path'; - -import { EsArchiver } from '@kbn/es-archiver'; -import { REPO_ROOT } from '@kbn/utils'; - -import { KibanaServer } from '@kbn/ftr-common-functional-services'; - -const INTEGRATION_TEST_ROOT = - process.env.WORKSPACE || Path.resolve(REPO_ROOT, '../integration-test'); - -export function EsArchiverProvider({ getService }) { - const config = getService('config'); - const client = getService('es'); - const log = getService('log'); - const kibanaServer = getService('kibanaServer'); - const retry = getService('retry'); - - const esArchiver = new EsArchiver({ - baseDir: INTEGRATION_TEST_ROOT, - client, - log, - kbnClient: kibanaServer, - }); - - KibanaServer.extendEsArchiver({ - esArchiver, - kibanaServer, - retry, - defaults: config.get('uiSettings.defaults'), - }); - - return esArchiver; -} diff --git a/x-pack/test/stack_functional_integration/services/index.js b/x-pack/test/stack_functional_integration/services/index.js deleted file mode 100644 index e311dd8b38f7e..0000000000000 --- a/x-pack/test/stack_functional_integration/services/index.js +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { services as xpackFunctionalServices } from '../../functional/services'; -import { EsArchiverProvider } from './es_archiver'; - -export const services = { - ...xpackFunctionalServices, - esArchiver: EsArchiverProvider, -}; From ab06783505956cca82ead6708bd00c2b078f341c Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Mon, 26 Sep 2022 12:52:17 -0700 Subject: [PATCH 36/51] Update CODEOWNERS for app-services test files (#141841) --- .github/CODEOWNERS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 51323cee4a112..480acad008f00 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -84,10 +84,12 @@ /x-pack/examples/ui_actions_enhanced_examples/ @elastic/kibana-app-services /x-pack/plugins/embeddable_enhanced/ @elastic/kibana-app-services /x-pack/plugins/runtime_fields @elastic/kibana-app-services -/x-pack/test/search_sessions_integration/ @elastic/kibana-app-services /src/plugins/dashboard/public/application/embeddable/viewport/print_media @elastic/kibana-app-services x-pack/plugins/files @elastic/kibana-app-services x-pack/examples/files_example @elastic/kibana-app-services +/x-pack/test/search_sessions_integration/ @elastic/kibana-app-services +/test/plugin_functional/test_suites/panel_actions @elastic/kibana-app-services +/test/plugin_functional/test_suites/data_plugin @elastic/kibana-app-services ### Observability Plugins From cedbf8076f570133a39b1469e346541de0a1d142 Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau Date: Mon, 26 Sep 2022 17:00:46 -0400 Subject: [PATCH 37/51] [RAM] rmv public validation around our search strategy for alerts (#141850) * rmv public validation * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../search_strategy/search_strategy.test.ts | 48 +------------------ .../server/search_strategy/search_strategy.ts | 9 ---- .../tests/basic/search_strategy.ts | 18 ------- 3 files changed, 1 insertion(+), 74 deletions(-) diff --git a/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.test.ts b/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.test.ts index 1b32f688ee8c0..ffcf973f028a2 100644 --- a/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.test.ts +++ b/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.test.ts @@ -8,11 +8,7 @@ import { of } from 'rxjs'; import { merge } from 'lodash'; import { loggerMock } from '@kbn/logging-mocks'; import { AlertConsumers } from '@kbn/rule-data-utils'; -import { - ruleRegistrySearchStrategyProvider, - EMPTY_RESPONSE, - RULE_SEARCH_STRATEGY_NAME, -} from './search_strategy'; +import { ruleRegistrySearchStrategyProvider, EMPTY_RESPONSE } from './search_strategy'; import { ruleDataServiceMock } from '../rule_data_plugin_service/rule_data_plugin_service.mock'; import { dataPluginMock } from '@kbn/data-plugin/server/mocks'; import { SearchStrategyDependencies } from '@kbn/data-plugin/server'; @@ -385,48 +381,6 @@ describe('ruleRegistrySearchStrategyProvider()', () => { ).toStrictEqual([{ test: { order: 'desc' } }]); }); - it('should reject, to the best of our ability, public requests', async () => { - (getIsKibanaRequest as jest.Mock).mockImplementation(() => { - return false; - }); - const request: RuleRegistrySearchRequest = { - featureIds: [AlertConsumers.LOGS], - sort: [ - { - test: { - order: 'desc', - }, - }, - ], - }; - const options = {}; - const deps = { - request: {}, - }; - - const strategy = ruleRegistrySearchStrategyProvider( - data, - ruleDataService, - alerting, - logger, - security, - spaces - ); - - let err = null; - try { - await strategy - .search(request, options, deps as unknown as SearchStrategyDependencies) - .toPromise(); - } catch (e) { - err = e; - } - expect(err).not.toBeNull(); - expect(err.message).toBe( - `The ${RULE_SEARCH_STRATEGY_NAME} search strategy is currently only available for internal use.` - ); - }); - it('passes the query ids if provided', async () => { const request: RuleRegistrySearchRequest = { featureIds: [AlertConsumers.SIEM], diff --git a/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts b/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts index 6b9ac15cd8d6a..49a6439ef9b59 100644 --- a/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts +++ b/x-pack/plugins/rule_registry/server/search_strategy/search_strategy.ts @@ -5,7 +5,6 @@ * 2.0. */ import { map, mergeMap, catchError } from 'rxjs/operators'; -import Boom from '@hapi/boom'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { Logger } from '@kbn/core/server'; import { from, of } from 'rxjs'; @@ -25,7 +24,6 @@ import { Dataset } from '../rule_data_plugin_service/index_options'; import { MAX_ALERT_SEARCH_SIZE } from '../../common/constants'; import { AlertAuditAction, alertAuditEvent } from '..'; import { getSpacesFilter, getAuthzFilter } from '../lib'; -import { getIsKibanaRequest } from '../lib/get_is_kibana_request'; export const EMPTY_RESPONSE: RuleRegistrySearchResponse = { rawResponse: {} as RuleRegistrySearchResponse['rawResponse'], @@ -47,13 +45,6 @@ export const ruleRegistrySearchStrategyProvider = ( const requestUserEs = data.search.getSearchStrategy(ENHANCED_ES_SEARCH_STRATEGY); return { search: (request, options, deps) => { - // We want to ensure this request came from our UI. We can't really do this - // but we have a best effort we can try - if (!getIsKibanaRequest(deps.request.headers)) { - throw Boom.notFound( - `The ${RULE_SEARCH_STRATEGY_NAME} search strategy is currently only available for internal use.` - ); - } // SIEM uses RBAC fields in their alerts but also utilizes ES DLS which // is different than every other solution so we need to special case // those requests. diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts index a04899d68d585..11982a8b51425 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts @@ -110,24 +110,6 @@ export default ({ getService }: FtrProviderContext) => { const second = result.rawResponse.hits.hits[1].fields?.['kibana.alert.evaluation.value']; expect(first > second).to.be(true); }); - - it('should reject public requests', async () => { - const result = await secureBsearch.send({ - supertestWithoutAuth, - auth: { - username: logsOnlySpacesAll.username, - password: logsOnlySpacesAll.password, - }, - options: { - featureIds: [AlertConsumers.LOGS], - }, - strategy: 'privateRuleRegistryAlertsSearchStrategy', - }); - expect(result.statusCode).to.be(500); - expect(result.message).to.be( - `The privateRuleRegistryAlertsSearchStrategy search strategy is currently only available for internal use.` - ); - }); }); describe('siem', () => { From 605c958297abe950588658650bd321804ac38acc Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Mon, 26 Sep 2022 14:06:00 -0700 Subject: [PATCH 38/51] [DOCS] Add v3 open API spec for ml sync (#141554) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: István Zoltán Szabó --- x-pack/plugins/ml/common/openapi/README.md | 2 + .../plugins/ml/common/openapi/ml_apis_v3.yaml | 169 ++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 x-pack/plugins/ml/common/openapi/ml_apis_v3.yaml diff --git a/x-pack/plugins/ml/common/openapi/README.md b/x-pack/plugins/ml/common/openapi/README.md index 256b3be6a8cc4..450f95cd52071 100644 --- a/x-pack/plugins/ml/common/openapi/README.md +++ b/x-pack/plugins/ml/common/openapi/README.md @@ -5,6 +5,7 @@ The current self-contained spec file can be used for online tools like those fou A guide about the openApi specification can be found at [https://swagger.io/docs/specification/about/](https://swagger.io/docs/specification/about/). The `ml_apis_v2.json` file uses OpenAPI Specification Version 2.0. +The `ml_apis_v3.yaml` file uses OpenAPI Specification Version 3.0.1. ## Tools @@ -12,4 +13,5 @@ It is possible to validate the docs before bundling them by running the followin ``` npx swagger-cli validate ml_apis_v2.json +npx swagger-cli validate ml_apis_v3.yaml ``` diff --git a/x-pack/plugins/ml/common/openapi/ml_apis_v3.yaml b/x-pack/plugins/ml/common/openapi/ml_apis_v3.yaml new file mode 100644 index 0000000000000..938b3c312c0c4 --- /dev/null +++ b/x-pack/plugins/ml/common/openapi/ml_apis_v3.yaml @@ -0,0 +1,169 @@ +openapi: 3.0.1 +info: + title: Machine learning APIs + description: Kibana APIs for the machine learning feature + version: "1.0.1" + license: + name: Elastic License 2.0 + url: https://www.elastic.co/licensing/elastic-license +tags: + - name: ml + description: Machine learning +servers: + - url: https://localhost:5601/ +paths: + /s/{spaceId}/api/ml/saved_objects/sync: + get: + summary: Synchronizes Kibana saved objects for machine learning jobs and trained models. + description: > + You must have `all` privileges for the **Machine Learning** feature in the **Analytics** section of the Kibana feature privileges. + This API runs automatically when you start Kibana and periodically thereafter. + operationId: ml-sync + tags: + - ml + parameters: + - $ref: '#/components/parameters/spaceParam' + - $ref: '#/components/parameters/simulateParam' + responses: + '200': + description: Indicates a successful call + content: + application/json: + schema: + $ref: '#/components/schemas/mlSyncResponse' + examples: + syncExample: + $ref: '#/components/examples/mlSyncExample' +components: + parameters: + spaceParam: + in: path + name: spaceId + description: An identifier for the space. If `/s/` and the identifier are omitted from the path, the default space is used. + required: true + schema: + type: string + simulateParam: + in: query + name: simulate + description: When true, simulates the synchronization by returning only the list of actions that would be performed. + required: false + schema: + type: boolean + example: 'true' + securitySchemes: + basicAuth: + type: http + scheme: basic + apiKeyAuth: + type: apiKey + in: header + name: ApiKey + schemas: + mlSyncResponseSuccess: + type: boolean + description: The success or failure of the synchronization. + mlSyncResponseAnomalyDetectors: + type: object + title: Sync API response for anomaly detection jobs + description: The sync machine learning saved objects API response contains this object when there are anomaly detection jobs affected by the synchronization. There is an object for each relevant job, which contains the synchronization status. + properties: + success: + $ref: '#/components/schemas/mlSyncResponseSuccess' + mlSyncResponseDatafeeds: + type: object + title: Sync API response for datafeeds + description: The sync machine learning saved objects API response contains this object when there are datafeeds affected by the synchronization. There is an object for each relevant datafeed, which contains the synchronization status. + properties: + success: + $ref: '#/components/schemas/mlSyncResponseSuccess' + mlSyncResponseDataFrameAnalytics: + type: object + title: Sync API response for data frame analytics jobs + description: The sync machine learning saved objects API response contains this object when there are data frame analytics jobs affected by the synchronization. There is an object for each relevant job, which contains the synchronization status. + properties: + success: + $ref: '#/components/schemas/mlSyncResponseSuccess' + mlSyncResponseSavedObjectsCreated: + type: object + title: Sync API response for created saved objects + description: If saved objects are missing for machine learning jobs or trained models, they are created when you run the sync machine learning saved objects API. + properties: + anomaly-detector: + type: object + description: If saved objects are missing for anomaly detection jobs, they are created. + additionalProperties: + $ref: '#/components/schemas/mlSyncResponseAnomalyDetectors' + data-frame-analytics: + type: object + description: If saved objects are missing for data frame analytics jobs, they are created. + additionalProperties: + $ref: '#/components/schemas/mlSyncResponseDataFrameAnalytics' + trained-model: + type: object + description: If saved objects are missing for trained models, they are created. + additionalProperties: + $ref: '#/components/schemas/mlSyncResponseTrainedModels' + mlSyncResponseSavedObjectsDeleted: + type: object + title: Sync API response for deleted saved objects + description: If saved objects exist for machine learning jobs or trained models that no longer exist, they are deleted when you run the sync machine learning saved objects API. + properties: + anomaly-detector: + type: object + description: If there are saved objects exist for nonexistent anomaly detection jobs, they are deleted. + additionalProperties: + $ref: '#/components/schemas/mlSyncResponseAnomalyDetectors' + data-frame-analytics: + type: object + description: If there are saved objects exist for nonexistent data frame analytics jobs, they are deleted. + additionalProperties: + $ref: '#/components/schemas/mlSyncResponseDataFrameAnalytics' + trained-model: + type: object + description: If there are saved objects exist for nonexistent trained models, they are deleted. + additionalProperties: + $ref: '#/components/schemas/mlSyncResponseTrainedModels' + mlSyncResponseTrainedModels: + type: object + title: Sync API response for trained models + description: The sync machine learning saved objects API response contains this object when there are trained models affected by the synchronization. There is an object for each relevant trained model, which contains the synchronization status. + properties: + success: + $ref: '#/components/schemas/mlSyncResponseSuccess' + mlSyncResponse: + type: object + title: Sync API response + properties: + datafeedsAdded: + type: object + description: If a saved object for an anomaly detection job is missing a datafeed identifier, it is added when you run the sync machine learning saved objects API. + additionalProperties: + $ref: '#/components/schemas/mlSyncResponseDatafeeds' + datafeedsRemoved: + type: object + description: If a saved object for an anomaly detection job references a datafeed that no longer exists, it is deleted when you run the sync machine learning saved objects API. + additionalProperties: + $ref: '#/components/schemas/mlSyncResponseDatafeeds' + savedObjectsCreated: + $ref: '#/components/schemas/mlSyncResponseSavedObjectsCreated' + savedObjectsDeleted: + $ref: '#/components/schemas/mlSyncResponseSavedObjectsDeleted' + examples: + mlSyncExample: + summary: Two anomaly detection jobs required synchronization in this example. + value: + { + "savedObjectsCreated": { + "anomaly_detector": { + "myjob1": { "success":true }, + "myjob2":{ "success":true } + } + }, + "savedObjectsDeleted": {}, + "datafeedsAdded":{}, + "datafeedsRemoved":{} + } +security: + - basicAuth: [ ] + - ApiKeyAuth: [ ] \ No newline at end of file From d36cde0d3b0ed1dd03fdca007948de8e8a4ffb85 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Mon, 26 Sep 2022 20:12:14 -0500 Subject: [PATCH 39/51] [Enterprise Search] update ml pipeline target field help text (#141863) Updated the help text for the target field to tell the user the field will be defaults to "ml.inference.pipeline-name" if not set. --- .../pipelines/ml_inference/configure_pipeline.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx index 0d8c5b7c71f1f..199d62f914f03 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx @@ -182,7 +182,13 @@ export const ConfigurePipeline: React.FC = () => { formErrors.destinationField === undefined && i18n.translate( 'xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.destinationField.helpText', - { defaultMessage: 'Your field name will be prefixed with "ml.inference."' } + { + defaultMessage: + 'Your field name will be prefixed with "ml.inference.", if not set it will be defaulted to "ml.inference.{pipelineName}"', + values: { + pipelineName, + }, + } ) } error={formErrors.destinationField} From d09e40fa250109d7bcc1aca3834304502e18a8d4 Mon Sep 17 00:00:00 2001 From: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com> Date: Mon, 26 Sep 2022 21:23:07 -0400 Subject: [PATCH 40/51] [Detection Rules] Add 8.5 rules (#141839) --- .../collection_email_powershell_exchange_mailbox.json | 3 ++- .../prepackaged_rules/collection_posh_audio_capture.json | 5 +++-- .../prepackaged_rules/collection_posh_keylogger.json | 5 +++-- .../prepackaged_rules/collection_posh_screen_grabber.json | 5 +++-- .../prepackaged_rules/collection_winrar_encryption.json | 3 ++- .../command_and_control_certutil_network_connection.json | 7 ++++--- .../command_and_control_common_webservices.json | 7 ++++--- .../command_and_control_dns_tunneling_nslookup.json | 5 +++-- ...ommand_and_control_port_forwarding_added_registry.json | 5 +++-- .../command_and_control_rdp_tunnel_plink.json | 3 ++- ...nd_and_control_remote_file_copy_desktopimgdownldr.json | 5 +++-- .../command_and_control_remote_file_copy_mpcmdrun.json | 7 ++++--- .../command_and_control_remote_file_copy_powershell.json | 7 ++++--- .../command_and_control_remote_file_copy_scripts.json | 7 ++++--- ...command_and_control_sunburst_c2_activity_detected.json | 5 +++-- .../command_and_control_teamviewer_remote_file_copy.json | 7 ++++--- ...credential_access_aws_iam_assume_role_brute_force.json | 5 +++-- .../credential_access_bruteforce_passowrd_guessing.json | 3 ++- .../credential_access_cmdline_dump_tool.json | 3 ++- .../credential_access_credential_dumping_msbuild.json | 7 ++++--- .../credential_access_dcsync_replication_rights.json | 5 +++-- .../credential_access_disable_kerberos_preauth.json | 5 +++-- .../credential_access_dump_registry_hives.json | 3 ++- .../credential_access_iam_user_addition_to_group.json | 5 +++-- .../credential_access_kerberoasting_unusual_process.json | 7 ++++--- .../credential_access_lsass_memdump_handle_access.json | 7 ++++--- .../credential_access_mimikatz_memssp_default_logs.json | 5 +++-- .../credential_access_mimikatz_powershell_module.json | 5 +++-- .../credential_access_mod_wdigest_security_provider.json | 7 ++++--- .../credential_access_moving_registry_hive_via_smb.json | 5 +++-- .../credential_access_posh_minidump.json | 5 +++-- .../credential_access_posh_request_ticket.json | 5 +++-- .../credential_access_potential_linux_ssh_bruteforce.json | 3 ++- ...ential_access_potential_linux_ssh_bruteforce_root.json | 1 + ...credential_access_potential_macos_ssh_bruteforce.json} | 4 ++-- .../credential_access_remote_sam_secretsdump.json | 5 +++-- .../credential_access_secretsmanager_getsecretvalue.json | 5 +++-- ...cess_seenabledelegationprivilege_assigned_to_user.json | 5 +++-- .../credential_access_spn_attribute_modified.json | 5 +++-- ...access_suspicious_winreg_access_via_sebackup_priv.json | 5 +++-- ...ntial_access_symbolic_link_to_shadow_copy_created.json | 5 +++-- .../defense_evasion_amsienable_key_mod.json | 7 ++++--- .../defense_evasion_azure_service_principal_addition.json | 5 +++-- .../defense_evasion_clearing_windows_console_history.json | 5 +++-- .../defense_evasion_clearing_windows_event_logs.json | 3 ++- .../defense_evasion_clearing_windows_security_logs.json | 5 +++-- .../defense_evasion_cloudtrail_logging_deleted.json | 5 +++-- .../defense_evasion_cloudtrail_logging_suspended.json | 5 +++-- .../defense_evasion_cloudwatch_alarm_deletion.json | 5 +++-- .../defense_evasion_config_service_rule_deletion.json | 5 +++-- .../defense_evasion_create_mod_root_certificate.json | 7 ++++--- .../defense_evasion_defender_disabled_via_registry.json | 5 +++-- ...defense_evasion_defender_exclusion_via_powershell.json | 7 ++++--- .../defense_evasion_disable_posh_scriptblocklogging.json | 5 +++-- ...evasion_disable_windows_firewall_rules_with_netsh.json | 3 ++- ...nse_evasion_disabling_windows_defender_powershell.json | 5 +++-- .../defense_evasion_disabling_windows_logs.json | 3 ++- .../defense_evasion_ec2_flow_log_deletion.json | 5 +++-- .../defense_evasion_enable_inbound_rdp_with_netsh.json | 3 ++- ...fense_evasion_enable_network_discovery_with_netsh.json | 7 ++++--- ...e_evasion_execution_msbuild_started_by_office_app.json | 5 +++-- .../defense_evasion_microsoft_defender_tampering.json | 5 +++-- .../defense_evasion_ms_office_suspicious_regmod.json | 7 ++++--- .../defense_evasion_posh_assembly_load.json | 7 ++++--- .../defense_evasion_posh_compressed.json | 7 ++++--- .../defense_evasion_posh_process_injection.json | 5 +++-- ...ense_evasion_powershell_windows_firewall_disabled.json | 7 ++++--- ..._evasion_suspicious_process_access_direct_syscall.json | 7 ++++--- ...nse_evasion_suspicious_process_creation_calltrace.json | 5 +++-- ...asion_system_critical_proc_abnormal_file_activity.json | 7 ++++--- .../defense_evasion_unusual_ads_file_creation.json | 4 ++-- ...e_evasion_unusual_network_connection_via_rundll32.json | 3 ++- ...efense_evasion_unusual_process_network_connection.json | 5 +++-- .../defense_evasion_workfolders_control_execution.json | 3 ++- .../discovery_adfind_command_activity.json | 3 ++- .../rules/prepackaged_rules/discovery_admin_recon.json | 5 +++-- .../discovery_command_system_account.json | 3 ++- .../rules/prepackaged_rules/discovery_net_view.json | 5 +++-- .../prepackaged_rules/discovery_peripheral_device.json | 5 +++-- .../discovery_posh_invoke_sharefinder.json | 2 +- .../discovery_posh_suspicious_api_functions.json | 5 +++-- .../discovery_post_exploitation_external_ip_lookup.json | 5 +++-- .../discovery_privileged_localgroup_membership.json | 7 ++++--- ...iscovery_remote_system_discovery_commands_windows.json | 5 +++-- .../discovery_security_software_grep.json | 4 ++-- .../discovery_security_software_wmic.json | 5 +++-- .../discovery_whoami_command_activity.json | 5 +++-- .../execution_abnormal_process_id_file_created.json | 4 ++-- .../execution_command_shell_started_by_svchost.json | 7 ++++--- .../execution_from_unusual_path_cmdline.json | 2 +- .../execution_linux_netcat_network_connection.json | 3 ++- .../execution_ms_office_written_file.json | 5 +++-- .../prepackaged_rules/execution_pdf_written_file.json | 5 +++-- .../execution_posh_portable_executable.json | 7 ++++--- .../rules/prepackaged_rules/execution_posh_psreflect.json | 7 ++++--- .../execution_psexec_lateral_movement_command.json | 5 +++-- .../execution_revershell_via_shell_cmd.json | 4 ++-- .../execution_suspicious_jar_child_process.json | 4 ++-- .../execution_suspicious_pdf_reader.json | 5 +++-- .../execution_suspicious_powershell_imgload.json | 7 ++++--- .../execution_via_hidden_shell_conhost.json | 5 +++-- .../execution_via_xp_cmdshell_mssql_stored_procedure.json | 5 ++++- .../exfiltration_ec2_snapshot_change_activity.json | 5 +++-- .../prepackaged_rules/impact_backup_file_deletion.json | 5 +++-- .../impact_cloudtrail_logging_updated.json | 5 +++-- .../impact_cloudwatch_log_group_deletion.json | 5 +++-- .../impact_cloudwatch_log_stream_deletion.json | 5 +++-- .../impact_deleting_backup_catalogs_with_wbadmin.json | 3 ++- .../impact_google_workspace_mfa_enforcement_disabled.json | 5 +++-- .../prepackaged_rules/impact_hosts_file_modified.json | 4 ++-- .../impact_iam_deactivate_mfa_device.json | 5 +++-- .../impact_modification_of_boot_config.json | 3 ++- .../prepackaged_rules/impact_process_kill_threshold.json | 5 +++-- .../impact_stop_process_service_threshold.json | 5 +++-- ...lume_shadow_copy_deletion_or_resized_via_vssadmin.json | 5 +++-- ...impact_volume_shadow_copy_deletion_via_powershell.json | 5 +++-- .../impact_volume_shadow_copy_deletion_via_wmic.json | 5 +++-- .../lib/detection_engine/rules/prepackaged_rules/index.ts | 2 +- ...al_access_azure_active_directory_high_risk_signin.json | 5 +++-- ...ve_directory_high_risk_signin_atrisk_or_confirmed.json | 5 +++-- ...l_access_azure_active_directory_powershell_signin.json | 5 +++-- ...ent_grant_attack_via_azure_registered_application.json | 5 +++-- .../initial_access_console_login_root.json | 5 +++-- .../initial_access_script_executing_powershell.json | 5 +++-- ...initial_access_suspicious_ms_office_child_process.json | 5 +++-- ...nitial_access_suspicious_ms_outlook_child_process.json | 5 +++-- .../initial_access_unusual_dns_service_children.json | 7 ++++--- .../initial_access_via_system_manager.json | 5 +++-- .../lateral_movement_direct_outbound_smb_connection.json | 7 ++++--- .../lateral_movement_dns_server_overflow.json | 5 +++-- .../lateral_movement_executable_tool_transfer_smb.json | 7 ++++--- ...teral_movement_execution_via_file_shares_sequence.json | 1 + .../lateral_movement_rdp_enabled_registry.json | 5 +++-- .../lateral_movement_remote_services.json | 4 ++++ .../lateral_movement_scheduled_task_target.json | 5 +++-- .../ml_cloudtrail_error_message_spike.json | 5 +++-- .../prepackaged_rules/ml_cloudtrail_rare_error_code.json | 5 +++-- .../ml_cloudtrail_rare_method_by_city.json | 5 +++-- .../ml_cloudtrail_rare_method_by_country.json | 5 +++-- .../ml_cloudtrail_rare_method_by_user.json | 5 +++-- .../persistence_adobe_hijack_persistence.json | 7 ++++--- ...zure_privileged_identity_management_role_modified.json | 5 +++-- .../persistence_dontexpirepasswd_account.json | 5 +++-- ...persistence_evasion_hidden_local_account_creation.json | 5 +++-- ...ce_evasion_registry_startup_shell_folder_modified.json | 7 ++++--- .../persistence_gpo_schtask_service_creation.json | 4 ++-- .../persistence_mfa_disabled_for_azure_user.json | 5 +++-- .../persistence_ml_rare_process_by_host_windows.json | 5 +++-- ...stence_priv_escalation_via_accessibility_features.json | 5 +++-- .../persistence_run_key_and_startup_broad.json | 3 ++- .../persistence_sdprop_exclusion_dsheuristics.json | 5 +++-- .../persistence_shell_activity_by_web_server.json | 3 ++- ...startup_folder_file_written_by_suspicious_process.json | 7 ++++--- ...e_startup_folder_file_written_by_unsigned_process.json | 5 +++-- .../persistence_startup_folder_scripts.json | 7 ++++--- .../persistence_suspicious_com_hijack_registry.json | 7 ++++--- .../persistence_system_shells_via_services.json | 3 ++- ...istence_user_account_added_to_privileged_group_ad.json | 5 +++-- .../persistence_user_account_creation.json | 3 ++- ...ersistence_via_update_orchestrator_service_hijack.json | 4 ++-- .../prepackaged_rules/persistence_webshell_detection.json | 6 +++--- .../privilege_escalation_disable_uac_registry.json | 4 ++-- .../privilege_escalation_group_policy_iniscript.json | 5 +++-- ...ivilege_escalation_group_policy_privileged_groups.json | 5 +++-- .../privilege_escalation_group_policy_scheduled_task.json | 5 +++-- .../privilege_escalation_installertakeover.json | 7 ++++--- .../privilege_escalation_persistence_phantom_dll.json | 4 ++-- ...ilege_escalation_printspooler_suspicious_spl_file.json | 8 ++++---- .../privilege_escalation_root_login_without_mfa.json | 5 +++-- .../privilege_escalation_uac_bypass_event_viewer.json | 5 +++-- .../privilege_escalation_uac_bypass_mock_windir.json | 5 +++-- .../privilege_escalation_uac_bypass_winfw_mmc_hijack.json | 5 +++-- ...ilege_escalation_unusual_parentchild_relationship.json | 5 +++-- .../privilege_escalation_updateassumerolepolicy.json | 5 +++-- .../rules/prepackaged_rules/threat_intel_filebeat8x.json | 5 +++-- .../threat_intel_fleet_integrations.json | 5 +++-- 176 files changed, 522 insertions(+), 357 deletions(-) rename x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/{credential_access_potential_ssh_bruteforce.json => credential_access_potential_macos_ssh_bruteforce.json} (95%) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json index 3a82c828d637c..d891ad96a57c0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json @@ -47,7 +47,8 @@ "Host", "Windows", "Threat Detection", - "Collection" + "Collection", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_audio_capture.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_audio_capture.json index 3721078880a42..2a3519f83bd29 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_audio_capture.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_audio_capture.json @@ -37,7 +37,8 @@ "Host", "Windows", "Threat Detection", - "Collection" + "Collection", + "has_guide" ], "threat": [ { @@ -80,5 +81,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_keylogger.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_keylogger.json index db9abf0b19506..a1d437332842a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_keylogger.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_keylogger.json @@ -38,7 +38,8 @@ "Host", "Windows", "Threat Detection", - "Collection" + "Collection", + "has_guide" ], "threat": [ { @@ -88,5 +89,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_screen_grabber.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_screen_grabber.json index 1b041659b488c..cec0fd82efb05 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_screen_grabber.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_screen_grabber.json @@ -37,7 +37,8 @@ "Host", "Windows", "Threat Detection", - "Collection" + "Collection", + "has_guide" ], "threat": [ { @@ -80,5 +81,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json index 6aeca04a6d9d7..0c69fba974b39 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json @@ -53,7 +53,8 @@ "Host", "Windows", "Threat Detection", - "Collection" + "Collection", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_certutil_network_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_certutil_network_connection.json index c437fde5ea4bb..827659f95566f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_certutil_network_connection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_certutil_network_connection.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Network Connection via Certutil", - "note": "## Triage and analysis\n\n### Investigating Network Connection via Certutil\n\nAttackers can abuse `certutil.exe` to download malware, offensive security tools, and certificates from external sources\nin order to take the next steps in a compromised environment.\n\nThis rule looks for network events where `certutil.exe` contacts IP ranges other than the ones specified in\n[IANA IPv4 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml)\n\n#### Possible investigation steps\n\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate if the downloaded file was executed.\n- Determine the context in which `certutil.exe` and the file were run.\n- Retrieve the downloaded file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This mechanism can be used legitimately. If trusted software uses this command and the triage has not identified\nanything suspicious, this alert can be closed as a false positive.\n- If this rule is noisy in your environment due to expected activity, consider adding exceptions \u2014 preferably with a combination\nof user and command line conditions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating Network Connection via Certutil\n\nAttackers can abuse `certutil.exe` to download malware, offensive security tools, and certificates from external sources\nin order to take the next steps in a compromised environment.\n\nThis rule looks for network events where `certutil.exe` contacts IP ranges other than the ones specified in\n[IANA IPv4 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml)\n\n#### Possible investigation steps\n\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate if the downloaded file was executed.\n- Determine the context in which `certutil.exe` and the file were run.\n- Retrieve the downloaded file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This mechanism can be used legitimately. If trusted software uses this command and the triage has not identified\nanything suspicious, this alert can be closed as a false positive.\n- If this rule is noisy in your environment due to expected activity, consider adding exceptions \u2014 preferably with a combination\nof user and command line conditions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence by process.entity_id\n [process where process.name : \"certutil.exe\" and event.type == \"start\"]\n [network where process.name : \"certutil.exe\" and\n not cidrmatch(destination.ip, \"10.0.0.0/8\", \"127.0.0.0/8\", \"169.254.0.0/16\", \"172.16.0.0/12\", \"192.0.0.0/24\",\n \"192.0.0.0/29\", \"192.0.0.8/32\", \"192.0.0.9/32\", \"192.0.0.10/32\", \"192.0.0.170/32\",\n \"192.0.0.171/32\", \"192.0.2.0/24\", \"192.31.196.0/24\", \"192.52.193.0/24\",\n \"192.168.0.0/16\", \"192.88.99.0/24\", \"224.0.0.0/4\", \"100.64.0.0/10\", \"192.175.48.0/24\",\n \"198.18.0.0/15\", \"198.51.100.0/24\", \"203.0.113.0/24\", \"240.0.0.0/4\", \"::1\",\n \"FE80::/10\", \"FF00::/8\")]\n", "references": [ "https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml", @@ -48,7 +48,8 @@ "Host", "Windows", "Threat Detection", - "Command and Control" + "Command and Control", + "has_guide" ], "threat": [ { @@ -68,5 +69,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json index f528501b0da5a..49562601e3372 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json @@ -10,7 +10,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Connection to Commonly Abused Web Services", - "note": "## Triage and analysis\n\n### Investigating Connection to Commonly Abused Web Services\n\nAdversaries may use an existing, legitimate external Web service as a means for relaying data to/from a compromised\nsystem. Popular websites and social media acting as a mechanism for C2 may give a significant amount of cover due to the\nlikelihood that hosts within a network are already communicating with them prior to a compromise.\n\nThis rule looks for processes outside known legitimate program locations communicating with a list of services that can\nbe abused for exfiltration or command and control.\n\n#### Possible investigation steps\n\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Verify whether the digital signature exists in the executable.\n- Identify the operation type (upload, download, tunneling, etc.).\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This rule has a high chance to produce false positives because it detects communication with legitimate services. Noisy\nfalse positives can be added as exceptions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating Connection to Commonly Abused Web Services\n\nAdversaries may use an existing, legitimate external Web service as a means for relaying data to/from a compromised\nsystem. Popular websites and social media acting as a mechanism for C2 may give a significant amount of cover due to the\nlikelihood that hosts within a network are already communicating with them prior to a compromise.\n\nThis rule looks for processes outside known legitimate program locations communicating with a list of services that can\nbe abused for exfiltration or command and control.\n\n#### Possible investigation steps\n\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Verify whether the digital signature exists in the executable.\n- Identify the operation type (upload, download, tunneling, etc.).\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This rule has a high chance to produce false positives because it detects communication with legitimate services. Noisy\nfalse positives can be added as exceptions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "network where network.protocol == \"dns\" and\n process.name != null and user.id not in (\"S-1-5-18\", \"S-1-5-19\", \"S-1-5-20\") and\n /* Add new WebSvc domains here */\n dns.question.name :\n (\n \"raw.githubusercontent.*\",\n \"*.pastebin.*\",\n \"*drive.google.*\",\n \"*docs.live.*\",\n \"*api.dropboxapi.*\",\n \"*dropboxusercontent.*\",\n \"*onedrive.*\",\n \"*4shared.*\",\n \"*.file.io\",\n \"*filebin.net\",\n \"*slack-files.com\",\n \"*ghostbin.*\",\n \"*ngrok.*\",\n \"*portmap.*\",\n \"*serveo.net\",\n \"*localtunnel.me\",\n \"*pagekite.me\",\n \"*localxpose.io\",\n \"*notabug.org\",\n \"rawcdn.githack.*\",\n \"paste.nrecom.net\",\n \"zerobin.net\",\n \"controlc.com\",\n \"requestbin.net\",\n \"cdn.discordapp.com\",\n \"discordapp.com\",\n \"discord.com\"\n ) and\n /* Insert noisy false positives here */\n not process.executable :\n (\n \"?:\\\\Program Files\\\\*.exe\",\n \"?:\\\\Program Files (x86)\\\\*.exe\",\n \"?:\\\\Windows\\\\System32\\\\WWAHost.exe\",\n \"?:\\\\Windows\\\\System32\\\\smartscreen.exe\",\n \"?:\\\\Windows\\\\System32\\\\MicrosoftEdgeCP.exe\",\n \"?:\\\\ProgramData\\\\Microsoft\\\\Windows Defender\\\\Platform\\\\*\\\\MsMpEng.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Programs\\\\Fiddler\\\\Fiddler.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Programs\\\\Microsoft VS Code\\\\Code.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Microsoft\\\\OneDrive\\\\OneDrive.exe\",\n \"?:\\\\Windows\\\\system32\\\\mobsync.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\mobsync.exe\",\n \"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Discord\\\\app-*\\\\Discord.exe\"\n )\n", "required_fields": [ { @@ -47,7 +47,8 @@ "Host", "Windows", "Threat Detection", - "Command and Control" + "Command and Control", + "has_guide" ], "threat": [ { @@ -95,5 +96,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json index 55eb5c136eb56..89945ae91c6da 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json @@ -47,7 +47,8 @@ "Host", "Windows", "Threat Detection", - "Command and Control" + "Command and Control", + "has_guide" ], "threat": [ { @@ -80,5 +81,5 @@ "value": 15 }, "type": "threshold", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_forwarding_added_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_forwarding_added_registry.json index 20a6904c44bc0..7898871bb9b3a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_forwarding_added_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_forwarding_added_registry.json @@ -33,7 +33,8 @@ "Host", "Windows", "Threat Detection", - "Command and Control" + "Command and Control", + "has_guide" ], "threat": [ { @@ -54,5 +55,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_tunnel_plink.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_tunnel_plink.json index d7d8d9b394813..a9af94cec09d3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_tunnel_plink.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_tunnel_plink.json @@ -38,7 +38,8 @@ "Host", "Windows", "Threat Detection", - "Command and Control" + "Command and Control", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json index a175e4f84ead1..c49f3cd7efefb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Remote File Download via Desktopimgdownldr Utility", - "note": "## Triage and analysis\n\n### Investigating Remote File Download via Desktopimgdownldr Utility\n\nAttackers commonly transfer tooling or malware from external systems into a compromised environment using the command\nand control channel. However, they can also abuse signed utilities to drop these files.\n\nThe `Desktopimgdownldr.exe` utility is used to to configure lockscreen/desktop image, and can be abused with the\n`lockscreenurl` argument to download remote files and tools, this rule looks for this behavior.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Check the reputation of the domain or IP address used to host the downloaded file or if the user downloaded the file\nfrom an internal system.\n- Retrieve the file and determine if it is malicious:\n - Identify the file type.\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unusual but can be done by administrators. Benign true positives (B-TPs) can be added as exceptions\nif necessary.\n- Analysts can dismiss the alert if the downloaded file is a legitimate image.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Remote File Download via Desktopimgdownldr Utility\n\nAttackers commonly transfer tooling or malware from external systems into a compromised environment using the command\nand control channel. However, they can also abuse signed utilities to drop these files.\n\nThe `Desktopimgdownldr.exe` utility is used to to configure lockscreen/desktop image, and can be abused with the\n`lockscreenurl` argument to download remote files and tools, this rule looks for this behavior.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Check the reputation of the domain or IP address used to host the downloaded file or if the user downloaded the file\nfrom an internal system.\n- Retrieve the file and determine if it is malicious:\n - Identify the file type.\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unusual but can be done by administrators. Benign true positives (B-TPs) can be added as exceptions\nif necessary.\n- Analysts can dismiss the alert if the downloaded file is a legitimate image.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n (process.name : \"desktopimgdownldr.exe\" or process.pe.original_file_name == \"desktopimgdownldr.exe\") and\n process.args : \"/lockscreenurl:http*\"\n", "references": [ "https://labs.sentinelone.com/living-off-windows-land-a-new-native-file-downldr/" @@ -48,7 +48,8 @@ "Host", "Windows", "Threat Detection", - "Command and Control" + "Command and Control", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json index 2ffafee4416b6..229755609cc38 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Remote File Download via MpCmdRun", - "note": "## Triage and analysis\n\n### Investigating Remote File Download via MpCmdRun\n\nAttackers commonly transfer tooling or malware from external systems into a compromised environment using the command\nand control channel. However, they can also abuse signed utilities to drop these files.\n\nThe `MpCmdRun.exe` is a command-line tool part of Windows Defender and is used to manage various Microsoft Windows\nDefender Antivirus settings and perform certain tasks. It can also be abused by attackers to download remote files,\nincluding malware and offensive tooling. This rule looks for the patterns used to perform downloads using the utility.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Check the reputation of the domain or IP address used to host the downloaded file.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Remote File Download via MpCmdRun\n\nAttackers commonly transfer tooling or malware from external systems into a compromised environment using the command\nand control channel. However, they can also abuse signed utilities to drop these files.\n\nThe `MpCmdRun.exe` is a command-line tool part of Windows Defender and is used to manage various Microsoft Windows\nDefender Antivirus settings and perform certain tasks. It can also be abused by attackers to download remote files,\nincluding malware and offensive tooling. This rule looks for the patterns used to perform downloads using the utility.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Check the reputation of the domain or IP address used to host the downloaded file.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n (process.name : \"MpCmdRun.exe\" or process.pe.original_file_name == \"MpCmdRun.exe\") and\n process.args : \"-DownloadFile\" and process.args : \"-url\" and process.args : \"-path\"\n", "references": [ "https://twitter.com/mohammadaskar2/status/1301263551638761477", @@ -49,7 +49,8 @@ "Host", "Windows", "Threat Detection", - "Command and Control" + "Command and Control", + "has_guide" ], "threat": [ { @@ -70,5 +71,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_powershell.json index 1b42352777aef..c6a7c798235d8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_powershell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_powershell.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Remote File Download via PowerShell", - "note": "## Triage and analysis\n\n### Investigating Remote File Download via PowerShell\n\nAttackers commonly transfer tooling or malware from external systems into a compromised environment using the command\nand control channel. However, they can also abuse signed utilities to drop these files.\n\nPowerShell is one of system administrators' main tools for automation, report routines, and other tasks. This makes it\navailable for use in various environments and creates an attractive way for attackers to execute code and perform\nactions. This rule correlates network and file events to detect downloads of executable and script files performed using\nPowerShell.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Evaluate whether the user needs to use PowerShell to complete tasks.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Check the reputation of the domain or IP address used to host the downloaded file.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- Administrators can use PowerShell legitimately to download executable and script files. Analysts can dismiss the alert\nif the Administrator is aware of the activity and the triage has not identified suspicious or malicious files.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating Remote File Download via PowerShell\n\nAttackers commonly transfer tooling or malware from external systems into a compromised environment using the command\nand control channel. However, they can also abuse signed utilities to drop these files.\n\nPowerShell is one of system administrators' main tools for automation, report routines, and other tasks. This makes it\navailable for use in various environments and creates an attractive way for attackers to execute code and perform\nactions. This rule correlates network and file events to detect downloads of executable and script files performed using\nPowerShell.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Evaluate whether the user needs to use PowerShell to complete tasks.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Check the reputation of the domain or IP address used to host the downloaded file.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- Administrators can use PowerShell legitimately to download executable and script files. Analysts can dismiss the alert\nif the Administrator is aware of the activity and the triage has not identified suspicious or malicious files.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence by host.id, process.entity_id with maxspan=30s\n [network where process.name : (\"powershell.exe\", \"pwsh.exe\", \"powershell_ise.exe\") and network.protocol == \"dns\" and\n not dns.question.name : (\"localhost\", \"*.microsoft.com\", \"*.azureedge.net\", \"*.powershellgallery.com\", \"*.windowsupdate.com\", \"metadata.google.internal\") and\n not user.domain : \"NT AUTHORITY\"]\n [file where process.name : \"powershell.exe\" and event.type == \"creation\" and file.extension : (\"exe\", \"dll\", \"ps1\", \"bat\") and\n not file.name : \"__PSScriptPolicy*.ps1\"]\n", "required_fields": [ { @@ -69,7 +69,8 @@ "Host", "Windows", "Threat Detection", - "Command and Control" + "Command and Control", + "has_guide" ], "threat": [ { @@ -111,5 +112,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_scripts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_scripts.json index 35ac4855cdab5..3ab79126bec9f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_scripts.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_scripts.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Remote File Download via Script Interpreter", - "note": "## Triage and analysis\n\n### Investigating Remote File Download via Script Interpreter\n\nThe Windows Script Host (WSH) is a Windows automation technology, which is ideal for non-interactive scripting needs,\nsuch as logon scripting, administrative scripting, and machine automation.\n\nAttackers commonly use WSH scripts as their initial access method, acting like droppers for second stage payloads, but\ncan also use them to download tools and utilities needed to accomplish their goals.\n\nThis rule looks for DLLs and executables downloaded using `cscript.exe` or `wscript.exe`.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Retrieve the script file and the executable involved and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n - Manually analyze the script to determine if malicious capabilities are present.\n- Investigate whether the potential malware ran successfully, is active on the host, or was stopped by defenses.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n\n### False positive analysis\n\n- The usage of these script engines by regular users is unlikely. In the case of authorized benign true positives\n(B-TPs), exceptions can be added.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating Remote File Download via Script Interpreter\n\nThe Windows Script Host (WSH) is a Windows automation technology, which is ideal for non-interactive scripting needs,\nsuch as logon scripting, administrative scripting, and machine automation.\n\nAttackers commonly use WSH scripts as their initial access method, acting like droppers for second stage payloads, but\ncan also use them to download tools and utilities needed to accomplish their goals.\n\nThis rule looks for DLLs and executables downloaded using `cscript.exe` or `wscript.exe`.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Retrieve the script file and the executable involved and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n - Manually analyze the script to determine if malicious capabilities are present.\n- Investigate whether the potential malware ran successfully, is active on the host, or was stopped by defenses.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n\n### False positive analysis\n\n- The usage of these script engines by regular users is unlikely. In the case of authorized benign true positives\n(B-TPs), exceptions can be added.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence by host.id, process.entity_id\n [network where process.name : (\"wscript.exe\", \"cscript.exe\") and network.protocol != \"dns\" and\n network.direction : (\"outgoing\", \"egress\") and network.type == \"ipv4\" and destination.ip != \"127.0.0.1\"\n ]\n [file where event.type == \"creation\" and file.extension : (\"exe\", \"dll\")]\n", "required_fields": [ { @@ -69,7 +69,8 @@ "Host", "Windows", "Threat Detection", - "Command and Control" + "Command and Control", + "has_guide" ], "threat": [ { @@ -89,5 +90,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json index 8a6bf64b5edb7..45c95688fc9b4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json @@ -10,7 +10,7 @@ "language": "eql", "license": "Elastic License v2", "name": "SUNBURST Command and Control Activity", - "note": "## Triage and analysis\n\n### Investigating SUNBURST Command and Control Activity\n\nSUNBURST is a trojanized version of a digitally signed SolarWinds Orion plugin called\nSolarWinds.Orion.Core.BusinessLayer.dll. The plugin contains a backdoor that communicates via HTTP to third-party\nservers. After an initial dormant period of up to two weeks, SUNBURST may retrieve and execute commands that instruct\nthe backdoor to transfer files, execute files, profile the system, reboot the system, and disable system services.\nThe malware's network traffic attempts to blend in with legitimate SolarWinds activity by imitating the Orion\nImprovement Program (OIP) protocol, and the malware stores persistent state data within legitimate plugin configuration files. The\nbackdoor uses multiple obfuscated blocklists to identify processes, services, and drivers associated with forensic and\nanti-virus tools.\n\nMore details on SUNBURST can be found on the [Mandiant Report](https://www.mandiant.com/resources/sunburst-additional-technical-details).\n\nThis rule identifies suspicious network connections that attempt to blend in with legitimate SolarWinds activity\nby imitating the Orion Improvement Program (OIP) protocol behavior.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Retrieve the executable involved:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Investigate whether the potential malware ran successfully, is active on the host, or was stopped by defenses.\n- Investigate the network traffic.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n\n### False positive analysis\n\n- This activity should not happen legitimately. The security team should address any potential benign true positive\n(B-TP), as this configuration can put the environment at risk.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Reimage the host operating system and restore compromised files to clean versions.\n- Upgrade SolarWinds systems to the latest version to eradicate the chance of reinfection by abusing the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating SUNBURST Command and Control Activity\n\nSUNBURST is a trojanized version of a digitally signed SolarWinds Orion plugin called\nSolarWinds.Orion.Core.BusinessLayer.dll. The plugin contains a backdoor that communicates via HTTP to third-party\nservers. After an initial dormant period of up to two weeks, SUNBURST may retrieve and execute commands that instruct\nthe backdoor to transfer files, execute files, profile the system, reboot the system, and disable system services.\nThe malware's network traffic attempts to blend in with legitimate SolarWinds activity by imitating the Orion\nImprovement Program (OIP) protocol, and the malware stores persistent state data within legitimate plugin configuration files. The\nbackdoor uses multiple obfuscated blocklists to identify processes, services, and drivers associated with forensic and\nanti-virus tools.\n\nMore details on SUNBURST can be found on the [Mandiant Report](https://www.mandiant.com/resources/sunburst-additional-technical-details).\n\nThis rule identifies suspicious network connections that attempt to blend in with legitimate SolarWinds activity\nby imitating the Orion Improvement Program (OIP) protocol behavior.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Retrieve the executable involved:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Investigate whether the potential malware ran successfully, is active on the host, or was stopped by defenses.\n- Investigate the network traffic.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n\n### False positive analysis\n\n- This activity should not happen legitimately. The security team should address any potential benign true positive\n(B-TP), as this configuration can put the environment at risk.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Reimage the host operating system and restore compromised files to clean versions.\n- Upgrade SolarWinds systems to the latest version to eradicate the chance of reinfection by abusing the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "network where event.type == \"protocol\" and network.protocol == \"http\" and\n process.name : (\"ConfigurationWizard.exe\",\n \"NetFlowService.exe\",\n \"NetflowDatabaseMaintenance.exe\",\n \"SolarWinds.Administration.exe\",\n \"SolarWinds.BusinessLayerHost.exe\",\n \"SolarWinds.BusinessLayerHostx64.exe\",\n \"SolarWinds.Collector.Service.exe\",\n \"SolarwindsDiagnostics.exe\") and\n (\n (\n (http.request.body.content : \"*/swip/Upload.ashx*\" and http.request.body.content : (\"POST*\", \"PUT*\")) or\n (http.request.body.content : (\"*/swip/SystemDescription*\", \"*/swip/Events*\") and http.request.body.content : (\"GET*\", \"HEAD*\"))\n ) and\n not http.request.body.content : \"*solarwinds.com*\"\n )\n", "references": [ "https://www.fireeye.com/blog/threat-research/2020/12/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor.html" @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Command and Control" + "Command and Control", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json index 0e82077dd3da8..82e7f299ea8fa 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Remote File Copy via TeamViewer", - "note": "## Triage and analysis\n\n### Investigating Remote File Copy via TeamViewer\n\nAttackers commonly transfer tooling or malware from external systems into a compromised environment using the command\nand control channel. However, they can also abuse legitimate utilities to drop these files.\n\nTeamViewer is a remote access and remote control tool used by helpdesks and system administrators to perform various\nsupport activities. It is also frequently used by attackers and scammers to deploy malware interactively and other\nmalicious activities. This rule looks for the TeamViewer process creating files with suspicious extensions.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Contact the user to gather information about who and why was conducting the remote access.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Check whether the company uses TeamViewer for the support activities and if there is a support ticket related to this\naccess.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This mechanism can be used legitimately. Analysts can dismiss the alert if the company relies on TeamViewer to conduct\nremote access and the triage has not identified suspicious or malicious files.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Remote File Copy via TeamViewer\n\nAttackers commonly transfer tooling or malware from external systems into a compromised environment using the command\nand control channel. However, they can also abuse legitimate utilities to drop these files.\n\nTeamViewer is a remote access and remote control tool used by helpdesks and system administrators to perform various\nsupport activities. It is also frequently used by attackers and scammers to deploy malware interactively and other\nmalicious activities. This rule looks for the TeamViewer process creating files with suspicious extensions.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Contact the user to gather information about who and why was conducting the remote access.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Check whether the company uses TeamViewer for the support activities and if there is a support ticket related to this\naccess.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This mechanism can be used legitimately. Analysts can dismiss the alert if the company relies on TeamViewer to conduct\nremote access and the triage has not identified suspicious or malicious files.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "file where event.type == \"creation\" and process.name : \"TeamViewer.exe\" and\n file.extension : (\"exe\", \"dll\", \"scr\", \"com\", \"bat\", \"ps1\", \"vbs\", \"vbe\", \"js\", \"wsh\", \"hta\")\n", "references": [ "https://blog.menasec.net/2019/11/hunting-for-suspicious-use-of.html" @@ -43,7 +43,8 @@ "Host", "Windows", "Threat Detection", - "Command and Control" + "Command and Control", + "has_guide" ], "threat": [ { @@ -69,5 +70,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_aws_iam_assume_role_brute_force.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_aws_iam_assume_role_brute_force.json index 646cc2397ac02..490b96665a83b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_aws_iam_assume_role_brute_force.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_aws_iam_assume_role_brute_force.json @@ -61,7 +61,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Identity and Access" + "Identity and Access", + "has_guide" ], "threat": [ { @@ -85,5 +86,5 @@ "value": 25 }, "type": "threshold", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_passowrd_guessing.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_passowrd_guessing.json index a50ad42b025ad..5d6992ccec503 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_passowrd_guessing.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_passowrd_guessing.json @@ -10,7 +10,8 @@ ], "language": "eql", "license": "Elastic License v2", - "name": "Potential SSH Password Spraying", + "name": "Potential SSH Password Guessing", + "note": "## Triage and analysis\n\n### Investigating Potential SSH Password Guessing Attack\n\nThe rule identifies consecutive SSH login failures followed by a successful login from the same source IP address to the\nsame target host indicating a successful attempt of brute force password guessing.\n\n#### Possible investigation steps\n\n- Investigate the login failure user name(s).\n- Investigate the source IP address of the failed ssh login attempt(s).\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Identify the source and the target computer and their roles in the IT environment.\n\n### False positive analysis\n\n- Authentication misconfiguration or obsolete credentials.\n- Service account password expired.\n- Infrastructure or availability issue.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Ensure active session(s) on the host(s) are terminated as the attacker could have gained initial\naccess to the system(s).\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified.\n- Reset passwords for these accounts and other potentially compromised credentials.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n\n", "query": "sequence by host.id, source.ip, user.name with maxspan=3s\n [authentication where event.action in (\"ssh_login\", \"user_login\") and\n event.outcome == \"failure\" and source.ip != null and source.ip != \"0.0.0.0\" and source.ip != \"::\" ] with runs=2\n\n [authentication where event.action in (\"ssh_login\", \"user_login\") and\n event.outcome == \"success\" and source.ip != null and source.ip != \"0.0.0.0\" and source.ip != \"::\" ]\n", "required_fields": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cmdline_dump_tool.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cmdline_dump_tool.json index dbc92a27f7040..30103c4bf3c5c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cmdline_dump_tool.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cmdline_dump_tool.json @@ -58,7 +58,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json index 844b09d5de305..cf962e1f5f65b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json @@ -15,7 +15,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Potential Credential Access via Trusted Developer Utility", - "note": "## Triage and analysis\n\n### Investigating Potential Credential Access via Trusted Developer Utility\n\nThe Microsoft Build Engine is a platform for building applications. This engine, also known as MSBuild, provides an XML\nschema for a project file that controls how the build platform processes and builds software.\n\nAdversaries can abuse MSBuild to proxy the execution of malicious code. The inline task capability of MSBuild that was\nintroduced in .NET version 4 allows for C# or Visual Basic code to be inserted into an XML project file. MSBuild will\ncompile and execute the inline task. `MSBuild.exe` is a signed Microsoft binary, and the execution of code using it can bypass\napplication control defenses that are configured to allow `MSBuild.exe` execution.\n\nThis rule looks for the MSBuild process loading `vaultcli.dll` or `SAMLib.DLL`, which indicates the execution of\ncredential access activities.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate abnormal behaviors observed by the subject process, such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Examine the command line to identify the `.csproj` file location.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Investigate potentially compromised accounts. Analysts can do this by searching for login events (for example, 4624) to the target\nhost after the registry modification.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating Potential Credential Access via Trusted Developer Utility\n\nThe Microsoft Build Engine is a platform for building applications. This engine, also known as MSBuild, provides an XML\nschema for a project file that controls how the build platform processes and builds software.\n\nAdversaries can abuse MSBuild to proxy the execution of malicious code. The inline task capability of MSBuild that was\nintroduced in .NET version 4 allows for C# or Visual Basic code to be inserted into an XML project file. MSBuild will\ncompile and execute the inline task. `MSBuild.exe` is a signed Microsoft binary, and the execution of code using it can bypass\napplication control defenses that are configured to allow `MSBuild.exe` execution.\n\nThis rule looks for the MSBuild process loading `vaultcli.dll` or `SAMLib.DLL`, which indicates the execution of\ncredential access activities.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate abnormal behaviors observed by the subject process, such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Examine the command line to identify the `.csproj` file location.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Investigate potentially compromised accounts. Analysts can do this by searching for login events (for example, 4624) to the target\nhost after the registry modification.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence by process.entity_id\n [process where event.type == \"start\" and (process.name : \"MSBuild.exe\" or process.pe.original_file_name == \"MSBuild.exe\")]\n [any where (event.category == \"library\" or (event.category == \"process\" and event.action : \"Image loaded*\")) and\n (dll.name : (\"vaultcli.dll\", \"SAMLib.DLL\") or file.name : (\"vaultcli.dll\", \"SAMLib.DLL\"))]\n", "required_fields": [ { @@ -67,7 +67,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -87,5 +88,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dcsync_replication_rights.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dcsync_replication_rights.json index 38a9092d1eb2f..15fcde9b83e81 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dcsync_replication_rights.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dcsync_replication_rights.json @@ -58,7 +58,8 @@ "Windows", "Threat Detection", "Credential Access", - "Active Directory" + "Active Directory", + "has_guide" ], "threat": [ { @@ -86,5 +87,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_disable_kerberos_preauth.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_disable_kerberos_preauth.json index 0bde382a2e55a..783852168fcb5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_disable_kerberos_preauth.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_disable_kerberos_preauth.json @@ -39,7 +39,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -67,5 +68,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dump_registry_hives.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dump_registry_hives.json index 15e4cad7bfc40..49a04cb198d86 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dump_registry_hives.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dump_registry_hives.json @@ -43,7 +43,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json index 41e7921aab797..2140870e22d1f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json @@ -61,7 +61,8 @@ "SecOps", "Identity and Access", "Credential Access", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { @@ -91,5 +92,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberoasting_unusual_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberoasting_unusual_process.json index b10a2e5ea9fbc..11a8abce27853 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberoasting_unusual_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberoasting_unusual_process.json @@ -15,7 +15,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Kerberos Traffic from Unusual Process", - "note": "## Triage and analysis\n\n### Investigating Kerberos Traffic from Unusual Process\n\nKerberos is the default authentication protocol in Active Directory, designed to provide strong authentication for\nclient/server applications by using secret-key cryptography.\n\nDomain-joined hosts usually perform Kerberos traffic using the `lsass.exe` process. This rule detects the occurrence of\ntraffic on the Kerberos port (88) by processes other than `lsass.exe` to detect the unusual request and usage of\nKerberos tickets.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Check if the Destination IP is related to a Domain Controller.\n- Review event ID 4769 for suspicious ticket requests.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This rule uses a Kerberos-related port but does not identify the protocol used on that port. HTTP traffic on a\nnon-standard port or destination IP address unrelated to Domain controllers can create false positives.\n- Exceptions can be added for noisy/frequent connections.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n - Ticket requests can be used to investigate potentially compromised accounts.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Kerberos Traffic from Unusual Process\n\nKerberos is the default authentication protocol in Active Directory, designed to provide strong authentication for\nclient/server applications by using secret-key cryptography.\n\nDomain-joined hosts usually perform Kerberos traffic using the `lsass.exe` process. This rule detects the occurrence of\ntraffic on the Kerberos port (88) by processes other than `lsass.exe` to detect the unusual request and usage of\nKerberos tickets.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Check if the Destination IP is related to a Domain Controller.\n- Review event ID 4769 for suspicious ticket requests.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This rule uses a Kerberos-related port but does not identify the protocol used on that port. HTTP traffic on a\nnon-standard port or destination IP address unrelated to Domain controllers can create false positives.\n- Exceptions can be added for noisy/frequent connections.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n - Ticket requests can be used to investigate potentially compromised accounts.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "network where event.type == \"start\" and network.direction : (\"outgoing\", \"egress\") and\n destination.port == 88 and source.port >= 49152 and\n not process.executable :\n (\"?:\\\\Windows\\\\System32\\\\lsass.exe\",\n \"System\",\n \"\\\\device\\\\harddiskvolume?\\\\windows\\\\system32\\\\lsass.exe\",\n \"?:\\\\Program Files\\\\rapid7\\\\nexpose\\\\nse\\\\.DLLCACHE\\\\nseserv.exe\",\n \"?:\\\\Program Files (x86)\\\\GFI\\\\LanGuard 12 Agent\\\\lnsscomm.exe\",\n \"?:\\\\Program Files (x86)\\\\SuperScan\\\\scanner.exe\",\n \"?:\\\\Program Files (x86)\\\\Nmap\\\\nmap.exe\",\n \"\\\\device\\\\harddiskvolume?\\\\program files (x86)\\\\nmap\\\\nmap.exe\") and\n destination.address !=\"127.0.0.1\" and destination.address !=\"::1\" and\n /* insert false positives here */\n not process.name in (\"swi_fc.exe\", \"fsIPcam.exe\", \"IPCamera.exe\", \"MicrosoftEdgeCP.exe\", \"MicrosoftEdge.exe\", \"iexplore.exe\", \"chrome.exe\", \"msedge.exe\", \"opera.exe\", \"firefox.exe\")\n", "required_fields": [ { @@ -63,7 +63,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -84,5 +85,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_handle_access.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_handle_access.json index 63b939ff2e55c..eb1af7292bdfa 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_handle_access.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_handle_access.json @@ -11,7 +11,7 @@ "language": "eql", "license": "Elastic License v2", "name": "LSASS Memory Dump Handle Access", - "note": "## Triage and analysis\n\n### Investigating LSASS Memory Dump Handle Access\n\nLocal Security Authority Server Service (LSASS) is a process in Microsoft Windows operating systems that is responsible\nfor enforcing security policy on the system. It verifies users logging on to a Windows computer or server, handles\npassword changes, and creates access tokens.\n\nAdversaries may attempt to access credential material stored in LSASS process memory. After a user logs on,the system\ngenerates and stores a variety of credential materials in LSASS process memory. This is meant to facilitate single\nsign-on (SSO) ensuring a user isn\u2019t prompted each time resource access is requested. These credential materials can be\nharvested by an adversary using administrative user or SYSTEM privileges to conduct lateral movement using\n[alternate authentication material](https://attack.mitre.org/techniques/T1550/).\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- There should be very few or no false positives for this rule. If this activity is expected or noisy in your environment,\nconsider adding exceptions \u2014 preferably with a combination of user and command line conditions.\n- If the process is related to antivirus or endpoint detection and response solutions, validate that it is installed on\nthe correct path and signed with the company's valid digital signature.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Scope compromised credentials and disable the accounts.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n\nEnsure advanced audit policies for Windows are enabled, specifically:\nObject Access policies [Event ID 4656](https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4656) (Handle to an Object was Requested)\n\n```\nComputer Configuration >\nPolicies >\nWindows Settings >\nSecurity Settings >\nAdvanced Audit Policies Configuration >\nSystem Audit Policies >\nObject Access >\nAudit File System (Success,Failure)\nAudit Handle Manipulation (Success,Failure)\n```\n\nAlso, this event generates only if the object\u2019s [SACL](https://docs.microsoft.com/en-us/windows/win32/secauthz/access-control-lists) has the required access control entry (ACE) to handle the use of specific access rights.\n\nIf enabling an EQL rule on a non-elastic-agent index (such as beats) for versions <8.2, events will not define `event.ingested` and default fallback for EQL rules was not added until 8.2, so you will need to add a custom pipeline to populate `event.ingested` to @timestamp for this rule to work.", + "note": "## Triage and analysis\n\n### Investigating LSASS Memory Dump Handle Access\n\nLocal Security Authority Server Service (LSASS) is a process in Microsoft Windows operating systems that is responsible\nfor enforcing security policy on the system. It verifies users logging on to a Windows computer or server, handles\npassword changes, and creates access tokens.\n\nAdversaries may attempt to access credential material stored in LSASS process memory. After a user logs on,the system\ngenerates and stores a variety of credential materials in LSASS process memory. This is meant to facilitate single\nsign-on (SSO) ensuring a user isn\u2019t prompted each time resource access is requested. These credential materials can be\nharvested by an adversary using administrative user or SYSTEM privileges to conduct lateral movement using\n[alternate authentication material](https://attack.mitre.org/techniques/T1550/).\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- There should be very few or no false positives for this rule. If this activity is expected or noisy in your environment,\nconsider adding exceptions \u2014 preferably with a combination of user and command line conditions.\n- If the process is related to antivirus or endpoint detection and response solutions, validate that it is installed on\nthe correct path and signed with the company's valid digital signature.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Scope compromised credentials and disable the accounts.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n\nEnsure advanced audit policies for Windows are enabled, specifically:\nObject Access policies [Event ID 4656](https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4656) (Handle to an Object was Requested)\n\n```\nComputer Configuration >\nPolicies >\nWindows Settings >\nSecurity Settings >\nAdvanced Audit Policies Configuration >\nSystem Audit Policies >\nObject Access >\nAudit File System (Success,Failure)\nAudit Handle Manipulation (Success,Failure)\n```\n\nAlso, this event generates only if the object\u2019s [SACL](https://docs.microsoft.com/en-us/windows/win32/secauthz/access-control-lists) has the required access control entry (ACE) to handle the use of specific access rights.\n\nIf enabling an EQL rule on a non-elastic-agent index (such as beats) for versions <8.2, events will not define `event.ingested` and default fallback for EQL rules was not added until 8.2, so you will need to add a custom pipeline to populate `event.ingested` to @timestamp for this rule to work.", "query": "any where event.action == \"File System\" and event.code == \"4656\" and\n\n winlog.event_data.ObjectName : (\n \"?:\\\\Windows\\\\System32\\\\lsass.exe\",\n \"\\\\Device\\\\HarddiskVolume?\\\\Windows\\\\System32\\\\lsass.exe\",\n \"\\\\Device\\\\HarddiskVolume??\\\\Windows\\\\System32\\\\lsass.exe\") and\n\n /* The right to perform an operation controlled by an extended access right. */\n\n (winlog.event_data.AccessMask : (\"0x1fffff\" , \"0x1010\", \"0x120089\", \"0x1F3FFF\") or\n winlog.event_data.AccessMaskDescription : (\"READ_CONTROL\", \"Read from process memory\"))\n\n /* Common Noisy False Positives */\n\n and not winlog.event_data.ProcessName : (\n \"?:\\\\Program Files\\\\*.exe\",\n \"?:\\\\Program Files (x86)\\\\*.exe\",\n \"?:\\\\Windows\\\\system32\\\\wbem\\\\WmiPrvSE.exe\",\n \"?:\\\\Windows\\\\System32\\\\dllhost.exe\",\n \"?:\\\\Windows\\\\System32\\\\svchost.exe\",\n \"?:\\\\Windows\\\\System32\\\\msiexec.exe\",\n \"?:\\\\ProgramData\\\\Microsoft\\\\Windows Defender\\\\*.exe\",\n \"?:\\\\Windows\\\\explorer.exe\")\n", "references": [ "https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4656", @@ -61,7 +61,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -89,5 +90,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json index 05199fed31f61..5fa244d380ae1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json @@ -35,7 +35,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -56,5 +57,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_powershell_module.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_powershell_module.json index 0524d0dbb1a2e..f78eead09dea8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_powershell_module.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_powershell_module.json @@ -38,7 +38,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -66,5 +67,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mod_wdigest_security_provider.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mod_wdigest_security_provider.json index 018868f23fb20..d5a13d5f0285f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mod_wdigest_security_provider.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mod_wdigest_security_provider.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Modification of WDigest Security Provider", - "note": "## Triage and analysis\n\n### Investigating Modification of WDigest Security Provider\n\nIn Windows XP, Microsoft added support for a protocol known as WDigest. The WDigest protocol allows clients to send\ncleartext credentials to Hypertext Transfer Protocol (HTTP) and Simple Authentication Security Layer (SASL) applications\nbased on RFC 2617 and 2831. Windows versions up to 8 and 2012 store logon credentials in memory in plaintext by default,\nwhich is no longer the case with newer Windows versions.\n\nStill, attackers can force WDigest to store the passwords insecurely on the memory by modifying the\n`HKLM\\SYSTEM\\*ControlSet*\\Control\\SecurityProviders\\WDigest\\UseLogonCredential` registry key. This activity is\ncommonly related to the execution of credential dumping tools.\n\n#### Possible investigation steps\n\n- It is unlikely that the monitored registry key was modified legitimately in newer versions of Windows. Analysts should\ntreat any activity triggered from this rule with high priority as it typically represents an active adversary.\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Determine if credential dumping tools were run on the host, and retrieve and analyze suspicious executables:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Use process name, command line, and file hash to search for occurrences on other hosts.\n- Investigate potentially compromised accounts. Analysts can do this by searching for login events (for example, 4624) to the target\nhost after the registry modification.\n\n### False positive analysis\n\n- This modification should not happen legitimately. Any potential benign true positive (B-TP) should be mapped and\nmonitored by the security team, as these modifications expose the entire domain to credential compromises and\nconsequently unauthorized access.\n\n### Related rules\n\n- Mimikatz Powershell Module Activity - ac96ceb8-4399-4191-af1d-4feeac1f1f46\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Reimage the host operating system and restore compromised files to clean versions.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Modification of WDigest Security Provider\n\nIn Windows XP, Microsoft added support for a protocol known as WDigest. The WDigest protocol allows clients to send\ncleartext credentials to Hypertext Transfer Protocol (HTTP) and Simple Authentication Security Layer (SASL) applications\nbased on RFC 2617 and 2831. Windows versions up to 8 and 2012 store logon credentials in memory in plaintext by default,\nwhich is no longer the case with newer Windows versions.\n\nStill, attackers can force WDigest to store the passwords insecurely on the memory by modifying the\n`HKLM\\SYSTEM\\*ControlSet*\\Control\\SecurityProviders\\WDigest\\UseLogonCredential` registry key. This activity is\ncommonly related to the execution of credential dumping tools.\n\n#### Possible investigation steps\n\n- It is unlikely that the monitored registry key was modified legitimately in newer versions of Windows. Analysts should\ntreat any activity triggered from this rule with high priority as it typically represents an active adversary.\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Determine if credential dumping tools were run on the host, and retrieve and analyze suspicious executables:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Use process name, command line, and file hash to search for occurrences on other hosts.\n- Investigate potentially compromised accounts. Analysts can do this by searching for login events (for example, 4624) to the target\nhost after the registry modification.\n\n### False positive analysis\n\n- This modification should not happen legitimately. Any potential benign true positive (B-TP) should be mapped and\nmonitored by the security team, as these modifications expose the entire domain to credential compromises and\nconsequently unauthorized access.\n\n### Related rules\n\n- Mimikatz Powershell Module Activity - ac96ceb8-4399-4191-af1d-4feeac1f1f46\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Reimage the host operating system and restore compromised files to clean versions.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "registry where event.type : (\"creation\", \"change\") and\n registry.path :\n \"HKLM\\\\SYSTEM\\\\*ControlSet*\\\\Control\\\\SecurityProviders\\\\WDigest\\\\UseLogonCredential\"\n and registry.data.strings : (\"1\", \"0x00000001\") and\n not (process.executable : \"?:\\\\Windows\\\\System32\\\\svchost.exe\" and user.id : \"S-1-5-18\")\n", "references": [ "https://www.csoonline.com/article/3438824/how-to-detect-and-halt-credential-theft-via-windows-wdigest.html", @@ -55,7 +55,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -83,5 +84,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_moving_registry_hive_via_smb.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_moving_registry_hive_via_smb.json index ca2bae7cdc87d..9da4639332581 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_moving_registry_hive_via_smb.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_moving_registry_hive_via_smb.json @@ -48,7 +48,8 @@ "Windows", "Threat Detection", "Lateral Movement", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -98,5 +99,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_minidump.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_minidump.json index a8be93f64e493..aa5dc5f8288d6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_minidump.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_minidump.json @@ -42,7 +42,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -92,5 +93,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_request_ticket.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_request_ticket.json index 8df600b289265..0caeb8f4cd34e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_request_ticket.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_request_ticket.json @@ -38,7 +38,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -93,5 +94,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce.json index 0dde40f82f1ce..bd28407a2d53c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce.json @@ -10,7 +10,8 @@ ], "language": "eql", "license": "Elastic License v2", - "name": "Potential SSH Brute Force Detected", + "name": "Potential Linux SSH Brute Force Detected", + "note": "## Triage and analysis\n\n### Investigating Potential SSH Brute Force Attack\n\nThe rule identifies consecutive SSH login failures targeting a user account from the same source IP address to the\nsame target host indicating brute force login attempts.\n\n#### Possible investigation steps\n\n- Investigate the login failure user name(s).\n- Investigate the source IP address of the failed ssh login attempt(s).\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Identify the source and the target computer and their roles in the IT environment.\n\n### False positive analysis\n\n- Authentication misconfiguration or obsolete credentials.\n- Service account password expired.\n- Infrastructure or availability issue.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified.\n- Reset passwords for these accounts and other potentially compromised credentials.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n\n", "query": "sequence by host.id, source.ip, user.name with maxspan=10s\n [authentication where event.action in (\"ssh_login\", \"user_login\") and\n event.outcome == \"failure\" and source.ip != null and source.ip != \"0.0.0.0\" and source.ip != \"::\" ] with runs=10\n", "required_fields": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce_root.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce_root.json index a15fa38e979a1..f540d3ae3202c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce_root.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce_root.json @@ -11,6 +11,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Potential SSH Brute Force Detected on Privileged Account", + "note": "## Triage and analysis\n\n### Investigating Potential SSH Brute Force Attack on Privileged Account\n\nThe rule identifies consecutive SSH login failures targeting a privileged (root) account from the same source IP\naddress to the same target host indicating brute force login attempts.\n\n#### Possible investigation steps\n\n- Investigate the login failure on privileged account(s).\n- Investigate the source IP address of the failed ssh login attempt(s).\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Identify the source and the target computer and their roles in the IT environment.\n\n### False positive analysis\n- Authentication misconfiguration or obsolete credentials.\n- Service account password expired.\n- Infrastructure or availability issue.\n\n### Response and remediation\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified.\n- Reset passwords for these accounts and other potentially compromised credentials.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n\n", "query": "sequence by host.id, source.ip with maxspan=10s\n [authentication where event.action in (\"ssh_login\", \"user_login\") and\n event.outcome == \"failure\" and source.ip != null and source.ip != \"0.0.0.0\" and\n source.ip != \"::\" and user.name in (\"*root*\" , \"*admin*\")] with runs=3\n", "required_fields": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_ssh_bruteforce.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_macos_ssh_bruteforce.json similarity index 95% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_ssh_bruteforce.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_macos_ssh_bruteforce.json index 89519f49a1170..0f420cfb6d08f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_ssh_bruteforce.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_macos_ssh_bruteforce.json @@ -10,7 +10,7 @@ ], "language": "kuery", "license": "Elastic License v2", - "name": "Potential SSH Brute Force Detected", + "name": "Potential macOS SSH Brute Force Detected", "query": "event.category:process and event.type:start and process.name:\"sshd-keygen-wrapper\" and process.parent.name:launchd\n", "references": [ "https://themittenmac.com/detecting-ssh-activity-via-process-monitoring/" @@ -71,5 +71,5 @@ "value": 20 }, "type": "threshold", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_remote_sam_secretsdump.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_remote_sam_secretsdump.json index 41d744c1ea8b1..1b6a0498a8f52 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_remote_sam_secretsdump.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_remote_sam_secretsdump.json @@ -89,7 +89,8 @@ "Windows", "Threat Detection", "Lateral Movement", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -131,5 +132,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_secretsmanager_getsecretvalue.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_secretsmanager_getsecretvalue.json index df0d68a13f901..2ec5b4d9a877b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_secretsmanager_getsecretvalue.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_secretsmanager_getsecretvalue.json @@ -57,7 +57,8 @@ "Continuous Monitoring", "SecOps", "Data Protection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -78,5 +79,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_seenabledelegationprivilege_assigned_to_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_seenabledelegationprivilege_assigned_to_user.json index 8421a442c4724..1992b3a85cf93 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_seenabledelegationprivilege_assigned_to_user.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_seenabledelegationprivilege_assigned_to_user.json @@ -47,7 +47,8 @@ "Windows", "Threat Detection", "Credential Access", - "Active Directory" + "Active Directory", + "has_guide" ], "threat": [ { @@ -71,5 +72,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_spn_attribute_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_spn_attribute_modified.json index 2b6866599d3da..8fb978965654c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_spn_attribute_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_spn_attribute_modified.json @@ -53,7 +53,8 @@ "Windows", "Threat Detection", "Credential Access", - "Active Directory" + "Active Directory", + "has_guide" ], "threat": [ { @@ -81,5 +82,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_winreg_access_via_sebackup_priv.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_winreg_access_via_sebackup_priv.json index 2d2c2fadf1518..d8e9a61e71b4e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_winreg_access_via_sebackup_priv.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_winreg_access_via_sebackup_priv.json @@ -54,7 +54,8 @@ "Windows", "Threat Detection", "Lateral Movement", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -96,5 +97,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_symbolic_link_to_shadow_copy_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_symbolic_link_to_shadow_copy_created.json index 6ae0580651a8c..0286e35f7d049 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_symbolic_link_to_shadow_copy_created.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_symbolic_link_to_shadow_copy_created.json @@ -55,7 +55,8 @@ "Host", "Windows", "Threat Detection", - "Credential Access" + "Credential Access", + "has_guide" ], "threat": [ { @@ -76,5 +77,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_amsienable_key_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_amsienable_key_mod.json index 3e6986451938e..52adb1756ad50 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_amsienable_key_mod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_amsienable_key_mod.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Modification of AmsiEnable Registry Key", - "note": "## Triage and analysis\n\n### Investigating Modification of AmsiEnable Registry Key\n\nThe Windows Antimalware Scan Interface (AMSI) is a versatile interface standard that allows your applications and\nservices to integrate with any antimalware product that's present on a machine. AMSI provides integration with multiple\nWindows components, ranging from User Account Control (UAC) to VBA Macros.\n\nSince AMSI is widely used across security products for increased visibility, attackers can disable it to evade\ndetections that rely on it.\n\nThis rule monitors the modifications to the Software\\Microsoft\\Windows Script\\Settings\\AmsiEnable registry key.\n\n#### Possible investigation steps\n\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate the execution of scripts and macros after the registry modification.\n- Retrieve scripts or Microsoft Office files and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Use process name, command line, and file hash to search for occurrences on other hosts.\n\n### False positive analysis\n\n- This modification should not happen legitimately. Any potential benign true positive (B-TP) should be mapped and\nmonitored by the security team, as these modifications expose the host to malware infections.\n\n### Related rules\n\n- Microsoft Windows Defender Tampering - fe794edd-487f-4a90-b285-3ee54f2af2d3\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Delete or set the key to its default value.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Modification of AmsiEnable Registry Key\n\nThe Windows Antimalware Scan Interface (AMSI) is a versatile interface standard that allows your applications and\nservices to integrate with any antimalware product that's present on a machine. AMSI provides integration with multiple\nWindows components, ranging from User Account Control (UAC) to VBA Macros.\n\nSince AMSI is widely used across security products for increased visibility, attackers can disable it to evade\ndetections that rely on it.\n\nThis rule monitors the modifications to the Software\\Microsoft\\Windows Script\\Settings\\AmsiEnable registry key.\n\n#### Possible investigation steps\n\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate the execution of scripts and macros after the registry modification.\n- Retrieve scripts or Microsoft Office files and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Use process name, command line, and file hash to search for occurrences on other hosts.\n\n### False positive analysis\n\n- This modification should not happen legitimately. Any potential benign true positive (B-TP) should be mapped and\nmonitored by the security team, as these modifications expose the host to malware infections.\n\n### Related rules\n\n- Microsoft Windows Defender Tampering - fe794edd-487f-4a90-b285-3ee54f2af2d3\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Delete or set the key to its default value.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "registry where event.type in (\"creation\", \"change\") and\n registry.path : (\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows Script\\\\Settings\\\\AmsiEnable\",\n \"HKU\\\\*\\\\Software\\\\Microsoft\\\\Windows Script\\\\Settings\\\\AmsiEnable\"\n ) and\n registry.data.strings: (\"0\", \"0x00000000\")\n", "references": [ "https://hackinparis.com/data/slides/2019/talks/HIP2019-Dominic_Chell-Cracking_The_Perimeter_With_Sharpshooter.pdf", @@ -44,7 +44,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -72,5 +73,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_service_principal_addition.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_service_principal_addition.json index 73223f74a8c37..8b409bdb63681 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_service_principal_addition.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_service_principal_addition.json @@ -53,7 +53,8 @@ "Azure", "Continuous Monitoring", "SecOps", - "Identity and Access" + "Identity and Access", + "has_guide" ], "threat": [ { @@ -81,5 +82,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_console_history.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_console_history.json index 191502d44c71b..972c69b5052da 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_console_history.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_console_history.json @@ -50,7 +50,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -78,5 +79,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json index fec3c5dd2f0e2..ff068224efa5a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json index a79fba0714765..eed3ed289c9c1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json @@ -29,7 +29,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -57,5 +58,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json index fa2c001a1e37a..cb0f9d549a04e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json @@ -60,7 +60,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Log Auditing" + "Log Auditing", + "has_guide" ], "threat": [ { @@ -88,5 +89,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json index c0f990f8e496e..97867f74d0557 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json @@ -60,7 +60,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Log Auditing" + "Log Auditing", + "has_guide" ], "threat": [ { @@ -88,5 +89,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json index 3f0d5960e41f6..6fc0a85d8e9cc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json @@ -60,7 +60,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Monitoring" + "Monitoring", + "has_guide" ], "threat": [ { @@ -88,5 +89,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json index 15b0818b4d3d6..9113f5907dd3b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json @@ -56,7 +56,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Monitoring" + "Monitoring", + "has_guide" ], "threat": [ { @@ -84,5 +85,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_create_mod_root_certificate.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_create_mod_root_certificate.json index 6221668580ee1..2264c363bb04c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_create_mod_root_certificate.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_create_mod_root_certificate.json @@ -15,7 +15,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Creation or Modification of Root Certificate", - "note": "## Triage and analysis\n\n### Investigating Creation or Modification of Root Certificate\n\nRoot certificates are the primary level of certifications that tell a browser that the communication is trusted and\nlegitimate. This verification is based upon the identification of a certification authority. Windows\nadds several trusted root certificates so browsers can use them to communicate with websites.\n\n[Check out this post](https://www.thewindowsclub.com/what-are-root-certificates-windows) for more details on root certificates and the involved cryptography.\n\nThis rule identifies the creation or modification of a root certificate by monitoring registry modifications. The\ninstallation of a malicious root certificate would allow an attacker the ability to masquerade malicious files as valid\nsigned components from any entity (for example, Microsoft). It could also allow an attacker to decrypt SSL traffic.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed by the subject process such as network connections, other registry or file\nmodifications, and any spawned child processes.\n- If one of the processes is suspicious, retrieve it and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This detection may be triggered by certain applications that install root certificates for the purpose of inspecting\nSSL traffic. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove the malicious certificate from the root certificate store.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Creation or Modification of Root Certificate\n\nRoot certificates are the primary level of certifications that tell a browser that the communication is trusted and\nlegitimate. This verification is based upon the identification of a certification authority. Windows\nadds several trusted root certificates so browsers can use them to communicate with websites.\n\n[Check out this post](https://www.thewindowsclub.com/what-are-root-certificates-windows) for more details on root certificates and the involved cryptography.\n\nThis rule identifies the creation or modification of a root certificate by monitoring registry modifications. The\ninstallation of a malicious root certificate would allow an attacker the ability to masquerade malicious files as valid\nsigned components from any entity (for example, Microsoft). It could also allow an attacker to decrypt SSL traffic.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed by the subject process such as network connections, other registry or file\nmodifications, and any spawned child processes.\n- If one of the processes is suspicious, retrieve it and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This detection may be triggered by certain applications that install root certificates for the purpose of inspecting\nSSL traffic. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove the malicious certificate from the root certificate store.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "registry where event.type in (\"creation\", \"change\") and\n registry.path :\n (\n \"HKLM\\\\Software\\\\Microsoft\\\\SystemCertificates\\\\Root\\\\Certificates\\\\*\\\\Blob\",\n \"HKLM\\\\Software\\\\Microsoft\\\\SystemCertificates\\\\AuthRoot\\\\Certificates\\\\*\\\\Blob\",\n \"HKLM\\\\Software\\\\Policies\\\\Microsoft\\\\SystemCertificates\\\\Root\\\\Certificates\\\\*\\\\Blob\",\n \"HKLM\\\\Software\\\\Policies\\\\Microsoft\\\\SystemCertificates\\\\AuthRoot\\\\Certificates\\\\*\\\\Blob\"\n ) and\n not process.executable :\n (\"?:\\\\Program Files\\\\*.exe\",\n \"?:\\\\Program Files (x86)\\\\*.exe\",\n \"?:\\\\Windows\\\\System32\\\\*.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\*.exe\",\n \"?:\\\\Windows\\\\Sysmon64.exe\",\n \"?:\\\\Windows\\\\Sysmon.exe\",\n \"?:\\\\ProgramData\\\\Microsoft\\\\Windows Defender\\\\Platform\\\\*\\\\MsMpEng.exe\",\n \"?:\\\\Windows\\\\WinSxS\\\\*.exe\",\n \"?:\\\\Windows\\\\UUS\\\\amd64\\\\MoUsoCoreWorker.exe\")\n", "references": [ "https://posts.specterops.io/code-signing-certificate-cloning-attacks-and-defenses-6f98657fc6ec", @@ -47,7 +47,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -75,5 +76,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_disabled_via_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_disabled_via_registry.json index 4bf9babea192f..5b39ffc36ed8e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_disabled_via_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_disabled_via_registry.json @@ -48,7 +48,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -81,5 +82,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json index 90650abf7b9bb..5a74bfc9b1664 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Windows Defender Exclusions Added via PowerShell", - "note": "## Triage and analysis\n\n### Investigating Windows Defender Exclusions Added via PowerShell\n\nMicrosoft Windows Defender is an antivirus product built into Microsoft Windows. Since this software product is\nused to prevent and stop malware, it's important to monitor what specific exclusions are made to the product's configuration\nsettings. These can often be signs of an adversary or malware trying to bypass Windows Defender's capabilities. One of\nthe more notable [examples](https://www.cyberbit.com/blog/endpoint-security/latest-trickbot-variant-has-new-tricks-up-its-sleeve/)\nwas observed in 2018 where Trickbot incorporated mechanisms to disable Windows Defender to avoid detection.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Examine the exclusion in order to determine the intent behind it.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- If the exclusion specifies a suspicious file or path, retrieve the file(s) and determine if malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This rule has a high chance to produce false positives due to how often network administrators legitimately configure\nexclusions. In order to validate the activity further, review the specific exclusion and its intent. There are many\nlegitimate reasons for exclusions, so it's important to gain context.\n\n### Related rules\n\n- Windows Defender Disabled via Registry Modification - 2ffa1f1e-b6db-47fa-994b-1512743847eb\n- Disabling Windows Defender Security Settings via PowerShell - c8cccb06-faf2-4cd5-886e-2c9636cfcb87\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Exclusion lists for antimalware capabilities should always be routinely monitored for review.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Windows Defender Exclusions Added via PowerShell\n\nMicrosoft Windows Defender is an antivirus product built into Microsoft Windows. Since this software product is\nused to prevent and stop malware, it's important to monitor what specific exclusions are made to the product's configuration\nsettings. These can often be signs of an adversary or malware trying to bypass Windows Defender's capabilities. One of\nthe more notable [examples](https://www.cyberbit.com/blog/endpoint-security/latest-trickbot-variant-has-new-tricks-up-its-sleeve/)\nwas observed in 2018 where Trickbot incorporated mechanisms to disable Windows Defender to avoid detection.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Examine the exclusion in order to determine the intent behind it.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- If the exclusion specifies a suspicious file or path, retrieve the file(s) and determine if malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This rule has a high chance to produce false positives due to how often network administrators legitimately configure\nexclusions. In order to validate the activity further, review the specific exclusion and its intent. There are many\nlegitimate reasons for exclusions, so it's important to gain context.\n\n### Related rules\n\n- Windows Defender Disabled via Registry Modification - 2ffa1f1e-b6db-47fa-994b-1512743847eb\n- Disabling Windows Defender Security Settings via PowerShell - c8cccb06-faf2-4cd5-886e-2c9636cfcb87\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Exclusion lists for antimalware capabilities should always be routinely monitored for review.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n (process.name : (\"powershell.exe\", \"pwsh.exe\", \"powershell_ise.exe\") or process.pe.original_file_name in (\"powershell.exe\", \"pwsh.dll\", \"powershell_ise.exe\")) and\n process.args : (\"*Add-MpPreference*\", \"*Set-MpPreference*\") and\n process.args : (\"*-Exclusion*\")\n", "references": [ "https://www.bitdefender.com/files/News/CaseStudies/study/400/Bitdefender-PR-Whitepaper-MosaicLoader-creat5540-en-EN.pdf" @@ -48,7 +48,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -103,5 +104,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_posh_scriptblocklogging.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_posh_scriptblocklogging.json index 3132045aeb9f1..f4c3273953dca 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_posh_scriptblocklogging.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_posh_scriptblocklogging.json @@ -43,7 +43,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -71,5 +72,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json index 912596ec4188f..a07759a72e73f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json @@ -40,7 +40,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_defender_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_defender_powershell.json index 9629c53ead56c..21c0bd54b831c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_defender_powershell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_defender_powershell.json @@ -51,7 +51,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -79,5 +80,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_logs.json index 24dde4c55f75b..b6c0b9ceceb53 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_logs.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_logs.json @@ -51,7 +51,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json index 6cd510f9c638c..9104509c8576e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json @@ -60,7 +60,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Log Auditing" + "Log Auditing", + "has_guide" ], "threat": [ { @@ -88,5 +89,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json index c90adc84eb4b7..5ddaa9cdac60a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json index b23b4a422fe4c..5013d8a5d731a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json @@ -15,7 +15,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Enable Host Network Discovery via Netsh", - "note": "## Triage and analysis\n\n### Investigating Enable Host Network Discovery via Netsh\n\nThe Windows Defender Firewall is a native component that provides host-based, two-way network traffic filtering for a\ndevice and blocks unauthorized network traffic flowing into or out of the local device.\n\nAttackers can enable Network Discovery on the Windows firewall to find other systems present in the same network. Systems\nwith this setting enabled will communicate with other systems using broadcast messages, which can be used to identify\ntargets for lateral movement. This rule looks for the setup of this setting using the netsh utility.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behaviors in the alert timeframe.\n\n### False positive analysis\n\n- This mechanism can be used legitimately. Analysts can dismiss the alert if the administrator is aware of the activity\nand there are justifications for this configuration.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Disable Network Discovery:\n - Using netsh: `netsh advfirewall firewall set rule group=\"Network Discovery\" new enable=No`\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Review the privileges assigned to the involved users to ensure that the least privilege principle is being followed.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Enable Host Network Discovery via Netsh\n\nThe Windows Defender Firewall is a native component that provides host-based, two-way network traffic filtering for a\ndevice and blocks unauthorized network traffic flowing into or out of the local device.\n\nAttackers can enable Network Discovery on the Windows firewall to find other systems present in the same network. Systems\nwith this setting enabled will communicate with other systems using broadcast messages, which can be used to identify\ntargets for lateral movement. This rule looks for the setup of this setting using the netsh utility.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n\n### False positive analysis\n\n- This mechanism can be used legitimately. Analysts can dismiss the alert if the administrator is aware of the activity\nand there are justifications for this configuration.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Disable Network Discovery:\n - Using netsh: `netsh advfirewall firewall set rule group=\"Network Discovery\" new enable=No`\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Review the privileges assigned to the involved users to ensure that the least privilege principle is being followed.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\nprocess.name : \"netsh.exe\" and\nprocess.args : (\"firewall\", \"advfirewall\") and process.args : \"group=Network Discovery\" and process.args : \"enable=Yes\"\n", "required_fields": [ { @@ -43,7 +43,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -71,5 +72,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json index faa6600e315bd..a3a651443340c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json @@ -15,7 +15,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Microsoft Build Engine Started by an Office Application", - "note": "## Triage and analysis\n\n### Investigating Microsoft Build Engine Started by an Office Application\n\nMicrosoft Office (MS Office) is a suite of applications designed to help with productivity and completing common tasks on a computer.\nYou can create and edit documents containing text and images, work with data in spreadsheets and databases, and create\npresentations and posters. As it is some of the most-used software across companies, MS Office is frequently targeted\nfor initial access. It also has a wide variety of capabilities that attackers can take advantage of.\n\nThe Microsoft Build Engine is a platform for building applications. This engine, also known as MSBuild, provides an XML\nschema for a project file that controls how the build platform processes and builds software, and can be abused to proxy\nexecution of code.\n\nThis rule looks for the `Msbuild.exe` utility spawned by MS Office programs. This is generally the result of the\nexecution of malicious documents.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate abnormal behaviors observed by the subject process, such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve MS Office documents received and opened by the user that could cause this behavior. Common locations include,\nbut are not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Microsoft Build Engine Started by an Office Application\n\nMicrosoft Office (MS Office) is a suite of applications designed to help with productivity and completing common tasks on a computer.\nYou can create and edit documents containing text and images, work with data in spreadsheets and databases, and create\npresentations and posters. As it is some of the most-used software across companies, MS Office is frequently targeted\nfor initial access. It also has a wide variety of capabilities that attackers can take advantage of.\n\nThe Microsoft Build Engine is a platform for building applications. This engine, also known as MSBuild, provides an XML\nschema for a project file that controls how the build platform processes and builds software, and can be abused to proxy\nexecution of code.\n\nThis rule looks for the `Msbuild.exe` utility spawned by MS Office programs. This is generally the result of the\nexecution of malicious documents.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate abnormal behaviors observed by the subject process, such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve MS Office documents received and opened by the user that could cause this behavior. Common locations include,\nbut are not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.name : \"MSBuild.exe\" and\n process.parent.name : (\"eqnedt32.exe\",\n \"excel.exe\",\n \"fltldr.exe\",\n \"msaccess.exe\",\n \"mspub.exe\",\n \"outlook.exe\",\n \"powerpnt.exe\",\n \"winword.exe\" )\n", "references": [ "https://blog.talosintelligence.com/2020/02/building-bypass-with-msbuild.html" @@ -46,7 +46,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_defender_tampering.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_defender_tampering.json index 24a214f445d77..89a34647ca08c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_defender_tampering.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_defender_tampering.json @@ -53,7 +53,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -74,5 +75,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ms_office_suspicious_regmod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ms_office_suspicious_regmod.json index ccb198f287caa..1d50e5192b479 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ms_office_suspicious_regmod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ms_office_suspicious_regmod.json @@ -11,7 +11,7 @@ "language": "eql", "license": "Elastic License v2", "name": "MS Office Macro Security Registry Modifications", - "note": "## Triage and analysis\n\n### Investigating MS Office Macro Security Registry Modifications\n\nMacros are small programs that are used to automate repetitive tasks in Microsoft Office applications.\nHistorically, macros have been used for a variety of reasons -- from automating part of a job, to\nbuilding entire processes and data flows. Macros are written in Visual Basic for Applications (VBA) and are saved as\npart of Microsoft Office files.\n\nMacros are often created for legitimate reasons, but they can also be written by attackers to gain access, harm a\nsystem, or bypass other security controls such as application allow listing. In fact, exploitation from malicious macros\nis one of the top ways that organizations are compromised today. These attacks are often conducted through phishing or\nspear phishing campaigns.\n\nAttackers can convince victims to modify Microsoft Office security settings, so their macros are trusted by default and\nno warnings are displayed when they are executed. These settings include:\n\n* *Trust access to the VBA project object model* - When enabled, Microsoft Office will trust all macros and run any code\nwithout showing a security warning or requiring user permission.\n* *VbaWarnings* - When set to 1, Microsoft Office will trust all macros and run any code without showing a security\nwarning or requiring user permission.\n\nThis rule looks for registry changes affecting the conditions above.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the user and check if the change was done manually.\n- Verify whether malicious macros were executed after the registry change.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve recently executed Office documents and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity should not happen legitimately. The security team should address any potential benign true\npositives (B-TPs), as this configuration can put the user and the domain at risk.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Reset the registry key value.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Explore using GPOs to manage security settings for Microsoft Office macros.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating MS Office Macro Security Registry Modifications\n\nMacros are small programs that are used to automate repetitive tasks in Microsoft Office applications.\nHistorically, macros have been used for a variety of reasons -- from automating part of a job, to\nbuilding entire processes and data flows. Macros are written in Visual Basic for Applications (VBA) and are saved as\npart of Microsoft Office files.\n\nMacros are often created for legitimate reasons, but they can also be written by attackers to gain access, harm a\nsystem, or bypass other security controls such as application allow listing. In fact, exploitation from malicious macros\nis one of the top ways that organizations are compromised today. These attacks are often conducted through phishing or\nspear phishing campaigns.\n\nAttackers can convince victims to modify Microsoft Office security settings, so their macros are trusted by default and\nno warnings are displayed when they are executed. These settings include:\n\n* *Trust access to the VBA project object model* - When enabled, Microsoft Office will trust all macros and run any code\nwithout showing a security warning or requiring user permission.\n* *VbaWarnings* - When set to 1, Microsoft Office will trust all macros and run any code without showing a security\nwarning or requiring user permission.\n\nThis rule looks for registry changes affecting the conditions above.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the user and check if the change was done manually.\n- Verify whether malicious macros were executed after the registry change.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve recently executed Office documents and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity should not happen legitimately. The security team should address any potential benign true\npositives (B-TPs), as this configuration can put the user and the domain at risk.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Reset the registry key value.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Explore using GPOs to manage security settings for Microsoft Office macros.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "registry where event.type == \"change\" and\n registry.path : (\n \"HKU\\\\S-1-5-21-*\\\\SOFTWARE\\\\Microsoft\\\\Office\\\\*\\\\Security\\\\AccessVBOM\",\n \"HKU\\\\S-1-5-21-*\\\\SOFTWARE\\\\Microsoft\\\\Office\\\\*\\\\Security\\\\VbaWarnings\"\n ) and\n registry.data.strings == \"0x00000001\" and\n process.name : (\"cscript.exe\", \"wscript.exe\", \"mshta.exe\", \"mshta.exe\", \"winword.exe\", \"excel.exe\")\n", "required_fields": [ { @@ -44,7 +44,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -87,5 +88,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_assembly_load.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_assembly_load.json index f2c188f102fa3..56df918e940ec 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_assembly_load.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_assembly_load.json @@ -11,7 +11,7 @@ "language": "kuery", "license": "Elastic License v2", "name": "Suspicious .NET Reflection via PowerShell", - "note": "## Triage and analysis\n\n### Investigating Suspicious .NET Reflection via PowerShell\n\nPowerShell is one of the main tools system administrators use for automation, report routines, and other tasks. This\nmakes it available for use in various environments, and creates an attractive way for attackers to execute code.\n\nAttackers can use .NET reflection to load PEs and DLLs in memory. These payloads are commonly embedded in the script,\nwhich can circumvent file-based security protections.\n\n#### Possible investigation steps\n\n- Examine the script content that triggered the detection; look for suspicious DLL imports, collection or exfiltration\ncapabilities, suspicious functions, encoded or compressed data, and other potentially malicious characteristics.\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Examine file or network events from the involved PowerShell process for suspicious behavior.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Evaluate whether the user needs to use PowerShell to complete tasks.\n- Retrieve the script and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately outside engineering or IT business units. As long as the analyst did\nnot identify malware or suspicious activity related to the user or host, this alert can be dismissed.\n\n### Related rules\n\n- PowerShell PSReflect Script - 56f2e9b5-4803-4e44-a0a4-a52dc79d57fe\n- Potential Process Injection via PowerShell - 2e29e96a-b67c-455a-afe4-de6183431d0d\n- PowerShell Suspicious Payload Encoded and Compressed - 81fe9dc6-a2d7-4192-a2d8-eed98afc766a\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, Intune, or similar software.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Suspicious .NET Reflection via PowerShell\n\nPowerShell is one of the main tools system administrators use for automation, report routines, and other tasks. This\nmakes it available for use in various environments, and creates an attractive way for attackers to execute code.\n\nAttackers can use .NET reflection to load PEs and DLLs in memory. These payloads are commonly embedded in the script,\nwhich can circumvent file-based security protections.\n\n#### Possible investigation steps\n\n- Examine the script content that triggered the detection; look for suspicious DLL imports, collection or exfiltration\ncapabilities, suspicious functions, encoded or compressed data, and other potentially malicious characteristics.\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Examine file or network events from the involved PowerShell process for suspicious behavior.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Evaluate whether the user needs to use PowerShell to complete tasks.\n- Retrieve the script and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately outside engineering or IT business units. As long as the analyst did\nnot identify malware or suspicious activity related to the user or host, this alert can be dismissed.\n\n### Related rules\n\n- PowerShell PSReflect Script - 56f2e9b5-4803-4e44-a0a4-a52dc79d57fe\n- Potential Process Injection via PowerShell - 2e29e96a-b67c-455a-afe4-de6183431d0d\n- PowerShell Suspicious Payload Encoded and Compressed - 81fe9dc6-a2d7-4192-a2d8-eed98afc766a\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, Intune, or similar software.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "event.category:process and\n powershell.file.script_block_text : (\n \"[System.Reflection.Assembly]::Load\" or\n \"[Reflection.Assembly]::Load\"\n )\n", "references": [ "https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.load" @@ -37,7 +37,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -92,5 +93,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_compressed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_compressed.json index 0918910210f5e..dec606a855dcb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_compressed.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_compressed.json @@ -14,7 +14,7 @@ "language": "kuery", "license": "Elastic License v2", "name": "PowerShell Suspicious Payload Encoded and Compressed", - "note": "## Triage and analysis\n\n### Investigating PowerShell Suspicious Payload Encoded and Compressed\n\nPowerShell is one of the main tools system administrators use for automation, report routines, and other tasks. This\nmakes it available for use in various environments, and creates an attractive way for attackers to execute code.\n\nAttackers can embed compressed and encoded payloads in scripts to load directly into the memory without touching the\ndisk. This strategy can circumvent string and file-based security protections.\n\n#### Possible investigation steps\n\n- Examine the script content that triggered the detection; look for suspicious DLL imports, collection or exfiltration\ncapabilities, suspicious functions, encoded or compressed data, and other potentially malicious characteristics.\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Examine file or network events from the involved PowerShell process for suspicious behavior.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Evaluate whether the user needs to use PowerShell to complete tasks.\n- Retrieve the script and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately outside engineering or IT business units. As long as the analyst did\nnot identify malware or suspicious activity related to the user or host, this alert can be dismissed.\n\n### Related rules\n\n- PowerShell PSReflect Script - 56f2e9b5-4803-4e44-a0a4-a52dc79d57fe\n- Potential Process Injection via PowerShell - 2e29e96a-b67c-455a-afe4-de6183431d0d\n- Suspicious .NET Reflection via PowerShell - e26f042e-c590-4e82-8e05-41e81bd822ad\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, Intune, or similar software.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating PowerShell Suspicious Payload Encoded and Compressed\n\nPowerShell is one of the main tools system administrators use for automation, report routines, and other tasks. This\nmakes it available for use in various environments, and creates an attractive way for attackers to execute code.\n\nAttackers can embed compressed and encoded payloads in scripts to load directly into the memory without touching the\ndisk. This strategy can circumvent string and file-based security protections.\n\n#### Possible investigation steps\n\n- Examine the script content that triggered the detection; look for suspicious DLL imports, collection or exfiltration\ncapabilities, suspicious functions, encoded or compressed data, and other potentially malicious characteristics.\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Examine file or network events from the involved PowerShell process for suspicious behavior.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Evaluate whether the user needs to use PowerShell to complete tasks.\n- Retrieve the script and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately outside engineering or IT business units. As long as the analyst did\nnot identify malware or suspicious activity related to the user or host, this alert can be dismissed.\n\n### Related rules\n\n- PowerShell PSReflect Script - 56f2e9b5-4803-4e44-a0a4-a52dc79d57fe\n- Potential Process Injection via PowerShell - 2e29e96a-b67c-455a-afe4-de6183431d0d\n- Suspicious .NET Reflection via PowerShell - e26f042e-c590-4e82-8e05-41e81bd822ad\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, Intune, or similar software.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "event.category:process and\n powershell.file.script_block_text : (\n (\n \"System.IO.Compression.DeflateStream\" or\n \"System.IO.Compression.GzipStream\" or\n \"IO.Compression.DeflateStream\" or\n \"IO.Compression.GzipStream\"\n ) and\n FromBase64String\n )\n", "required_fields": [ { @@ -37,7 +37,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -85,5 +86,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_process_injection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_process_injection.json index 53aa8459e996d..686591b1738ab 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_process_injection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_process_injection.json @@ -42,7 +42,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -75,5 +76,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_powershell_windows_firewall_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_powershell_windows_firewall_disabled.json index 5cc10bf316cdb..9f870734840dd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_powershell_windows_firewall_disabled.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_powershell_windows_firewall_disabled.json @@ -15,7 +15,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Windows Firewall Disabled via PowerShell", - "note": "## Triage and analysis\n\n### Investigating Windows Firewall Disabled via PowerShell\n\nWindows Defender Firewall is a native component that provides host-based, two-way network traffic filtering for a\ndevice and blocks unauthorized network traffic flowing into or out of the local device.\n\nAttackers can disable the Windows firewall or its rules to enable lateral movement and command and control activity.\n\nThis rule identifies patterns related to disabling the Windows firewall or its rules using the `Set-NetFirewallProfile`\nPowerShell cmdlet.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behaviors in the alert timeframe.\n\n### False positive analysis\n\n- This mechanism can be used legitimately. Check whether the user is an administrator and is legitimately performing\ntroubleshooting.\n- In case of an allowed benign true positive (B-TP), assess adding rules to allow needed traffic and re-enable the firewall.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Re-enable the firewall with its desired configurations.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Review the privileges assigned to the involved users to ensure that the least privilege principle is being followed.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Windows Firewall Disabled via PowerShell\n\nWindows Defender Firewall is a native component that provides host-based, two-way network traffic filtering for a\ndevice and blocks unauthorized network traffic flowing into or out of the local device.\n\nAttackers can disable the Windows firewall or its rules to enable lateral movement and command and control activity.\n\nThis rule identifies patterns related to disabling the Windows firewall or its rules using the `Set-NetFirewallProfile`\nPowerShell cmdlet.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n\n### False positive analysis\n\n- This mechanism can be used legitimately. Check whether the user is an administrator and is legitimately performing\ntroubleshooting.\n- In case of an allowed benign true positive (B-TP), assess adding rules to allow needed traffic and re-enable the firewall.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Re-enable the firewall with its desired configurations.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Review the privileges assigned to the involved users to ensure that the least privilege principle is being followed.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.action == \"start\" and\n (process.name : (\"powershell.exe\", \"pwsh.exe\", \"powershell_ise.exe\") or process.pe.original_file_name == \"PowerShell.EXE\") and\n process.args : \"*Set-NetFirewallProfile*\" and\n (process.args : \"*-Enabled*\" and process.args : \"*False*\") and\n (process.args : \"*-All*\" or process.args : (\"*Public*\", \"*Domain*\", \"*Private*\"))\n", "references": [ "https://docs.microsoft.com/en-us/powershell/module/netsecurity/set-netfirewallprofile?view=windowsserver2019-ps", @@ -54,7 +54,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -82,5 +83,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_access_direct_syscall.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_access_direct_syscall.json index ee61888d446e1..d7f255f981c3a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_access_direct_syscall.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_access_direct_syscall.json @@ -11,7 +11,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Suspicious Process Access via Direct System Call", - "note": "## Triage and analysis\n\n### Investigating Suspicious Process Access via Direct System Call\n\nEndpoint security solutions usually hook userland Windows APIs in order to decide if the code that is being executed is\nmalicious or not. It's possible to bypass hooked functions by writing malicious functions that call syscalls directly.\n\nMore context and technical details can be found in this [research blog](https://outflank.nl/blog/2019/06/19/red-team-tactics-combining-direct-system-calls-and-srdi-to-bypass-av-edr/).\n\nThis rule identifies suspicious process access events from an unknown memory region. Attackers can use direct system\ncalls to bypass security solutions that rely on hooks.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed by the subject process such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This detection may be triggered by certain applications that install root certificates for the purpose of inspecting\nSSL traffic. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove the malicious certificate from the root certificate store.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Suspicious Process Access via Direct System Call\n\nEndpoint security solutions usually hook userland Windows APIs in order to decide if the code that is being executed is\nmalicious or not. It's possible to bypass hooked functions by writing malicious functions that call syscalls directly.\n\nMore context and technical details can be found in this [research blog](https://outflank.nl/blog/2019/06/19/red-team-tactics-combining-direct-system-calls-and-srdi-to-bypass-av-edr/).\n\nThis rule identifies suspicious process access events from an unknown memory region. Attackers can use direct system\ncalls to bypass security solutions that rely on hooks.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This detection may be triggered by certain applications that install root certificates for the purpose of inspecting\nSSL traffic. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove the malicious certificate from the root certificate store.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.code == \"10\" and\n length(winlog.event_data.CallTrace) > 0 and\n\n /* Sysmon CallTrace starting with unknown memory module instead of ntdll which host Windows NT Syscalls */\n not winlog.event_data.CallTrace :\n (\"?:\\\\WINDOWS\\\\SYSTEM32\\\\ntdll.dll*\",\n \"?:\\\\WINDOWS\\\\SysWOW64\\\\ntdll.dll*\",\n \"?:\\\\Windows\\\\System32\\\\wow64cpu.dll*\",\n \"?:\\\\WINDOWS\\\\System32\\\\wow64win.dll*\",\n \"?:\\\\Windows\\\\System32\\\\win32u.dll*\") and\n\n not winlog.event_data.TargetImage :\n (\"?:\\\\Program Files (x86)\\\\Malwarebytes Anti-Exploit\\\\mbae-svc.exe\",\n \"?:\\\\Program Files\\\\Cisco\\\\AMP\\\\*\\\\sfc.exe\",\n \"?:\\\\Program Files (x86)\\\\Microsoft\\\\EdgeWebView\\\\Application\\\\*\\\\msedgewebview2.exe\",\n \"?:\\\\Program Files\\\\Adobe\\\\Acrobat DC\\\\Acrobat\\\\*\\\\AcroCEF.exe\") and\n\n not (process.executable : (\"?:\\\\Program Files\\\\Adobe\\\\Acrobat DC\\\\Acrobat\\\\Acrobat.exe\",\n \"?:\\\\Program Files (x86)\\\\World of Warcraft\\\\_classic_\\\\WowClassic.exe\") and\n not winlog.event_data.TargetImage : \"?:\\\\WINDOWS\\\\system32\\\\lsass.exe\")\n", "references": [ "https://twitter.com/SBousseaden/status/1278013896440324096", @@ -48,7 +48,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -69,5 +70,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_creation_calltrace.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_creation_calltrace.json index 76e62528a181c..71090cbe65b64 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_creation_calltrace.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_creation_calltrace.json @@ -2,7 +2,7 @@ "author": [ "Elastic" ], - "description": "Identifies when a process is created and immediately accessed from an unknown memory code region and by the same parent process. This may indicate a code injection or hollowing attempt.", + "description": "Identifies when a process is created and immediately accessed from an unknown memory code region and by the same parent process. This may indicate a code injection attempt.", "from": "now-9m", "index": [ "winlogbeat-*", @@ -11,6 +11,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Suspicious Process Creation CallTrace", + "note": "## Triage and analysis\n\n### Investigating Suspicious Process Creation CallTrace\n\nAttackers may inject code into child processes' memory to hide their actual activity, evade detection mechanisms, and\ndecrease discoverability during forensics. This rule looks for a spawned process by Microsoft Office, scripting, and\ncommand line applications, followed by a process access event for an unknown memory region by the parent process, which\ncan indicate a code injection attempt.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate abnormal behavior observed by the subject process such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n- Create a memory dump of the child process for analysis.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence by host.id with maxspan=1m\n [process where event.code == \"1\" and\n /* sysmon process creation */\n process.parent.name : (\"winword.exe\", \"excel.exe\", \"outlook.exe\", \"powerpnt.exe\", \"eqnedt32.exe\", \"fltldr.exe\",\n \"mspub.exe\", \"msaccess.exe\",\"cscript.exe\", \"wscript.exe\", \"rundll32.exe\", \"regsvr32.exe\",\n \"mshta.exe\", \"wmic.exe\", \"cmstp.exe\", \"msxsl.exe\") and\n\n /* noisy FP patterns */\n not (process.parent.name : \"EXCEL.EXE\" and process.executable : \"?:\\\\Program Files\\\\Microsoft Office\\\\root\\\\Office*\\\\ADDINS\\\\*.exe\") and\n not (process.executable : \"?:\\\\Windows\\\\splwow64.exe\" and process.args in (\"8192\", \"12288\") and process.parent.name : (\"winword.exe\", \"excel.exe\", \"outlook.exe\", \"powerpnt.exe\")) and\n not (process.parent.name : \"rundll32.exe\" and process.parent.args : (\"?:\\\\WINDOWS\\\\Installer\\\\MSI*.tmp,zzzzInvokeManagedCustomActionOutOfProc\", \"--no-sandbox\")) and\n not (process.executable :\n (\"?:\\\\Program Files (x86)\\\\Microsoft\\\\EdgeWebView\\\\Application\\\\*\\\\msedgewebview2.exe\",\n \"?:\\\\Program Files\\\\Adobe\\\\Acrobat DC\\\\Acrobat\\\\Acrobat.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\DWWIN.EXE\") and\n process.parent.name : (\"winword.exe\", \"excel.exe\", \"outlook.exe\", \"powerpnt.exe\")) and\n not (process.parent.name : \"regsvr32.exe\" and process.parent.args : (\"?:\\\\Program Files\\\\*\", \"?:\\\\Program Files (x86)\\\\*\"))\n ] by process.parent.entity_id, process.entity_id\n [process where event.code == \"10\" and\n /* Sysmon process access event from unknown module */\n winlog.event_data.CallTrace : \"*UNKNOWN*\"] by process.entity_id, winlog.event_data.TargetProcessGUID\n", "required_fields": [ { @@ -92,5 +93,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json index 2a39c7a7961f0..2e44936da71b2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Unusual Executable File Creation by a System Critical Process", - "note": "## Triage and analysis\n\n### Investigating Unusual Executable File Creation by a System Critical Process\n\nWindows internal/system processes have some characteristics that can be used to spot suspicious activities. One of these\ncharacteristics is file operations.\n\nThis rule looks for the creation of executable files done by system-critical processes. This can indicate the exploitation\nof a vulnerability or a malicious process masquerading as a system-critical process.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed by the subject process such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Unusual Executable File Creation by a System Critical Process\n\nWindows internal/system processes have some characteristics that can be used to spot suspicious activities. One of these\ncharacteristics is file operations.\n\nThis rule looks for the creation of executable files done by system-critical processes. This can indicate the exploitation\nof a vulnerability or a malicious process masquerading as a system-critical process.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "file where event.type != \"deletion\" and\n file.extension : (\"exe\", \"dll\") and\n process.name : (\"smss.exe\",\n \"autochk.exe\",\n \"csrss.exe\",\n \"wininit.exe\",\n \"services.exe\",\n \"lsass.exe\",\n \"winlogon.exe\",\n \"userinit.exe\",\n \"LogonUI.exe\")\n", "required_fields": [ { @@ -40,7 +40,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -61,5 +62,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_ads_file_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_ads_file_creation.json index 5892ec0a1e44b..e9d8c440038b7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_ads_file_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_ads_file_creation.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Unusual File Creation - Alternate Data Stream", - "note": "", + "note": "## Triage and analysis\n\n### Investigating Unusual File Creation - Alternate Data Stream\n\nAlternate Data Streams (ADS) are file attributes only found on the NTFS file system. In this file system, files are\nbuilt up from a couple of attributes; one of them is $Data, also known as the data attribute.\n\nThe regular data stream, also referred to as the unnamed data stream since the name string of this attribute is empty,\ncontains the data inside the file. So any data stream that has a name is considered an alternate data stream.\n\nAttackers can abuse these alternate data streams to hide malicious files, string payloads, etc. This rule detects the\ncreation of alternate data streams on highly targeted file types.\n\n#### Possible investigation steps\n\n- Retrieve the contents of the alternate data stream, and analyze it for potential maliciousness. Analysts can use the\nfollowing PowerShell cmdlet to accomplish this:\n - `Get-Content -file C:\\Path\\To\\file.exe -stream ADSname`\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- If this activity is expected and noisy in your environment, consider adding exceptions \u2014 preferably with a combination\nof process executable and file conditions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "file where event.type == \"creation\" and\n\n file.path : \"C:\\\\*:*\" and\n not file.path : \"C:\\\\*:zone.identifier*\" and\n\n not process.executable :\n (\"?:\\\\windows\\\\System32\\\\svchost.exe\",\n \"?:\\\\Windows\\\\System32\\\\inetsrv\\\\w3wp.exe\",\n \"?:\\\\Windows\\\\explorer.exe\",\n \"?:\\\\Windows\\\\System32\\\\sihost.exe\",\n \"?:\\\\Windows\\\\System32\\\\PickerHost.exe\",\n \"?:\\\\Windows\\\\System32\\\\SearchProtocolHost.exe\",\n \"?:\\\\Program Files (x86)\\\\Dropbox\\\\Client\\\\Dropbox.exe\",\n \"?:\\\\Program Files\\\\Rivet Networks\\\\SmartByte\\\\SmartByteNetworkService.exe\",\n \"?:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe\",\n \"?:\\\\Program Files\\\\ExpressConnect\\\\ExpressConnectNetworkService.exe\",\n \"?:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n \"?:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n \"?:\\\\Program Files\\\\Mozilla Firefox\\\\firefox.exe\") and\n\n file.extension :\n (\n \"pdf\",\n \"dll\",\n \"png\",\n \"exe\",\n \"dat\",\n \"com\",\n \"bat\",\n \"cmd\",\n \"sys\",\n \"vbs\",\n \"ps1\",\n \"hta\",\n \"txt\",\n \"vbe\",\n \"js\",\n \"wsh\",\n \"docx\",\n \"doc\",\n \"xlsx\",\n \"xls\",\n \"pptx\",\n \"ppt\",\n \"rtf\",\n \"gif\",\n \"jpg\",\n \"png\",\n \"bmp\",\n \"img\",\n \"iso\"\n )\n", "required_fields": [ { @@ -73,5 +73,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json index 9ea550212840e..7afc341466d9e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json @@ -58,7 +58,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_process_network_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_process_network_connection.json index 6b0299f2e5cd5..c93d6b9eb7045 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_process_network_connection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_process_network_connection.json @@ -39,7 +39,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { @@ -59,5 +60,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_workfolders_control_execution.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_workfolders_control_execution.json index 614bfead11cd3..aeaba22f4b281 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_workfolders_control_execution.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_workfolders_control_execution.json @@ -50,7 +50,8 @@ "Host", "Windows", "Threat Detection", - "Defense Evasion" + "Defense Evasion", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_adfind_command_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_adfind_command_activity.json index 00229a55fadc8..fa27159b49fd1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_adfind_command_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_adfind_command_activity.json @@ -53,7 +53,8 @@ "Host", "Windows", "Threat Detection", - "Discovery" + "Discovery", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_admin_recon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_admin_recon.json index 13d3d85f47363..76d95e51f4692 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_admin_recon.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_admin_recon.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Enumeration of Administrator Accounts", - "note": "## Triage and analysis\n\n### Investigating Enumeration of Administrator Accounts\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `net` and `wmic` utilities to enumerate administrator-related users or groups\nin the domain and local machine scope. Attackers can use this information to plan their next steps of the attack, such\nas mapping targets for credential compromise and other post-exploitation activities.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed using the account, such as commands executed, files created or modified, and\nnetwork connections.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Related rules\n\n- AdFind Command Activity - eda499b8-a073-4e35-9733-22ec71f57f3a\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Enumeration of Administrator Accounts\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `net` and `wmic` utilities to enumerate administrator-related users or groups\nin the domain and local machine scope. Attackers can use this information to plan their next steps of the attack, such\nas mapping targets for credential compromise and other post-exploitation activities.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Related rules\n\n- AdFind Command Activity - eda499b8-a073-4e35-9733-22ec71f57f3a\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n (((process.name : \"net.exe\" or process.pe.original_file_name == \"net.exe\") or\n ((process.name : \"net1.exe\" or process.pe.original_file_name == \"net1.exe\") and\n not process.parent.name : \"net.exe\")) and\n process.args : (\"group\", \"user\", \"localgroup\") and\n process.args : (\"admin\", \"Domain Admins\", \"Remote Desktop Users\", \"Enterprise Admins\", \"Organization Management\") and\n not process.args : \"/add\")\n\n or\n\n ((process.name : \"wmic.exe\" or process.pe.original_file_name == \"wmic.exe\") and\n process.args : (\"group\", \"useraccount\"))\n", "required_fields": [ { @@ -50,7 +50,8 @@ "Host", "Windows", "Threat Detection", - "Discovery" + "Discovery", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_command_system_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_command_system_account.json index 938ed63bb184f..e0f2daaefa5ab 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_command_system_account.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_command_system_account.json @@ -50,7 +50,8 @@ "Host", "Windows", "Threat Detection", - "Discovery" + "Discovery", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_view.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_view.json index a8d08a029cd2f..38779d72a19d4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_view.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_view.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Windows Network Enumeration", - "note": "## Triage and analysis\n\n### Investigating Windows Network Enumeration\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `net` utility to enumerate servers in the environment that hosts shared drives\nor printers. This information is useful to attackers as they can identify targets for lateral movements and search for\nvaluable shared data.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed using the account, such as commands executed, files created or modified, and\nnetwork connections.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Windows Network Enumeration\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `net` utility to enumerate servers in the environment that hosts shared drives\nor printers. This information is useful to attackers as they can identify targets for lateral movements and search for\nvaluable shared data.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n ((process.name : \"net.exe\" or process.pe.original_file_name == \"net.exe\") or\n ((process.name : \"net1.exe\" or process.pe.original_file_name == \"net1.exe\") and\n not process.parent.name : \"net.exe\")) and\n (process.args : \"view\" or (process.args : \"time\" and process.args : \"\\\\\\\\*\"))\n\n\n /* expand when ancestry is available\n and not descendant of [process where event.type == \"start\" and process.name : \"cmd.exe\" and\n ((process.parent.name : \"userinit.exe\") or\n (process.parent.name : \"gpscript.exe\") or\n (process.parent.name : \"explorer.exe\" and\n process.args : \"C:\\\\*\\\\Start Menu\\\\Programs\\\\Startup\\\\*.bat*\"))]\n */\n", "required_fields": [ { @@ -50,7 +50,8 @@ "Host", "Windows", "Threat Detection", - "Discovery" + "Discovery", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_peripheral_device.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_peripheral_device.json index 9a8fd5df2687a..08d44e6911cae 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_peripheral_device.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_peripheral_device.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Peripheral Device Discovery", - "note": "## Triage and analysis\n\n### Investigating Peripheral Device Discovery\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `fsutil` utility with the `fsinfo` subcommand to enumerate drives attached to\nthe computer, which can be used to identify secondary drives used for backups, mapped network drives, and removable\nmedia. These devices can contain valuable information for attackers.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed using the account, such as commands executed, files created or modified, and\nnetwork connections.\n- Determine whether this activity was followed by suspicious file access/copy operations or uploads to file storage\nservices.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Peripheral Device Discovery\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `fsutil` utility with the `fsinfo` subcommand to enumerate drives attached to\nthe computer, which can be used to identify secondary drives used for backups, mapped network drives, and removable\nmedia. These devices can contain valuable information for attackers.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n- Determine whether this activity was followed by suspicious file access/copy operations or uploads to file storage\nservices.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n (process.name : \"fsutil.exe\" or process.pe.original_file_name == \"fsutil.exe\") and\n process.args : \"fsinfo\" and process.args : \"drives\"\n", "required_fields": [ { @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Discovery" + "Discovery", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_invoke_sharefinder.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_invoke_sharefinder.json index c4c07e84c0e20..cd5b4ebbdf9f2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_invoke_sharefinder.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_invoke_sharefinder.json @@ -11,7 +11,7 @@ "language": "kuery", "license": "Elastic License v2", "name": "PowerShell Share Enumeration Script", - "note": "", + "note": "## Triage and analysis\n\n### Investigating PowerShell Share Enumeration Script\n\nPowerShell is one of the main tools system administrators use for automation, report routines, and other tasks. This\nmakes it available for use in various environments, and creates an attractive way for attackers to execute code.\n\nAttackers can use PowerShell to enumerate shares to search for sensitive data like documents, scripts, and other kinds\nof valuable data for encryption, exfiltration, and lateral movement.\n\n#### Possible investigation steps\n\n- Examine the script content that triggered the detection; look for suspicious DLL imports, collection or exfiltration\ncapabilities, suspicious functions, encoded or compressed data, and other potentially malicious characteristics.\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Evaluate whether the user needs to use PowerShell to complete tasks.\n- Check for additional PowerShell and command line logs that indicate that imported functions were run.\n - Evaluate which information was potentially mapped and accessed by the attacker.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, Intune, or similar software.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "event.category:process and\n powershell.file.script_block_text:(\n \"Invoke-ShareFinder\" or\n \"Invoke-ShareFinderThreaded\" or\n (\n \"shi1_netname\" and\n \"shi1_remark\"\n ) or\n (\n \"NetShareEnum\" and\n \"NetApiBufferFree\"\n )\n )\n", "references": [ "https://www.advintel.io/post/hunting-for-corporate-insurance-policies-indicators-of-ransom-exfiltrations", diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_suspicious_api_functions.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_suspicious_api_functions.json index 5d584a1eed8e1..cc587ddbf8315 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_suspicious_api_functions.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_suspicious_api_functions.json @@ -41,7 +41,8 @@ "Host", "Windows", "Threat Detection", - "Discovery" + "Discovery", + "has_guide" ], "threat": [ { @@ -101,5 +102,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json index 6724b509809c2..271d3736b125c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json @@ -59,7 +59,8 @@ "Host", "Windows", "Threat Detection", - "Discovery" + "Discovery", + "has_guide" ], "threat": [ { @@ -92,5 +93,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_privileged_localgroup_membership.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_privileged_localgroup_membership.json index ca21e6cf9077c..5c81974ec6ce3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_privileged_localgroup_membership.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_privileged_localgroup_membership.json @@ -11,7 +11,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Enumeration of Privileged Local Groups Membership", - "note": "## Triage and analysis\n\n### Investigating Enumeration of Privileged Local Groups Membership\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the enumeration of privileged local groups' membership by suspicious processes, and excludes known\nlegitimate utilities and programs installed. Attackers can use this information to decide the next steps of the attack,\nsuch as mapping targets for credential compromise and other post-exploitation activities.\n\n#### Possible investigation steps\n\n- Identify the process, host and user involved on the event.\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed using the account, such as commands executed, files created or modified, and\nnetwork connections.\n- Retrieve the process executable and determine if it is malicious:\n - Check if the file belongs to the operating system or has a valid digital signature.\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n- If this rule is noisy in your environment due to expected activity, consider adding exceptions \u2014 preferably with a combination\nof user and command line conditions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n\nThe 'Audit Security Group Management' audit policy must be configured (Success).\nSteps to implement the logging policy with with Advanced Audit Configuration:\n\n```\nComputer Configuration >\nPolicies >\nWindows Settings >\nSecurity Settings >\nAdvanced Audit Policies Configuration >\nAudit Policies >\nAccount Management >\nAudit Security Group Management (Success)\n```\n\nMicrosoft introduced the [event used](https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4799) in this detection rule on Windows 10 and Windows Server 2016 or later operating systems.\n\nIf enabling an EQL rule on a non-elastic-agent index (such as beats) for versions <8.2, events will not define `event.ingested` and default fallback for EQL rules was not added until 8.2, so you will need to add a custom pipeline to populate `event.ingested` to @timestamp for this rule to work.", + "note": "## Triage and analysis\n\n### Investigating Enumeration of Privileged Local Groups Membership\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the enumeration of privileged local groups' membership by suspicious processes, and excludes known\nlegitimate utilities and programs installed. Attackers can use this information to decide the next steps of the attack,\nsuch as mapping targets for credential compromise and other post-exploitation activities.\n\n#### Possible investigation steps\n\n- Identify the process, host and user involved on the event.\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n- Retrieve the process executable and determine if it is malicious:\n - Check if the file belongs to the operating system or has a valid digital signature.\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n- If this rule is noisy in your environment due to expected activity, consider adding exceptions \u2014 preferably with a combination\nof user and command line conditions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n\nThe 'Audit Security Group Management' audit policy must be configured (Success).\nSteps to implement the logging policy with with Advanced Audit Configuration:\n\n```\nComputer Configuration >\nPolicies >\nWindows Settings >\nSecurity Settings >\nAdvanced Audit Policies Configuration >\nAudit Policies >\nAccount Management >\nAudit Security Group Management (Success)\n```\n\nMicrosoft introduced the [event used](https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4799) in this detection rule on Windows 10 and Windows Server 2016 or later operating systems.\n\nIf enabling an EQL rule on a non-elastic-agent index (such as beats) for versions <8.2, events will not define `event.ingested` and default fallback for EQL rules was not added until 8.2, so you will need to add a custom pipeline to populate `event.ingested` to @timestamp for this rule to work.", "query": "iam where event.action == \"user-member-enumerated\" and\n\n /* excluding machine account */\n not winlog.event_data.SubjectUserName: (\"*$\", \"LOCAL SERVICE\", \"NETWORK SERVICE\") and\n\n /* noisy and usual legit processes excluded */\n not winlog.event_data.CallerProcessName:\n (\"-\",\n \"?:\\\\Windows\\\\System32\\\\VSSVC.exe\",\n \"?:\\\\Windows\\\\System32\\\\SearchIndexer.exe\",\n \"?:\\\\Windows\\\\System32\\\\CompatTelRunner.exe\",\n \"?:\\\\Windows\\\\System32\\\\oobe\\\\msoobe.exe\",\n \"?:\\\\Windows\\\\System32\\\\net1.exe\",\n \"?:\\\\Windows\\\\System32\\\\svchost.exe\",\n \"?:\\\\Windows\\\\System32\\\\Netplwiz.exe\",\n \"?:\\\\Windows\\\\System32\\\\msiexec.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\msiexec.exe\",\n \"?:\\\\Windows\\\\System32\\\\CloudExperienceHostBroker.exe\",\n \"?:\\\\Windows\\\\System32\\\\wbem\\\\WmiPrvSE.exe\",\n \"?:\\\\Windows\\\\System32\\\\SrTasks.exe\",\n \"?:\\\\Windows\\\\System32\\\\lsass.exe\",\n \"?:\\\\Windows\\\\System32\\\\diskshadow.exe\",\n \"?:\\\\Windows\\\\System32\\\\dfsrs.exe\",\n \"?:\\\\Program Files\\\\*.exe\",\n \"?:\\\\Program Files (x86)\\\\*.exe\",\n \"?:\\\\WindowsAzure\\\\*\\\\WaAppAgent.exe\",\n \"?:\\\\Windows\\\\System32\\\\vssadmin.exe\",\n \"?:\\\\Windows\\\\VeeamVssSupport\\\\VeeamGuestHelper.exe\",\n \"?:\\\\Windows\\\\System32\\\\dllhost.exe\",\n \"?:\\\\Windows\\\\System32\\\\mmc.exe\",\n \"?:\\\\Windows\\\\System32\\\\SettingSyncHost.exe\",\n \"?:\\\\Windows\\\\ImmersiveControlPanel\\\\SystemSettings.exe\",\n \"?:\\\\Windows\\\\System32\\\\SystemSettingsAdminFlows.exe\",\n \"?:\\\\Windows\\\\Temp\\\\rubrik_vmware???\\\\snaptool.exe\",\n \"?:\\\\Windows\\\\System32\\\\inetsrv\\\\w3wp.exe\",\n \"?:\\\\$WINDOWS.~BT\\\\Sources\\\\*.exe\",\n \"?:\\\\Windows\\\\System32\\\\wsmprovhost.exe\",\n \"?:\\\\Windows\\\\System32\\\\spool\\\\drivers\\\\x64\\\\3\\\\x3jobt3?.exe\",\n \"?:\\\\Windows\\\\System32\\\\mstsc.exe\",\n \"?:\\\\Windows\\\\System32\\\\esentutl.exe\",\n \"?:\\\\Windows\\\\System32\\\\RecoveryDrive.exe\",\n \"?:\\\\Windows\\\\System32\\\\SystemPropertiesComputerName.exe\") and\n\n /* privileged local groups */\n (group.name:(\"admin*\",\"RemoteDesktopUsers\") or\n winlog.event_data.TargetSid:(\"S-1-5-32-544\",\"S-1-5-32-555\"))\n", "required_fields": [ { @@ -49,7 +49,8 @@ "Host", "Windows", "Threat Detection", - "Discovery" + "Discovery", + "has_guide" ], "threat": [ { @@ -77,5 +78,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_remote_system_discovery_commands_windows.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_remote_system_discovery_commands_windows.json index 2378e0c21b4e6..e0bf3a485e835 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_remote_system_discovery_commands_windows.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_remote_system_discovery_commands_windows.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Remote System Discovery Commands", - "note": "## Triage and analysis\n\n### Investigating Remote System Discovery Commands\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `arp` or `nbstat` utilities to enumerate remote systems in the environment,\nwhich is useful for attackers to identify lateral movement targets.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed using the account, such as commands executed, files created or modified, and\nnetwork connections.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Remote System Discovery Commands\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `arp` or `nbstat` utilities to enumerate remote systems in the environment,\nwhich is useful for attackers to identify lateral movement targets.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n ((process.name : \"nbtstat.exe\" and process.args : (\"-n\", \"-s\")) or\n (process.name : \"arp.exe\" and process.args : \"-a\"))\n", "required_fields": [ { @@ -40,7 +40,8 @@ "Host", "Windows", "Threat Detection", - "Discovery" + "Discovery", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_grep.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_grep.json index 1d81253496323..dbed80d94bef8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_grep.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_grep.json @@ -14,7 +14,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Security Software Discovery via Grep", - "note": "", + "note": "## Triage and analysis\n\n### Investigating Security Software Discovery via Grep\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `grep` utility with arguments compatible to the enumeration of the security\nsoftware installed on the host. Attackers can use this information to decide whether or not to infect a system, disable\nprotections, use bypasses, etc.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence and whether they are located in expected locations.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n- Investigate any abnormal behavior by the subject process such as network connections, file modifications, and any\nspawned child processes.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate\nsoftware installations.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\nprocess.name : \"grep\" and user.id != \"0\" and\n not process.parent.executable : \"/Library/Application Support/*\" and\n process.args :\n (\"Little Snitch*\",\n \"Avast*\",\n \"Avira*\",\n \"ESET*\",\n \"BlockBlock*\",\n \"360Sec*\",\n \"LuLu*\",\n \"KnockKnock*\",\n \"kav\",\n \"KIS\",\n \"RTProtectionDaemon*\",\n \"Malware*\",\n \"VShieldScanner*\",\n \"WebProtection*\",\n \"webinspectord*\",\n \"McAfee*\",\n \"isecespd*\",\n \"macmnsvc*\",\n \"masvc*\",\n \"kesl*\",\n \"avscan*\",\n \"guard*\",\n \"rtvscand*\",\n \"symcfgd*\",\n \"scmdaemon*\",\n \"symantec*\",\n \"sophos*\",\n \"osquery*\",\n \"elastic-endpoint*\"\n ) and\n not (process.args : \"Avast\" and process.args : \"Passwords\")\n", "required_fields": [ { @@ -81,5 +81,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_wmic.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_wmic.json index 4c4b1e6127340..5e0d757a0c232 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_wmic.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_wmic.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Security Software Discovery using WMIC", - "note": "## Triage and analysis\n\n### Investigating Security Software Discovery using WMIC\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `wmic` utility with arguments compatible to the enumeration of the security\nsoftware installed on the host. Attackers can use this information to decide whether or not to infect a system, disable\nprotections, use bypasses, etc.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed using the account, such as commands executed, files created or modified, and\nnetwork connections.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Security Software Discovery using WMIC\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `wmic` utility with arguments compatible to the enumeration of the security\nsoftware installed on the host. Attackers can use this information to decide whether or not to infect a system, disable\nprotections, use bypasses, etc.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n (process.name:\"wmic.exe\" or process.pe.original_file_name:\"wmic.exe\") and\n process.args:\"/namespace:\\\\\\\\root\\\\SecurityCenter2\" and process.args:\"Get\"\n", "required_fields": [ { @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Discovery" + "Discovery", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_command_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_command_activity.json index 801024ec2f04a..f27272de5cee0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_command_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_command_activity.json @@ -16,7 +16,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Whoami Process Activity", - "note": "## Triage and analysis\n\n### Investigating Whoami Process Activity\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `whoami` utility. Attackers commonly use this utility to measure their current\nprivileges, discover the current user, determine if a privilege escalation was successful, etc.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed using the account, such as commands executed, files created or modified, and\nnetwork connections.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Related rules\n\n- Account Discovery Command via SYSTEM Account - 2856446a-34e6-435b-9fb5-f8f040bfa7ed\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection via the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Whoami Process Activity\n\nAfter successfully compromising an environment, attackers may try to gain situational awareness to plan their next steps.\nThis can happen by running commands to enumerate network resources, users, connections, files, and installed security\nsoftware.\n\nThis rule looks for the execution of the `whoami` utility. Attackers commonly use this utility to measure their current\nprivileges, discover the current user, determine if a privilege escalation was successful, etc.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n\n### False positive analysis\n\n- Discovery activities are not inherently malicious if they occur in isolation. As long as the analyst did not identify\nsuspicious activity related to the user or host, such alerts can be dismissed.\n\n### Related rules\n\n- Account Discovery Command via SYSTEM Account - 2856446a-34e6-435b-9fb5-f8f040bfa7ed\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and process.name : \"whoami.exe\" and\n(\n\n (/* scoped for whoami execution under system privileges */\n (user.domain : (\"NT AUTHORITY\", \"NT-AUTORIT\u00c4T\", \"AUTORITE NT\", \"IIS APPPOOL\") or user.id : (\"S-1-5-18\", \"S-1-5-19\", \"S-1-5-20\")) and\n\n not (process.parent.name : \"cmd.exe\" and\n process.parent.args : (\"chcp 437>nul 2>&1 & C:\\\\WINDOWS\\\\System32\\\\whoami.exe /groups\",\n \"chcp 437>nul 2>&1 & %systemroot%\\\\system32\\\\whoami /user\",\n \"C:\\\\WINDOWS\\\\System32\\\\whoami.exe /groups\",\n \"*WINDOWS\\\\system32\\\\config\\\\systemprofile*\")) and\n not (process.parent.executable : \"C:\\\\Windows\\\\system32\\\\inetsrv\\\\appcmd.exe\" and process.parent.args : \"LIST\") and\n not process.parent.executable : (\"C:\\\\Program Files\\\\Microsoft Monitoring Agent\\\\Agent\\\\MonitoringHost.exe\",\n \"C:\\\\Program Files\\\\Cohesity\\\\cohesity_windows_agent_service.exe\")) or\n\n process.parent.name : (\"wsmprovhost.exe\", \"w3wp.exe\", \"wmiprvse.exe\", \"rundll32.exe\", \"regsvr32.exe\")\n\n)\n", "required_fields": [ { @@ -64,7 +64,8 @@ "Host", "Windows", "Threat Detection", - "Discovery" + "Discovery", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_abnormal_process_id_file_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_abnormal_process_id_file_created.json index 6389a8a3ab80d..785c950719b8f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_abnormal_process_id_file_created.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_abnormal_process_id_file_created.json @@ -13,7 +13,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Abnormal Process ID or Lock File Created", - "note": "## Triage and analysis\n\n### Investigating Abnormal Process ID or Lock File Created\nDetection alerts from this rule indicate that an unusual PID file was created and could potentially have alternate purposes during an intrusion. Here are some possible avenues of investigation:\n- Run the following in Osquery to quickly identify unsual PID file size: \"SELECT f.size, f.uid, f.type, f.path from file f WHERE path like '/var/run/%pid';\"\n- Examine the history of this file creation and from which process it was created by using the \"lsof\" command.\n- Examine the contents of the PID file itself, simply by running the \"cat\" command to determine if the expected process ID integer exists and if not, the PID file is not legitimate.\n- Examine the reputation of the SHA256 hash from the PID file in a database like VirusTotal to identify additional pivots and artifacts for investigation.", + "note": "## Triage and analysis\n\n### Investigating Abnormal Process ID or Lock File Created\n\nLinux applications may need to save their process identification number (PID) for various purposes: from signaling that\na program is running to serving as a signal that a previous instance of an application didn't exit successfully. PID\nfiles contain its creator process PID in an integer value.\n\nLinux lock files are used to coordinate operations in files so that conflicts and race conditions are prevented.\n\nThis rule identifies the creation of PID, lock, or reboot files in the /var/run/ directory. Attackers can masquerade\nmalware, payloads, staged data for exfiltration, and more as legitimate PID files.\n\n#### Possible investigation steps\n\n- Retrieve the file and determine if it is malicious:\n - Check the contents of the PID files. They should only contain integer strings.\n - Check the file type of the lock and PID files to determine if they are executables. This is only observed in\n malicious files.\n - Check the size of the subject file. Legitimate PID files should be under 10 bytes.\n - Check if the lock or PID file has high entropy. This typically indicates an encrypted payload.\n - Analysts can use tools like `ent` to measure entropy.\n - Examine the reputation of the SHA-256 hash in the PID file. Use a database like VirusTotal to identify additional\n pivots and artifacts for investigation.\n- Trace the file's creation to ensure it came from a legitimate or authorized process.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n- Investigate any abnormal behavior by the subject process such as network connections, file modifications, and any\nspawned child processes.\n\n### False positive analysis\n\n- False positives can appear if the PID file is legitimate and holding a process ID as intended. If the PID file is\nan executable or has a file size that's larger than 10 bytes, it should be ruled suspicious.\n- If this activity is expected and noisy in your environment, consider adding exceptions \u2014 preferably with a combination\nof file name and process executable conditions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Block the identified indicators of compromise (IoCs).\n- Take actions to terminate processes and connections used by the attacker.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "/* add file size filters when data is available */\nfile where event.type == \"creation\" and user.id == \"0\" and\n file.path regex~ \"\"\"/var/run/\\w+\\.(pid|lock|reboot)\"\"\" and file.extension in (\"pid\",\"lock\",\"reboot\") and\n\n /* handle common legitimate files */\n\n not file.name in (\n \"auditd.pid\",\n \"python*\",\n \"apport.pid\",\n \"apport.lock\",\n \"kworker*\",\n \"gdm3.pid\",\n \"sshd.pid\",\n \"acpid.pid\",\n \"unattended-upgrades.lock\",\n \"unattended-upgrades.pid\",\n \"cmd.pid\",\n \"cron*.pid\",\n \"yum.pid\",\n \"netconfig.pid\",\n \"docker.pid\",\n \"atd.pid\",\n \"lfd.pid\",\n \"atop.pid\",\n \"nginx.pid\",\n \"dhclient.pid\",\n \"smtpd.pid\",\n \"stunnel.pid\"\n )\n", "references": [ "https://www.sandflysecurity.com/blog/linux-file-masquerading-and-malicious-pids-sandfly-1-2-6-update/", @@ -77,5 +77,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json index c14551a7a751e..7cea863e990a2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Svchost spawning Cmd", - "note": "## Triage and analysis\n\n### Investigating Svchost spawning Cmd\n\nThe Service Host process (SvcHost) is a system process that can host one, or multiple, Windows services in the Windows\nNT family of operating systems. Note that `Svchost.exe` is reserved for use by the operating system and should not be\nused by non-Windows services.\n\nThis rule looks for the creation of the `cmd.exe` process with `svchost.exe` as its parent process. This is an unusual\nbehavior that can indicate the masquerading of a malicious process as `svchost.exe` or exploitation for privilege\nescalation.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed by the subject process such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Svchost spawning Cmd\n\nThe Service Host process (SvcHost) is a system process that can host one, or multiple, Windows services in the Windows\nNT family of operating systems. Note that `Svchost.exe` is reserved for use by the operating system and should not be\nused by non-Windows services.\n\nThis rule looks for the creation of the `cmd.exe` process with `svchost.exe` as its parent process. This is an unusual\nbehavior that can indicate the masquerading of a malicious process as `svchost.exe` or exploitation for privilege\nescalation.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n\n process.parent.name : \"svchost.exe\" and process.name : \"cmd.exe\" and\n\n not process.args :\n (\"??:\\\\Program Files\\\\Npcap\\\\CheckStatus.bat?\",\n \"?:\\\\Program Files\\\\Npcap\\\\CheckStatus.bat\",\n \"\\\\system32\\\\cleanmgr.exe\",\n \"?:\\\\Windows\\\\system32\\\\silcollector.cmd\",\n \"\\\\system32\\\\AppHostRegistrationVerifier.exe\",\n \"\\\\system32\\\\ServerManagerLauncher.exe\",\n \"dir\",\n \"?:\\\\Program Files\\\\*\",\n \"?:\\\\Program Files (x86)\\\\*\",\n \"?:\\\\Windows\\\\LSDeployment\\\\Lspush.exe\",\n \"(x86)\\\\FMAuditOnsite\\\\watchdog.bat\",\n \"?:\\\\ProgramData\\\\chocolatey\\\\bin\\\\choco-upgrade-all.bat\",\n \"Files\\\\Npcap\\\\CheckStatus.bat\") and\n\n /* very noisy pattern - bat or cmd script executed via scheduled tasks */\n not (process.parent.args : \"netsvcs\" and process.args : (\"?:\\\\*.bat\", \"?:\\\\*.cmd\"))\n", "references": [ "https://nasbench.medium.com/demystifying-the-svchost-exe-process-and-its-command-line-options-508e9114e747" @@ -53,7 +53,8 @@ "Host", "Windows", "Threat Detection", - "Execution" + "Execution", + "has_guide" ], "threat": [ { @@ -76,5 +77,5 @@ "timeline_title": "Comprehensive Process Timeline", "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_from_unusual_path_cmdline.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_from_unusual_path_cmdline.json index a63258dc96af6..2221085a9b518 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_from_unusual_path_cmdline.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_from_unusual_path_cmdline.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Execution from Unusual Directory - Command Line", - "note": "## Triage and analysis\n\nThis is related to the `Process Execution from an Unusual Directory rule`.", + "note": "## Triage and analysis\n\n### Investigating Execution from Unusual Directory - Command Line\n\nThis rule looks for the execution of scripts from unusual directories. Attackers can use system or application paths to\nhide malware and make the execution less suspicious.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Examine the command line to determine which commands or scripts were executed.\n- Retrieve the script and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- If this activity is expected and noisy in your environment, consider adding exceptions \u2014 preferably with a combination\nof parent process executable and command line conditions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n\n\nThis is related to the `Process Execution from an Unusual Directory rule`.", "query": "process where event.type == \"start\" and\n process.name : (\"wscript.exe\",\n \"cscript.exe\",\n \"rundll32.exe\",\n \"regsvr32.exe\",\n \"cmstp.exe\",\n \"RegAsm.exe\",\n \"installutil.exe\",\n \"mshta.exe\",\n \"RegSvcs.exe\",\n \"powershell.exe\",\n \"pwsh.exe\",\n \"cmd.exe\") and\n\n /* add suspicious execution paths here */\n process.args : (\"C:\\\\PerfLogs\\\\*\",\n \"C:\\\\Users\\\\Public\\\\*\",\n \"C:\\\\Windows\\\\Tasks\\\\*\",\n \"C:\\\\Intel\\\\*\",\n \"C:\\\\AMD\\\\Temp\\\\*\",\n \"C:\\\\Windows\\\\AppReadiness\\\\*\",\n \"C:\\\\Windows\\\\ServiceState\\\\*\",\n \"C:\\\\Windows\\\\security\\\\*\",\n \"C:\\\\Windows\\\\IdentityCRL\\\\*\",\n \"C:\\\\Windows\\\\Branding\\\\*\",\n \"C:\\\\Windows\\\\csc\\\\*\",\n \"C:\\\\Windows\\\\DigitalLocker\\\\*\",\n \"C:\\\\Windows\\\\en-US\\\\*\",\n \"C:\\\\Windows\\\\wlansvc\\\\*\",\n \"C:\\\\Windows\\\\Prefetch\\\\*\",\n \"C:\\\\Windows\\\\Fonts\\\\*\",\n \"C:\\\\Windows\\\\diagnostics\\\\*\",\n \"C:\\\\Windows\\\\TAPI\\\\*\",\n \"C:\\\\Windows\\\\INF\\\\*\",\n \"C:\\\\Windows\\\\System32\\\\Speech\\\\*\",\n \"C:\\\\windows\\\\tracing\\\\*\",\n \"c:\\\\windows\\\\IME\\\\*\",\n \"c:\\\\Windows\\\\Performance\\\\*\",\n \"c:\\\\windows\\\\intel\\\\*\",\n \"c:\\\\windows\\\\ms\\\\*\",\n \"C:\\\\Windows\\\\dot3svc\\\\*\",\n \"C:\\\\Windows\\\\panther\\\\*\",\n \"C:\\\\Windows\\\\RemotePackages\\\\*\",\n \"C:\\\\Windows\\\\OCR\\\\*\",\n \"C:\\\\Windows\\\\appcompat\\\\*\",\n \"C:\\\\Windows\\\\apppatch\\\\*\",\n \"C:\\\\Windows\\\\addins\\\\*\",\n \"C:\\\\Windows\\\\Setup\\\\*\",\n \"C:\\\\Windows\\\\Help\\\\*\",\n \"C:\\\\Windows\\\\SKB\\\\*\",\n \"C:\\\\Windows\\\\Vss\\\\*\",\n \"C:\\\\Windows\\\\servicing\\\\*\",\n \"C:\\\\Windows\\\\CbsTemp\\\\*\",\n \"C:\\\\Windows\\\\Logs\\\\*\",\n \"C:\\\\Windows\\\\WaaS\\\\*\",\n \"C:\\\\Windows\\\\twain_32\\\\*\",\n \"C:\\\\Windows\\\\ShellExperiences\\\\*\",\n \"C:\\\\Windows\\\\ShellComponents\\\\*\",\n \"C:\\\\Windows\\\\PLA\\\\*\",\n \"C:\\\\Windows\\\\Migration\\\\*\",\n \"C:\\\\Windows\\\\debug\\\\*\",\n \"C:\\\\Windows\\\\Cursors\\\\*\",\n \"C:\\\\Windows\\\\Containers\\\\*\",\n \"C:\\\\Windows\\\\Boot\\\\*\",\n \"C:\\\\Windows\\\\bcastdvr\\\\*\",\n \"C:\\\\Windows\\\\TextInput\\\\*\",\n \"C:\\\\Windows\\\\security\\\\*\",\n \"C:\\\\Windows\\\\schemas\\\\*\",\n \"C:\\\\Windows\\\\SchCache\\\\*\",\n \"C:\\\\Windows\\\\Resources\\\\*\",\n \"C:\\\\Windows\\\\rescache\\\\*\",\n \"C:\\\\Windows\\\\Provisioning\\\\*\",\n \"C:\\\\Windows\\\\PrintDialog\\\\*\",\n \"C:\\\\Windows\\\\PolicyDefinitions\\\\*\",\n \"C:\\\\Windows\\\\media\\\\*\",\n \"C:\\\\Windows\\\\Globalization\\\\*\",\n \"C:\\\\Windows\\\\L2Schemas\\\\*\",\n \"C:\\\\Windows\\\\LiveKernelReports\\\\*\",\n \"C:\\\\Windows\\\\ModemLogs\\\\*\",\n \"C:\\\\Windows\\\\ImmersiveControlPanel\\\\*\",\n \"C:\\\\$Recycle.Bin\\\\*\") and\n\n /* noisy FP patterns */\n\n not process.parent.executable : (\"C:\\\\WINDOWS\\\\System32\\\\DriverStore\\\\FileRepository\\\\*\\\\igfxCUIService*.exe\",\n \"C:\\\\Windows\\\\System32\\\\spacedeskService.exe\",\n \"C:\\\\Program Files\\\\Dell\\\\SupportAssistAgent\\\\SRE\\\\SRE.exe\") and\n not (process.name : \"rundll32.exe\" and\n process.args : (\"uxtheme.dll,#64\",\n \"PRINTUI.DLL,PrintUIEntry\",\n \"?:\\\\Windows\\\\System32\\\\FirewallControlPanel.dll,ShowNotificationDialog\",\n \"?:\\\\WINDOWS\\\\system32\\\\Speech\\\\SpeechUX\\\\sapi.cpl\",\n \"?:\\\\Windows\\\\system32\\\\shell32.dll,OpenAs_RunDLL\")) and\n\n not (process.name : \"cscript.exe\" and process.args : \"?:\\\\WINDOWS\\\\system32\\\\calluxxprovider.vbs\") and\n\n not (process.name : \"cmd.exe\" and process.args : \"?:\\\\WINDOWS\\\\system32\\\\powercfg.exe\" and process.args : \"?:\\\\WINDOWS\\\\inf\\\\PowerPlan.log\") and\n\n not (process.name : \"regsvr32.exe\" and process.args : \"?:\\\\Windows\\\\Help\\\\OEM\\\\scripts\\\\checkmui.dll\") and\n\n not (process.name : \"cmd.exe\" and\n process.parent.executable : (\"?:\\\\Windows\\\\System32\\\\oobe\\\\windeploy.exe\",\n \"?:\\\\Program Files (x86)\\\\ossec-agent\\\\wazuh-agent.exe\",\n \"?:\\\\Windows\\\\System32\\\\igfxCUIService.exe\",\n \"?:\\\\Windows\\\\Temp\\\\IE*.tmp\\\\IE*-support\\\\ienrcore.exe\"))\n", "required_fields": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_linux_netcat_network_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_linux_netcat_network_connection.json index bd0d4ee978b74..ce07c4a04bfca 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_linux_netcat_network_connection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_linux_netcat_network_connection.json @@ -14,6 +14,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Netcat Network Activity", + "note": "## Triage and analysis\n\n### Investigating Netcat Network Activity\n\nNetcat is a dual-use command line tool that can be used for various purposes, such as port scanning, file transfers, and\nconnection tests. Attackers can abuse its functionality for malicious purposes such creating bind shells or reverse\nshells to gain access to the target system.\n\nA reverse shell is a mechanism that's abused to connect back to an attacker-controlled system. It effectively redirects\nthe system's input and output and delivers a fully functional remote shell to the attacker. Even private systems are\nvulnerable since the connection is outgoing.\n\nA bind shell is a type of backdoor that attackers set up on the target host and binds to a specific port to listen for\nan incoming connection from the attacker.\n\nThis rule identifies potential reverse shell or bind shell activity using Netcat by checking for the execution of Netcat\nfollowed by a network connection.\n\n#### Possible investigation steps\n\n- Examine the command line to identify if the command is suspicious.\n- Extract and examine the target domain or IP address.\n - Check if the domain is newly registered or unexpected.\n - Check the reputation of the domain or IP address.\n - Scope other potentially compromised hosts in your environment by mapping hosts that also communicated with the\n domain or IP address.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n- Investigate any abnormal behavior by the subject process such as network connections, file modifications, and any\nspawned child processes.\n\n### False positive analysis\n\n- Netcat is a dual-use tool that can be used for benign or malicious activity. It is included in some Linux\ndistributions, so its presence is not necessarily suspicious. Some normal use of this program, while uncommon, may\noriginate from scripts, automation tools, and frameworks.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Block the identified indicators of compromise (IoCs).\n- Take actions to terminate processes and connections used by the attacker.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence by process.entity_id\n [process where (process.name == \"nc\" or process.name == \"ncat\" or process.name == \"netcat\" or\n process.name == \"netcat.openbsd\" or process.name == \"netcat.traditional\") and\n event.type == \"start\"]\n [network where (process.name == \"nc\" or process.name == \"ncat\" or process.name == \"netcat\" or\n process.name == \"netcat.openbsd\" or process.name == \"netcat.traditional\")]\n", "references": [ "http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet", @@ -65,5 +66,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ms_office_written_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ms_office_written_file.json index eaad2e49cd4f7..89f6364c7571c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ms_office_written_file.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ms_office_written_file.json @@ -13,7 +13,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Execution of File Written or Modified by Microsoft Office", - "note": "## Triage and analysis\n\n### Investigating Execution of File Written or Modified by Microsoft Office\n\nMicrosoft Office is a suite of applications designed to help with productivity and completing common tasks on a computer.\nYou can create and edit documents containing text and images, work with data in spreadsheets and databases, and create\npresentations and posters. As it is some of the most-used software across companies, MS Office is frequently\ntargeted for initial access. It also has a wide variety of capabilities that attackers can take advantage of.\n\nThis rule searches for executable files written by MS Office applications executed in sequence. This is most likely the result\nof the execution of malicious documents or exploitation for initial access or privilege escalation. This rule can also detect\nsuspicious processes masquerading as the MS Office applications.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve MS Office documents received and opened by the user that could cause this behavior. Common locations include,\nbut are not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating Execution of File Written or Modified by Microsoft Office\n\nMicrosoft Office is a suite of applications designed to help with productivity and completing common tasks on a computer.\nYou can create and edit documents containing text and images, work with data in spreadsheets and databases, and create\npresentations and posters. As it is some of the most-used software across companies, MS Office is frequently\ntargeted for initial access. It also has a wide variety of capabilities that attackers can take advantage of.\n\nThis rule searches for executable files written by MS Office applications executed in sequence. This is most likely the result\nof the execution of malicious documents or exploitation for initial access or privilege escalation. This rule can also detect\nsuspicious processes masquerading as the MS Office applications.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve MS Office documents received and opened by the user that could cause this behavior. Common locations include,\nbut are not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence with maxspan=2h\n [file where event.type != \"deletion\" and file.extension : \"exe\" and\n (process.name : \"WINWORD.EXE\" or\n process.name : \"EXCEL.EXE\" or\n process.name : \"OUTLOOK.EXE\" or\n process.name : \"POWERPNT.EXE\" or\n process.name : \"eqnedt32.exe\" or\n process.name : \"fltldr.exe\" or\n process.name : \"MSPUB.EXE\" or\n process.name : \"MSACCESS.EXE\")\n ] by host.id, file.path\n [process where event.type == \"start\"] by host.id, process.executable\n", "required_fields": [ { @@ -55,7 +55,8 @@ "Host", "Windows", "Threat Detection", - "Execution" + "Execution", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pdf_written_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pdf_written_file.json index 84871a5b9d608..e525b02a6efd5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pdf_written_file.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pdf_written_file.json @@ -13,7 +13,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Execution of File Written or Modified by PDF Reader", - "note": "## Triage and analysis\n\n### Investigating Execution of File Written or Modified by PDF Reader\n\nPDF is a common file type used in corporate environments and most machines have software to\nhandle these files. This creates a vector where attackers can exploit the engines and technology behind this class of\nsoftware for initial access or privilege escalation.\n\nThis rule searches for executable files written by PDF reader software and executed in sequence. This is most likely the\nresult of exploitation for privilege escalation or initial access. This rule can also detect suspicious processes masquerading as\nPDF readers.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve the PDF documents received and opened by the user that could cause this behavior. Common locations include,\nbut are not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating Execution of File Written or Modified by PDF Reader\n\nPDF is a common file type used in corporate environments and most machines have software to\nhandle these files. This creates a vector where attackers can exploit the engines and technology behind this class of\nsoftware for initial access or privilege escalation.\n\nThis rule searches for executable files written by PDF reader software and executed in sequence. This is most likely the\nresult of exploitation for privilege escalation or initial access. This rule can also detect suspicious processes masquerading as\nPDF readers.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve the PDF documents received and opened by the user that could cause this behavior. Common locations include,\nbut are not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence with maxspan=2h\n [file where event.type != \"deletion\" and file.extension : \"exe\" and\n (process.name : \"AcroRd32.exe\" or\n process.name : \"rdrcef.exe\" or\n process.name : \"FoxitPhantomPDF.exe\" or\n process.name : \"FoxitReader.exe\") and\n not (file.name : \"FoxitPhantomPDF.exe\" or\n file.name : \"FoxitPhantomPDFUpdater.exe\" or\n file.name : \"FoxitReader.exe\" or\n file.name : \"FoxitReaderUpdater.exe\" or\n file.name : \"AcroRd32.exe\" or\n file.name : \"rdrcef.exe\")\n ] by host.id, file.path\n [process where event.type == \"start\"] by host.id, process.executable\n", "required_fields": [ { @@ -60,7 +60,8 @@ "Host", "Windows", "Threat Detection", - "Execution" + "Execution", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_portable_executable.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_portable_executable.json index 538dc16e045d3..50a63ceed93a2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_portable_executable.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_portable_executable.json @@ -11,7 +11,7 @@ "language": "kuery", "license": "Elastic License v2", "name": "Suspicious Portable Executable Encoded in Powershell Script", - "note": "## Triage and analysis\n\n### Investigating Suspicious Portable Executable Encoded in Powershell Script\n\nPowerShell is one of the main tools system administrators use for automation, report routines, and other tasks. This\nmakes it available for use in various environments, and creates an attractive way for attackers to execute code.\n\nAttackers can abuse PowerShell in-memory capabilities to inject executables into memory without touching the disk,\nbypassing file-based security protections. These executables are generally base64 encoded.\n\n#### Possible investigation steps\n\n- Examine the script content that triggered the detection; look for suspicious DLL imports, collection or exfiltration\ncapabilities, suspicious functions, encoded or compressed data, and other potentially malicious characteristics.\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Evaluate whether the user needs to use PowerShell to complete tasks.\n- Retrieve the script and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Related rules\n\n- Suspicious .NET Reflection via PowerShell - e26f042e-c590-4e82-8e05-41e81bd822ad\n- PowerShell Suspicious Payload Encoded and Compressed - 81fe9dc6-a2d7-4192-a2d8-eed98afc766a\n- PowerShell PSReflect Script - 56f2e9b5-4803-4e44-a0a4-a52dc79d57fe\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Reimage the host operating system or restore the compromised files to clean versions.\n- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, Intune, or similar software.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Suspicious Portable Executable Encoded in Powershell Script\n\nPowerShell is one of the main tools system administrators use for automation, report routines, and other tasks. This\nmakes it available for use in various environments, and creates an attractive way for attackers to execute code.\n\nAttackers can abuse PowerShell in-memory capabilities to inject executables into memory without touching the disk,\nbypassing file-based security protections. These executables are generally base64 encoded.\n\n#### Possible investigation steps\n\n- Examine the script content that triggered the detection; look for suspicious DLL imports, collection or exfiltration\ncapabilities, suspicious functions, encoded or compressed data, and other potentially malicious characteristics.\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Evaluate whether the user needs to use PowerShell to complete tasks.\n- Retrieve the script and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Related rules\n\n- Suspicious .NET Reflection via PowerShell - e26f042e-c590-4e82-8e05-41e81bd822ad\n- PowerShell Suspicious Payload Encoded and Compressed - 81fe9dc6-a2d7-4192-a2d8-eed98afc766a\n- PowerShell PSReflect Script - 56f2e9b5-4803-4e44-a0a4-a52dc79d57fe\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Reimage the host operating system or restore the compromised files to clean versions.\n- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, Intune, or similar software.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "event.category:process and\n powershell.file.script_block_text : (\n TVqQAAMAAAAEAAAA\n )\n", "references": [ "https://github.com/atc-project/atc-data/blob/master/docs/Logging_Policies/LP_0109_windows_powershell_script_block_log.md" @@ -37,7 +37,8 @@ "Host", "Windows", "Threat Detection", - "Execution" + "Execution", + "has_guide" ], "threat": [ { @@ -65,5 +66,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_psreflect.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_psreflect.json index e775d8bf73942..ac618f2a58cd4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_psreflect.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_psreflect.json @@ -14,7 +14,7 @@ "language": "kuery", "license": "Elastic License v2", "name": "PowerShell PSReflect Script", - "note": "## Triage and analysis\n\n### Investigating PowerShell PSReflect Script\n\nPowerShell is one of the main tools system administrators use for automation, report routines, and other tasks. This\nmakes it available for use in various environments, and creates an attractive way for attackers to execute code.\n\nPSReflect is a library that enables PowerShell to access win32 API functions in an uncomplicated way. It also helps to\ncreate enums and structs easily\u2014all without touching the disk.\n\nAlthough this is an interesting project for every developer and admin out there, it is mainly used in the red team and\nmalware tooling for its capabilities.\n\nDetecting the core implementation of PSReflect means detecting most of the tooling that uses Windows API through\nPowerShell, enabling defenders to discover tools being dropped in the environment.\n\n#### Possible investigation steps\n\n- Examine the script content that triggered the detection; look for suspicious DLL imports, collection or exfiltration\ncapabilities, suspicious functions, encoded or compressed data, and other potentially malicious characteristics. The\nscript content that may be split into multiple script blocks (you can use the field `powershell.file.script_block_id`\nfor filtering).\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Check for additional PowerShell and command-line logs that indicate that imported functions were run.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Evaluate whether the user needs to use PowerShell to complete tasks.\n- Retrieve the script and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Related rules\n\n- PowerShell Suspicious Discovery Related Windows API Functions - 61ac3638-40a3-44b2-855a-985636ca985e\n- PowerShell Keylogging Script - bd2c86a0-8b61-4457-ab38-96943984e889\n- PowerShell Suspicious Script with Audio Capture Capabilities - 2f2f4939-0b34-40c2-a0a3-844eb7889f43\n- Potential Process Injection via PowerShell - 2e29e96a-b67c-455a-afe4-de6183431d0d\n- Suspicious .NET Reflection via PowerShell - e26f042e-c590-4e82-8e05-41e81bd822ad\n- PowerShell Suspicious Payload Encoded and Compressed - 81fe9dc6-a2d7-4192-a2d8-eed98afc766a\n- PowerShell Suspicious Script with Screenshot Capabilities - 959a7353-1129-4aa7-9084-30746b256a70\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, Intune, or similar software.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating PowerShell PSReflect Script\n\nPowerShell is one of the main tools system administrators use for automation, report routines, and other tasks. This\nmakes it available for use in various environments, and creates an attractive way for attackers to execute code.\n\nPSReflect is a library that enables PowerShell to access win32 API functions in an uncomplicated way. It also helps to\ncreate enums and structs easily\u2014all without touching the disk.\n\nAlthough this is an interesting project for every developer and admin out there, it is mainly used in the red team and\nmalware tooling for its capabilities.\n\nDetecting the core implementation of PSReflect means detecting most of the tooling that uses Windows API through\nPowerShell, enabling defenders to discover tools being dropped in the environment.\n\n#### Possible investigation steps\n\n- Examine the script content that triggered the detection; look for suspicious DLL imports, collection or exfiltration\ncapabilities, suspicious functions, encoded or compressed data, and other potentially malicious characteristics. The\nscript content that may be split into multiple script blocks (you can use the field `powershell.file.script_block_id`\nfor filtering).\n- Investigate the script execution chain (parent process tree) for unknown processes. Examine their executable files for\nprevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Check for additional PowerShell and command-line logs that indicate that imported functions were run.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Evaluate whether the user needs to use PowerShell to complete tasks.\n- Retrieve the script and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Related rules\n\n- PowerShell Suspicious Discovery Related Windows API Functions - 61ac3638-40a3-44b2-855a-985636ca985e\n- PowerShell Keylogging Script - bd2c86a0-8b61-4457-ab38-96943984e889\n- PowerShell Suspicious Script with Audio Capture Capabilities - 2f2f4939-0b34-40c2-a0a3-844eb7889f43\n- Potential Process Injection via PowerShell - 2e29e96a-b67c-455a-afe4-de6183431d0d\n- Suspicious .NET Reflection via PowerShell - e26f042e-c590-4e82-8e05-41e81bd822ad\n- PowerShell Suspicious Payload Encoded and Compressed - 81fe9dc6-a2d7-4192-a2d8-eed98afc766a\n- PowerShell Suspicious Script with Screenshot Capabilities - 959a7353-1129-4aa7-9084-30746b256a70\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, Intune, or similar software.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "event.category:process and\n powershell.file.script_block_text:(\n \"New-InMemoryModule\" or\n \"Add-Win32Type\" or\n psenum or\n DefineDynamicAssembly or\n DefineDynamicModule or\n \"Reflection.TypeAttributes\" or\n \"Reflection.Emit.OpCodes\" or\n \"Reflection.Emit.CustomAttributeBuilder\" or\n \"Runtime.InteropServices.DllImportAttribute\"\n )\n", "references": [ "https://github.com/mattifestation/PSReflect/blob/master/PSReflect.psm1", @@ -41,7 +41,8 @@ "Host", "Windows", "Threat Detection", - "Execution" + "Execution", + "has_guide" ], "threat": [ { @@ -74,5 +75,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json index 72d8ed1fdaffc..a293878687a6e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json @@ -57,7 +57,8 @@ "Host", "Windows", "Threat Detection", - "Execution" + "Execution", + "has_guide" ], "threat": [ { @@ -93,5 +94,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_revershell_via_shell_cmd.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_revershell_via_shell_cmd.json index 85ed673ec33e6..fbefe7152d9c0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_revershell_via_shell_cmd.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_revershell_via_shell_cmd.json @@ -11,7 +11,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Potential Reverse Shell Activity via Terminal", - "note": "", + "note": "## Triage and analysis\n\n### Investigating Potential Reverse Shell Activity via Terminal\n\nA reverse shell is a mechanism that's abused to connect back to an attacker-controlled system. It effectively redirects\nthe system's input and output and delivers a fully functional remote shell to the attacker. Even private systems are\nvulnerable since the connection is outgoing. This activity is typically the result of vulnerability exploitation,\nmalware infection, or penetration testing.\n\nThis rule identifies commands that are potentially related to reverse shell activities using shell applications.\n\n#### Possible investigation steps\n\n- Examine the command line and extract the target domain or IP address information.\n - Check if the domain is newly registered or unexpected.\n - Check the reputation of the domain or IP address.\n - Scope other potentially compromised hosts in your environment by mapping hosts that also communicated with the\n domain or IP address.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n- Investigate any abnormal behavior by the subject process such as network connections, file modifications, and any\nspawned child processes.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Any activity that triggered the alert and is not inherently\nmalicious must be monitored by the security team.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Take actions to terminate processes and connections used by the attacker.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type in (\"start\", \"process_started\") and\n process.name in (\"sh\", \"bash\", \"zsh\", \"dash\", \"zmodload\") and\n process.args : (\"*/dev/tcp/*\", \"*/dev/udp/*\", \"*zsh/net/tcp*\", \"*zsh/net/udp*\") and\n\n /* noisy FPs */\n not (process.parent.name : \"timeout\" and process.executable : \"/var/lib/docker/overlay*\") and\n not process.command_line : (\"*/dev/tcp/sirh_db/*\", \"*/dev/tcp/remoteiot.com/*\", \"*dev/tcp/elk.stag.one/*\", \"*dev/tcp/kafka/*\", \"*/dev/tcp/$0/$1*\", \"*/dev/tcp/127.*\", \"*/dev/udp/127.*\", \"*/dev/tcp/localhost/*\") and\n not process.parent.command_line : \"runc init\"\n", "references": [ "https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md", @@ -86,5 +86,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_jar_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_jar_child_process.json index 629a5b1f21401..5e742ae4ed4bb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_jar_child_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_jar_child_process.json @@ -11,7 +11,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Suspicious JAVA Child Process", - "note": "", + "note": "## Triage and analysis\n\n### Investigating Suspicious Java Child Process\n\nThis rule identifies a suspicious child process of the Java interpreter process. It may indicate an attempt to execute\na malicious JAR file or an exploitation attempt via a Java specific vulnerability.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence and whether they are located in expected locations.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n- Investigate any abnormal behavior by the subject process such as network connections, file modifications, and any\nspawned child processes.\n- Examine the command line to determine if the command executed is potentially harmful or malicious.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n\n### False positive analysis\n\n- If this activity is expected and noisy in your environment, consider adding exceptions \u2014 preferably with a combination\nof process and command line conditions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type in (\"start\", \"process_started\") and\n process.parent.name : \"java\" and\n process.name : (\"sh\", \"bash\", \"dash\", \"ksh\", \"tcsh\", \"zsh\", \"curl\", \"wget\")\n", "references": [ "https://www.lunasec.io/docs/blog/log4j-zero-day/", @@ -73,5 +73,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json index 3bf8084fe3659..3eab94d7a63e7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Suspicious PDF Reader Child Process", - "note": "## Triage and analysis\n\n### Investigating Suspicious PDF Reader Child Process\n\nPDF is a common file type used in corporate environments and most machines have software to handle these files. This\ncreates a vector where attackers can exploit the engines and technology behind this class of software for initial access\nor privilege escalation.\n\nThis rule looks for commonly abused built-in utilities spawned by a PDF reader process, which is likely a malicious behavior.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve PDF documents received and opened by the user that could cause this behavior. Common locations include, but\nare not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Suspicious PDF Reader Child Process\n\nPDF is a common file type used in corporate environments and most machines have software to handle these files. This\ncreates a vector where attackers can exploit the engines and technology behind this class of software for initial access\nor privilege escalation.\n\nThis rule looks for commonly abused built-in utilities spawned by a PDF reader process, which is likely a malicious behavior.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve PDF documents received and opened by the user that could cause this behavior. Common locations include, but\nare not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.parent.name : (\"AcroRd32.exe\",\n \"Acrobat.exe\",\n \"FoxitPhantomPDF.exe\",\n \"FoxitReader.exe\") and\n process.name : (\"arp.exe\", \"dsquery.exe\", \"dsget.exe\", \"gpresult.exe\", \"hostname.exe\", \"ipconfig.exe\", \"nbtstat.exe\",\n \"net.exe\", \"net1.exe\", \"netsh.exe\", \"netstat.exe\", \"nltest.exe\", \"ping.exe\", \"qprocess.exe\",\n \"quser.exe\", \"qwinsta.exe\", \"reg.exe\", \"sc.exe\", \"systeminfo.exe\", \"tasklist.exe\", \"tracert.exe\",\n \"whoami.exe\", \"bginfo.exe\", \"cdb.exe\", \"cmstp.exe\", \"csi.exe\", \"dnx.exe\", \"fsi.exe\", \"ieexec.exe\",\n \"iexpress.exe\", \"installutil.exe\", \"Microsoft.Workflow.Compiler.exe\", \"msbuild.exe\", \"mshta.exe\",\n \"msxsl.exe\", \"odbcconf.exe\", \"rcsi.exe\", \"regsvr32.exe\", \"xwizard.exe\", \"atbroker.exe\",\n \"forfiles.exe\", \"schtasks.exe\", \"regasm.exe\", \"regsvcs.exe\", \"cmd.exe\", \"cscript.exe\",\n \"powershell.exe\", \"pwsh.exe\", \"wmic.exe\", \"wscript.exe\", \"bitsadmin.exe\", \"certutil.exe\", \"ftp.exe\")\n", "required_fields": [ { @@ -40,7 +40,8 @@ "Host", "Windows", "Threat Detection", - "Execution" + "Execution", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_powershell_imgload.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_powershell_imgload.json index 652689a233566..b1b2b87bc5d87 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_powershell_imgload.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_powershell_imgload.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Suspicious PowerShell Engine ImageLoad", - "note": "## Triage and analysis\n\n### Investigating Suspicious PowerShell Engine ImageLoad\n\nPowerShell is one of the main tools system administrators use for automation, report routines, and other tasks. This\nmakes it available for use in various environments, and creates an attractive way for attackers to execute code.\n\nAttackers can use PowerShell without having to execute `PowerShell.exe` directly. This technique, often called\n\"PowerShell without PowerShell,\" works by using the underlying System.Management.Automation namespace and can bypass\napplication allowlisting and PowerShell security features.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate abnormal behaviors observed by the subject process, such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behaviors in the alert timeframe.\n- Retrieve the implementation (DLL, executable, etc.) and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity can happen legitimately. Some vendors have their own PowerShell implementations that are shipped with\nsome products. These benign true positives (B-TPs) can be added as exceptions if necessary after analysis.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n\n\n\nIf enabling an EQL rule on a non-elastic-agent index (such as beats) for versions <8.2, events will not define `event.ingested` and default fallback for EQL rules was not added until 8.2, so you will need to add a custom pipeline to populate `event.ingested` to @timestamp for this rule to work.", + "note": "## Triage and analysis\n\n### Investigating Suspicious PowerShell Engine ImageLoad\n\nPowerShell is one of the main tools system administrators use for automation, report routines, and other tasks. This\nmakes it available for use in various environments, and creates an attractive way for attackers to execute code.\n\nAttackers can use PowerShell without having to execute `PowerShell.exe` directly. This technique, often called\n\"PowerShell without PowerShell,\" works by using the underlying System.Management.Automation namespace and can bypass\napplication allowlisting and PowerShell security features.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate abnormal behaviors observed by the subject process, such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n- Retrieve the implementation (DLL, executable, etc.) and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity can happen legitimately. Some vendors have their own PowerShell implementations that are shipped with\nsome products. These benign true positives (B-TPs) can be added as exceptions if necessary after analysis.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n\n\n\nIf enabling an EQL rule on a non-elastic-agent index (such as beats) for versions <8.2, events will not define `event.ingested` and default fallback for EQL rules was not added until 8.2, so you will need to add a custom pipeline to populate `event.ingested` to @timestamp for this rule to work.", "query": "any where (event.category == \"library\" or (event.category == \"process\" and event.action : \"Image loaded*\")) and\n (dll.name : (\"System.Management.Automation.ni.dll\", \"System.Management.Automation.dll\") or\n file.name : (\"System.Management.Automation.ni.dll\", \"System.Management.Automation.dll\")) and\n\n/* add false positives relevant to your environment here */\nnot process.executable : (\"C:\\\\Windows\\\\System32\\\\RemoteFXvGPUDisablement.exe\", \"C:\\\\Windows\\\\System32\\\\sdiagnhost.exe\") and\nnot process.executable regex~ \"\"\"C:\\\\Program Files( \\(x86\\))?\\\\*\\.exe\"\"\" and\n not process.name :\n (\n \"Altaro.SubAgent.exe\",\n \"AppV_Manage.exe\",\n \"azureadconnect.exe\",\n \"CcmExec.exe\",\n \"configsyncrun.exe\",\n \"choco.exe\",\n \"ctxappvservice.exe\",\n \"DVLS.Console.exe\",\n \"edgetransport.exe\",\n \"exsetup.exe\",\n \"forefrontactivedirectoryconnector.exe\",\n \"InstallUtil.exe\",\n \"JenkinsOnDesktop.exe\",\n \"Microsoft.EnterpriseManagement.ServiceManager.UI.Console.exe\",\n \"mmc.exe\",\n \"mscorsvw.exe\",\n \"msexchangedelivery.exe\",\n \"msexchangefrontendtransport.exe\",\n \"msexchangehmworker.exe\",\n \"msexchangesubmission.exe\",\n \"msiexec.exe\",\n \"MsiExec.exe\",\n \"noderunner.exe\",\n \"NServiceBus.Host.exe\",\n \"NServiceBus.Host32.exe\",\n \"NServiceBus.Hosting.Azure.HostProcess.exe\",\n \"OuiGui.WPF.exe\",\n \"powershell.exe\",\n \"powershell_ise.exe\",\n \"pwsh.exe\",\n \"SCCMCliCtrWPF.exe\",\n \"ScriptEditor.exe\",\n \"ScriptRunner.exe\",\n \"sdiagnhost.exe\",\n \"servermanager.exe\",\n \"setup100.exe\",\n \"ServiceHub.VSDetouredHost.exe\",\n \"SPCAF.Client.exe\",\n \"SPCAF.SettingsEditor.exe\",\n \"SQLPS.exe\",\n \"telemetryservice.exe\",\n \"UMWorkerProcess.exe\",\n \"w3wp.exe\",\n \"wsmprovhost.exe\"\n )\n", "required_fields": [ { @@ -55,7 +55,8 @@ "Host", "Windows", "Threat Detection", - "Execution" + "Execution", + "has_guide" ], "threat": [ { @@ -83,5 +84,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_hidden_shell_conhost.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_hidden_shell_conhost.json index 4f6e8c63b7be8..873ed4a120f19 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_hidden_shell_conhost.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_hidden_shell_conhost.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Conhost Spawned By Suspicious Parent Process", - "note": "## Triage and analysis\n\n### Investigating Conhost Spawned By Suspicious Parent Process\n\nThe Windows Console Host, or `conhost.exe`, is both the server application for all of the Windows Console APIs as well as\nthe classic Windows user interface for working with command-line applications.\n\nAttackers often rely on custom shell implementations to avoid using built-in command interpreters like `cmd.exe` and\n`PowerShell.exe` and bypass application allowlisting and security features. Attackers commonly inject these implementations into\nlegitimate system processes.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate abnormal behaviors observed by the subject process, such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behaviors in the alert timeframe.\n- Retrieve the parent process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Related rules\n\n- Suspicious Process from Conhost - 28896382-7d4f-4d50-9b72-67091901fd26\n- Suspicious PowerShell Engine ImageLoad - 852c1f19-68e8-43a6-9dce-340771fe1be3\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Conhost Spawned By Suspicious Parent Process\n\nThe Windows Console Host, or `conhost.exe`, is both the server application for all of the Windows Console APIs as well as\nthe classic Windows user interface for working with command-line applications.\n\nAttackers often rely on custom shell implementations to avoid using built-in command interpreters like `cmd.exe` and\n`PowerShell.exe` and bypass application allowlisting and security features. Attackers commonly inject these implementations into\nlegitimate system processes.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate abnormal behaviors observed by the subject process, such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n- Retrieve the parent process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Related rules\n\n- Suspicious Process from Conhost - 28896382-7d4f-4d50-9b72-67091901fd26\n- Suspicious PowerShell Engine ImageLoad - 852c1f19-68e8-43a6-9dce-340771fe1be3\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.name : \"conhost.exe\" and\n process.parent.name : (\"lsass.exe\", \"services.exe\", \"smss.exe\", \"winlogon.exe\", \"explorer.exe\", \"dllhost.exe\", \"rundll32.exe\",\n \"regsvr32.exe\", \"userinit.exe\", \"wininit.exe\", \"spoolsv.exe\", \"ctfmon.exe\") and\n not (process.parent.name : \"rundll32.exe\" and\n process.parent.args : (\"?:\\\\Windows\\\\Installer\\\\MSI*.tmp,zzzzInvokeManagedCustomActionOutOfProc\",\n \"?:\\\\WINDOWS\\\\system32\\\\PcaSvc.dll,PcaPatchSdbTask\",\n \"?:\\\\WINDOWS\\\\system32\\\\davclnt.dll,DavSetCookie\"))\n", "references": [ "https://www.fireeye.com/blog/threat-research/2017/08/monitoring-windows-console-activity-part-one.html" @@ -48,7 +48,8 @@ "Host", "Windows", "Threat Detection", - "Execution" + "Execution", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json index fdc2114f9c36d..2b55041c64fe7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json @@ -12,8 +12,11 @@ "language": "eql", "license": "Elastic License v2", "name": "Execution via MSSQL xp_cmdshell Stored Procedure", - "note": "", + "note": "## Triage and analysis\n\n### Investigating Execution via MSSQL xp_cmdshell Stored Procedure\n\nMicrosoft SQL Server (MSSQL) has procedures meant to extend its functionality, the Extended Stored Procedures. These\nprocedures are external functions written in C/C++; some provide interfaces for external programs. This is the case for\nxp_cmdshell, which spawns a Windows command shell and passes in a string for execution. Attackers can use this to\nexecute commands on the system running the SQL server, commonly to escalate their privileges and establish persistence.\n\nThe xp_cmdshell procedure is disabled by default, but when used, it has the same security context as the MSSQL Server\nservice account, which is often privileged.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal account behavior, such as command executions, file creations or modifications, and network\nconnections.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Examine the command line to determine if the command executed is potentially harmful or malicious.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n\n### False positive analysis\n\n- This mechanism can be used legitimately, but it brings inherent risk. The security team must monitor any activity of\nit. If recurrent tasks are being executed using this mechanism, consider adding exceptions \u2014 preferably with a full\ncommand line.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Ensure that SQL servers are not directly exposed to the internet. If there is a business justification for such, use\nan allowlist to allow only connections from known legitimate sources.\n- Disable the xp_cmdshell stored procedure.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.name : \"cmd.exe\" and process.parent.name : \"sqlservr.exe\" and\n not process.args : (\"\\\\\\\\*\", \"diskfree\", \"rmdir\", \"mkdir\", \"dir\", \"del\", \"rename\", \"bcp\", \"*XMLNAMESPACES*\",\n \"?:\\\\MSSQL\\\\Backup\\\\Jobs\\\\sql_agent_backup_job.ps1\", \"K:\\\\MSSQL\\\\Backup\\\\msdb\", \"K:\\\\MSSQL\\\\Backup\\\\Logins\")\n", + "references": [ + "https://thedfirreport.com/2022/07/11/select-xmrig-from-sqlserver/" + ], "required_fields": [ { "ecs": true, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_ec2_snapshot_change_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_ec2_snapshot_change_activity.json index c39d0637ab983..d8de82c5251a9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_ec2_snapshot_change_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_ec2_snapshot_change_activity.json @@ -56,7 +56,8 @@ "Continuous Monitoring", "SecOps", "Asset Visibility", - "Exfiltration" + "Exfiltration", + "has_guide" ], "threat": [ { @@ -77,5 +78,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_backup_file_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_backup_file_deletion.json index 5c0cae49bde07..73d7ed7c943bf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_backup_file_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_backup_file_deletion.json @@ -46,7 +46,8 @@ "Host", "Windows", "Threat Detection", - "Impact" + "Impact", + "has_guide" ], "threat": [ { @@ -67,5 +68,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json index 84403d4b48ded..80ad1350df659 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json @@ -60,7 +60,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Log Auditing" + "Log Auditing", + "has_guide" ], "threat": [ { @@ -103,5 +104,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json index 0e28f8255ffb2..5734ffe4c312a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json @@ -60,7 +60,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Log Auditing" + "Log Auditing", + "has_guide" ], "threat": [ { @@ -103,5 +104,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json index fa184b0ea2c37..04870a18138e7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json @@ -61,7 +61,8 @@ "Continuous Monitoring", "SecOps", "Log Auditing", - "Impact" + "Impact", + "has_guide" ], "threat": [ { @@ -104,5 +105,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_deleting_backup_catalogs_with_wbadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_deleting_backup_catalogs_with_wbadmin.json index 9b83fccb1fb17..0136fbd4adc2a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_deleting_backup_catalogs_with_wbadmin.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_deleting_backup_catalogs_with_wbadmin.json @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Impact" + "Impact", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_google_workspace_mfa_enforcement_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_google_workspace_mfa_enforcement_disabled.json index bbaed9c02d794..6095c3c3a3923 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_google_workspace_mfa_enforcement_disabled.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_google_workspace_mfa_enforcement_disabled.json @@ -64,7 +64,8 @@ "Continuous Monitoring", "SecOps", "Configuration Audit", - "Impact" + "Impact", + "has_guide" ], "threat": [ { @@ -85,5 +86,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json index a5970f7a09fbd..a7ce614def97f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json @@ -13,7 +13,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Hosts File Modified", - "note": "", + "note": "## Triage and analysis\n\n### Investigating Hosts File Modified\n\nOperating systems use the hosts file to map a connection between an IP address and domain names before going to domain\nname servers. Attackers can abuse this mechanism to route traffic to malicious infrastructure or disrupt security that\ndepends on server communications. For example, Russian threat actors modified this file on a domain controller to\nredirect Duo MFA calls to localhost instead of the Duo server, which prevented the MFA service from contacting its\nserver to validate MFA login. This effectively disabled MFA for active domain accounts because the default policy of Duo\nfor Windows is to \"Fail open\" if the MFA server is unreachable. This can happen in any MFA implementation and is not\nexclusive to Duo. Find more details in this [CISA Alert](https://www.cisa.gov/uscert/ncas/alerts/aa22-074a).\n\nThis rule identifies modifications in the hosts file across multiple operating systems using process creation events for\nLinux and file events in Windows and macOS.\n\n#### Possible investigation steps\n\n- Identify the specifics of the involved assets, such as role, criticality, and associated users.\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Examine the changes to the hosts file by comparing it against file backups, volume shadow copies, and other restoration\nmechanisms.\n\n### False positive analysis\n\n- This mechanism can be used legitimately. Analysts can dismiss the alert if the administrator is aware of the activity\nand the configuration was justified.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Consider isolating the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Review the privileges of the administrator account that performed the action.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "any where\n\n /* file events for creation; file change events are not captured by some of the included sources for linux and so may\n miss this, which is the purpose of the process + command line args logic below */\n (\n event.category == \"file\" and event.type in (\"change\", \"creation\") and\n file.path : (\"/private/etc/hosts\", \"/etc/hosts\", \"?:\\\\Windows\\\\System32\\\\drivers\\\\etc\\\\hosts\")\n )\n or\n\n /* process events for change targeting linux only */\n (\n event.category == \"process\" and event.type in (\"start\") and\n process.name in (\"nano\", \"vim\", \"vi\", \"emacs\", \"echo\", \"sed\") and\n process.args : (\"/etc/hosts\")\n )\n", "references": [ "https://www.elastic.co/guide/en/beats/auditbeat/current/auditbeat-reference-yml.html" @@ -86,5 +86,5 @@ "timeline_title": "Comprehensive File Timeline", "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_deactivate_mfa_device.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_deactivate_mfa_device.json index 864a9c9e814f6..49c4f32551554 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_deactivate_mfa_device.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_deactivate_mfa_device.json @@ -61,7 +61,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Monitoring" + "Monitoring", + "has_guide" ], "threat": [ { @@ -82,5 +83,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_modification_of_boot_config.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_modification_of_boot_config.json index 2952696f91d6b..256e8a869d076 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_modification_of_boot_config.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_modification_of_boot_config.json @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Impact" + "Impact", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_process_kill_threshold.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_process_kill_threshold.json index 0a86a88da1140..18700e2d4bbac 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_process_kill_threshold.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_process_kill_threshold.json @@ -42,7 +42,8 @@ "Host", "Linux", "Threat Detection", - "Impact" + "Impact", + "has_guide" ], "threat": [ { @@ -68,5 +69,5 @@ "value": 10 }, "type": "threshold", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_stop_process_service_threshold.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_stop_process_service_threshold.json index cb9344a9276ee..8204204bb34c0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_stop_process_service_threshold.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_stop_process_service_threshold.json @@ -44,7 +44,8 @@ "Host", "Windows", "Threat Detection", - "Impact" + "Impact", + "has_guide" ], "threat": [ { @@ -70,5 +71,5 @@ "value": 10 }, "type": "threshold", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json index e640e7778107d..a4dbdf6df2385 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Volume Shadow Copy Deleted or Resized via VssAdmin", - "note": "## Triage and analysis\n\n### Investigating Volume Shadow Copy Deleted or Resized via VssAdmin\n\nThe Volume Shadow Copy Service (VSS) is a Windows feature that enables system administrators to take snapshots of volumes\nthat can later be restored or mounted to recover specific files or folders.\n\nA typical step in the playbook of an attacker attempting to deploy ransomware is to delete Volume Shadow\nCopies to ensure that victims have no alternative to paying the ransom, making any action that deletes shadow\ncopies worth monitoring.\n\nThis rule monitors the execution of Vssadmin.exe to either delete or resize shadow copies.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- In the case of a resize operation, check if the resize value is equal to suspicious values, like 401MB.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- If unsigned files are found on the process tree, retrieve them and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Use process name, command line, and file hash to search for occurrences in other hosts.\n- Check if any files on the host machine have been encrypted.\n\n\n### False positive analysis\n\n- This rule may produce benign true positives (B-TPs). If this activity is expected and noisy in your\nenvironment, consider adding exceptions \u2014 preferably with a combination of user and command line conditions.\n\n### Related rules\n\n- Volume Shadow Copy Deleted or Resized via VssAdmin - b5ea4bfe-a1b2-421f-9d47-22a75a6f2921\n- Volume Shadow Copy Deletion via PowerShell - d99a037b-c8e2-47a5-97b9-170d076827c4\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Consider isolating the involved host to prevent destructive behavior, which is commonly associated with this activity.\n- Priority should be given due to the advanced stage of this activity on the attack.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- If data was encrypted, deleted, or modified, activate your data recovery plan.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Perform data recovery locally or restore the backups from replicated copies (cloud, other servers, etc.).\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Volume Shadow Copy Deleted or Resized via VssAdmin\n\nThe Volume Shadow Copy Service (VSS) is a Windows feature that enables system administrators to take snapshots of volumes\nthat can later be restored or mounted to recover specific files or folders.\n\nA typical step in the playbook of an attacker attempting to deploy ransomware is to delete Volume Shadow\nCopies to ensure that victims have no alternative to paying the ransom, making any action that deletes shadow\ncopies worth monitoring.\n\nThis rule monitors the execution of Vssadmin.exe to either delete or resize shadow copies.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- In the case of a resize operation, check if the resize value is equal to suspicious values, like 401MB.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- If unsigned files are found on the process tree, retrieve them and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Use process name, command line, and file hash to search for occurrences in other hosts.\n- Check if any files on the host machine have been encrypted.\n\n\n### False positive analysis\n\n- This rule may produce benign true positives (B-TPs). If this activity is expected and noisy in your\nenvironment, consider adding exceptions \u2014 preferably with a combination of user and command line conditions.\n\n### Related rules\n\n- Volume Shadow Copy Deleted or Resized via VssAdmin - b5ea4bfe-a1b2-421f-9d47-22a75a6f2921\n- Volume Shadow Copy Deletion via PowerShell - d99a037b-c8e2-47a5-97b9-170d076827c4\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Consider isolating the involved host to prevent destructive behavior, which is commonly associated with this activity.\n- Priority should be given due to the advanced stage of this activity on the attack.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- If data was encrypted, deleted, or modified, activate your data recovery plan.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Perform data recovery locally or restore the backups from replicated copies (cloud, other servers, etc.).\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\"\n and (process.name : \"vssadmin.exe\" or process.pe.original_file_name == \"VSSADMIN.EXE\") and\n process.args in (\"delete\", \"resize\") and process.args : \"shadows*\"\n", "required_fields": [ { @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Impact" + "Impact", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_powershell.json index fefcf9f192ded..04563fc72f525 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_powershell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_powershell.json @@ -13,7 +13,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Volume Shadow Copy Deletion via PowerShell", - "note": "## Triage and analysis\n\n### Investigating Volume Shadow Copy Deletion via PowerShell\n\nThe Volume Shadow Copy Service (VSS) is a Windows feature that enables system administrators to take snapshots of volumes\nthat can later be restored or mounted to recover specific files or folders.\n\nA typical step in the playbook of an attacker attempting to deploy ransomware is to delete Volume Shadow\nCopies to ensure that victims have no alternative to paying the ransom, making any action that deletes shadow\ncopies worth monitoring.\n\nThis rule monitors the execution of PowerShell cmdlets to interact with the Win32_ShadowCopy WMI class, retrieve shadow\ncopy objects, and delete them.\n\n#### Possible investigation steps\n\n- Investigate the program execution chain (parent process tree).\n- Check whether the account is authorized to perform this operation.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- If unsigned files are found on the process tree, retrieve them and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Use process name, command line, and file hash to search for occurrences in other hosts.\n- Check if any files on the host machine have been encrypted.\n\n\n### False positive analysis\n\n- This rule has chances of producing benign true positives (B-TPs). If this activity is expected and noisy in your\nenvironment, consider adding exceptions \u2014 preferably with a combination of user and command line conditions.\n\n### Related rules\n\n- Volume Shadow Copy Deleted or Resized via VssAdmin - b5ea4bfe-a1b2-421f-9d47-22a75a6f2921\n- Volume Shadow Copy Deletion via PowerShell - d99a037b-c8e2-47a5-97b9-170d076827c4\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Consider isolating the involved host to prevent destructive behavior, which is commonly associated with this activity.\n- Priority should be given due to the advanced stage of this activity on the attack.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- If data was encrypted, deleted, or modified, activate your data recovery plan.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Perform data recovery locally or restore the backups from replicated copies (cloud, other servers, etc.).\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Volume Shadow Copy Deletion via PowerShell\n\nThe Volume Shadow Copy Service (VSS) is a Windows feature that enables system administrators to take snapshots of volumes\nthat can later be restored or mounted to recover specific files or folders.\n\nA typical step in the playbook of an attacker attempting to deploy ransomware is to delete Volume Shadow\nCopies to ensure that victims have no alternative to paying the ransom, making any action that deletes shadow\ncopies worth monitoring.\n\nThis rule monitors the execution of PowerShell cmdlets to interact with the Win32_ShadowCopy WMI class, retrieve shadow\ncopy objects, and delete them.\n\n#### Possible investigation steps\n\n- Investigate the program execution chain (parent process tree).\n- Check whether the account is authorized to perform this operation.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- If unsigned files are found on the process tree, retrieve them and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Use process name, command line, and file hash to search for occurrences in other hosts.\n- Check if any files on the host machine have been encrypted.\n\n\n### False positive analysis\n\n- This rule has chances of producing benign true positives (B-TPs). If this activity is expected and noisy in your\nenvironment, consider adding exceptions \u2014 preferably with a combination of user and command line conditions.\n\n### Related rules\n\n- Volume Shadow Copy Deleted or Resized via VssAdmin - b5ea4bfe-a1b2-421f-9d47-22a75a6f2921\n- Volume Shadow Copy Deletion via PowerShell - d99a037b-c8e2-47a5-97b9-170d076827c4\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Consider isolating the involved host to prevent destructive behavior, which is commonly associated with this activity.\n- Priority should be given due to the advanced stage of this activity on the attack.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- If data was encrypted, deleted, or modified, activate your data recovery plan.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Perform data recovery locally or restore the backups from replicated copies (cloud, other servers, etc.).\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.name : (\"powershell.exe\", \"pwsh.exe\", \"powershell_ise.exe\") and\n process.args : (\"*Get-WmiObject*\", \"*gwmi*\", \"*Get-CimInstance*\", \"*gcim*\") and\n process.args : (\"*Win32_ShadowCopy*\") and\n process.args : (\"*.Delete()*\", \"*Remove-WmiObject*\", \"*rwmi*\", \"*Remove-CimInstance*\", \"*rcim*\")\n", "references": [ "https://docs.microsoft.com/en-us/previous-versions/windows/desktop/vsswmi/win32-shadowcopy", @@ -46,7 +46,8 @@ "Host", "Windows", "Threat Detection", - "Impact" + "Impact", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_wmic.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_wmic.json index 0844dc6d0148d..eac82475417b6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_wmic.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_wmic.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Volume Shadow Copy Deletion via WMIC", - "note": "## Triage and analysis\n\n### Investigating Volume Shadow Copy Deletion via WMIC\n\nThe Volume Shadow Copy Service (VSS) is a Windows feature that enables system administrators to take snapshots of volumes\nthat can later be restored or mounted to recover specific files or folders.\n\nA typical step in the playbook of an attacker attempting to deploy ransomware is to delete Volume Shadow\nCopies to ensure that victims have no alternative to paying the ransom, making any action that deletes shadow\ncopies worth monitoring.\n\nThis rule monitors the execution of `wmic.exe` to interact with VSS via the `shadowcopy` alias and delete parameter.\n\n#### Possible investigation steps\n\n- Investigate the program execution chain (parent process tree).\n- Check whether the account is authorized to perform this operation.\n- Contact the account owner and confirm whether they are aware of this activity.\n- In the case of a resize operation, check if the resize value is equal to suspicious values, like 401MB.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- If unsigned files are found on the process tree, retrieve them and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Use process name, command line, and file hash to search for occurrences in other hosts.\n- Check if any files on the host machine have been encrypted.\n\n\n### False positive analysis\n\n- This rule has chances of producing benign true positives (B-TPs). If this activity is expected and noisy in your\nenvironment, consider adding exceptions \u2014 preferably with a combination of user and command line conditions.\n\n### Related rules\n\n- Volume Shadow Copy Deleted or Resized via VssAdmin - b5ea4bfe-a1b2-421f-9d47-22a75a6f2921\n- Volume Shadow Copy Deletion via PowerShell - d99a037b-c8e2-47a5-97b9-170d076827c4\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Priority should be given due to the advanced stage of this activity on the attack.\n- Consider isolating the involved host to prevent destructive behavior, which is commonly associated with this activity.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- If data was encrypted, deleted, or modified, activate your data recovery plan.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Perform data recovery locally or restore the backups from replicated copies (cloud, other servers, etc.).\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Volume Shadow Copy Deletion via WMIC\n\nThe Volume Shadow Copy Service (VSS) is a Windows feature that enables system administrators to take snapshots of volumes\nthat can later be restored or mounted to recover specific files or folders.\n\nA typical step in the playbook of an attacker attempting to deploy ransomware is to delete Volume Shadow\nCopies to ensure that victims have no alternative to paying the ransom, making any action that deletes shadow\ncopies worth monitoring.\n\nThis rule monitors the execution of `wmic.exe` to interact with VSS via the `shadowcopy` alias and delete parameter.\n\n#### Possible investigation steps\n\n- Investigate the program execution chain (parent process tree).\n- Check whether the account is authorized to perform this operation.\n- Contact the account owner and confirm whether they are aware of this activity.\n- In the case of a resize operation, check if the resize value is equal to suspicious values, like 401MB.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- If unsigned files are found on the process tree, retrieve them and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Use process name, command line, and file hash to search for occurrences in other hosts.\n- Check if any files on the host machine have been encrypted.\n\n\n### False positive analysis\n\n- This rule has chances of producing benign true positives (B-TPs). If this activity is expected and noisy in your\nenvironment, consider adding exceptions \u2014 preferably with a combination of user and command line conditions.\n\n### Related rules\n\n- Volume Shadow Copy Deleted or Resized via VssAdmin - b5ea4bfe-a1b2-421f-9d47-22a75a6f2921\n- Volume Shadow Copy Deletion via PowerShell - d99a037b-c8e2-47a5-97b9-170d076827c4\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Priority should be given due to the advanced stage of this activity on the attack.\n- Consider isolating the involved host to prevent destructive behavior, which is commonly associated with this activity.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- If data was encrypted, deleted, or modified, activate your data recovery plan.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Perform data recovery locally or restore the backups from replicated copies (cloud, other servers, etc.).\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n (process.name : \"WMIC.exe\" or process.pe.original_file_name == \"wmic.exe\") and\n process.args : \"delete\" and process.args : \"shadowcopy\"\n", "required_fields": [ { @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Impact" + "Impact", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts index 7d30ff7502a90..97878f9eb2e0b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts @@ -368,7 +368,7 @@ import rule355 from './persistence_google_workspace_api_access_granted_via_domai import rule356 from './defense_evasion_suspicious_short_program_name.json'; import rule357 from './lateral_movement_incoming_wmi.json'; import rule358 from './persistence_via_hidden_run_key_valuename.json'; -import rule359 from './credential_access_potential_ssh_bruteforce.json'; +import rule359 from './credential_access_potential_macos_ssh_bruteforce.json'; import rule360 from './credential_access_promt_for_pwd_via_osascript.json'; import rule361 from './lateral_movement_remote_services.json'; import rule362 from './defense_evasion_domain_added_to_google_workspace_trusted_domains.json'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin.json index 3dec3ef0087ae..d06a073fd504c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin.json @@ -57,7 +57,8 @@ "Azure", "Continuous Monitoring", "SecOps", - "Identity and Access" + "Identity and Access", + "has_guide" ], "threat": [ { @@ -78,5 +79,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin_atrisk_or_confirmed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin_atrisk_or_confirmed.json index c1aa77df2db99..c2d57924a39e4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin_atrisk_or_confirmed.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin_atrisk_or_confirmed.json @@ -52,7 +52,8 @@ "Azure", "Continuous Monitoring", "SecOps", - "Identity and Access" + "Identity and Access", + "has_guide" ], "threat": [ { @@ -73,5 +74,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json index e6660c2dc1251..d46d34a762cce 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json @@ -58,7 +58,8 @@ "Azure", "Continuous Monitoring", "SecOps", - "Identity and Access" + "Identity and Access", + "has_guide" ], "threat": [ { @@ -86,5 +87,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json index 9ce6e6ddaee9d..01a68b944d294 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json @@ -70,7 +70,8 @@ "Azure", "Continuous Monitoring", "SecOps", - "Identity and Access" + "Identity and Access", + "has_guide" ], "threat": [ { @@ -113,5 +114,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_console_login_root.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_console_login_root.json index 48b42a0351b9e..7612d79572c17 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_console_login_root.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_console_login_root.json @@ -64,7 +64,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Identity and Access" + "Identity and Access", + "has_guide" ], "threat": [ { @@ -100,5 +101,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json index 8c707115c0bb6..564667506aac3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Windows Script Executing PowerShell", - "note": "## Triage and analysis\n\n### Investigating Windows Script Executing PowerShell\n\nThe Windows Script Host (WSH) is an Windows automation technology, which is ideal for non-interactive scripting needs,\nsuch as logon scripting, administrative scripting, and machine automation.\n\nAttackers commonly use WSH scripts as their initial access method, acting like droppers for second stage payloads, but\ncan also use them to download tools and utilities needed to accomplish their goals.\n\nThis rule looks for the spawn of the `powershell.exe` process with `cscript.exe` or `wscript.exe` as its parent process.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate commands executed by the spawned PowerShell process.\n- If unsigned files are found on the process tree, retrieve them and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Determine how the script file was delivered (email attachment, dropped by other processes, etc.).\n- Investigate other alerts associated with the user/host during the past 48 hours.\n\n### False positive analysis\n\n- The usage of these script engines by regular users is unlikely. In the case of authorized benign true positives\n(B-TPs), exceptions can be added.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Reimage the host operating system and restore compromised files to clean versions.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Windows Script Executing PowerShell\n\nThe Windows Script Host (WSH) is an Windows automation technology, which is ideal for non-interactive scripting needs,\nsuch as logon scripting, administrative scripting, and machine automation.\n\nAttackers commonly use WSH scripts as their initial access method, acting like droppers for second stage payloads, but\ncan also use them to download tools and utilities needed to accomplish their goals.\n\nThis rule looks for the spawn of the `powershell.exe` process with `cscript.exe` or `wscript.exe` as its parent process.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate commands executed by the spawned PowerShell process.\n- If unsigned files are found on the process tree, retrieve them and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n- Determine how the script file was delivered (email attachment, dropped by other processes, etc.).\n- Investigate other alerts associated with the user/host during the past 48 hours.\n\n### False positive analysis\n\n- The usage of these script engines by regular users is unlikely. In the case of authorized benign true positives\n(B-TPs), exceptions can be added.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Reimage the host operating system and restore compromised files to clean versions.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.parent.name : (\"cscript.exe\", \"wscript.exe\") and process.name : \"powershell.exe\"\n", "required_fields": [ { @@ -40,7 +40,8 @@ "Host", "Windows", "Threat Detection", - "Initial Access" + "Initial Access", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json index 91f65ff6fbd18..9bc62b2b0ec53 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Suspicious MS Office Child Process", - "note": "## Triage and analysis\n\n### Investigating Suspicious MS Office Child Process\n\nMicrosoft Office (MS Office) is a suite of applications designed to help with productivity and completing common tasks on a computer.\nYou can create and edit documents containing text and images, work with data in spreadsheets and databases, and create\npresentations and posters. As it is some of the most-used software across companies, MS Office is frequently targeted\nfor initial access. It also has a wide variety of capabilities that attackers can take advantage of.\n\nThis rule looks for suspicious processes spawned by MS Office programs. This is generally the result of the execution of\nmalicious documents.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve MS Office documents received and opened by the user that could cause this behavior. Common locations include,\nbut are not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Suspicious MS Office Child Process\n\nMicrosoft Office (MS Office) is a suite of applications designed to help with productivity and completing common tasks on a computer.\nYou can create and edit documents containing text and images, work with data in spreadsheets and databases, and create\npresentations and posters. As it is some of the most-used software across companies, MS Office is frequently targeted\nfor initial access. It also has a wide variety of capabilities that attackers can take advantage of.\n\nThis rule looks for suspicious processes spawned by MS Office programs. This is generally the result of the execution of\nmalicious documents.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve MS Office documents received and opened by the user that could cause this behavior. Common locations include,\nbut are not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.parent.name : (\"eqnedt32.exe\", \"excel.exe\", \"fltldr.exe\", \"msaccess.exe\", \"mspub.exe\", \"powerpnt.exe\", \"winword.exe\", \"outlook.exe\") and\n process.name : (\"Microsoft.Workflow.Compiler.exe\", \"arp.exe\", \"atbroker.exe\", \"bginfo.exe\", \"bitsadmin.exe\", \"cdb.exe\", \"certutil.exe\",\n \"cmd.exe\", \"cmstp.exe\", \"control.exe\", \"cscript.exe\", \"csi.exe\", \"dnx.exe\", \"dsget.exe\", \"dsquery.exe\", \"forfiles.exe\",\n \"fsi.exe\", \"ftp.exe\", \"gpresult.exe\", \"hostname.exe\", \"ieexec.exe\", \"iexpress.exe\", \"installutil.exe\", \"ipconfig.exe\",\n \"mshta.exe\", \"msxsl.exe\", \"nbtstat.exe\", \"net.exe\", \"net1.exe\", \"netsh.exe\", \"netstat.exe\", \"nltest.exe\", \"odbcconf.exe\",\n \"ping.exe\", \"powershell.exe\", \"pwsh.exe\", \"qprocess.exe\", \"quser.exe\", \"qwinsta.exe\", \"rcsi.exe\", \"reg.exe\", \"regasm.exe\",\n \"regsvcs.exe\", \"regsvr32.exe\", \"sc.exe\", \"schtasks.exe\", \"systeminfo.exe\", \"tasklist.exe\", \"tracert.exe\", \"whoami.exe\",\n \"wmic.exe\", \"wscript.exe\", \"xwizard.exe\", \"explorer.exe\", \"rundll32.exe\", \"hh.exe\", \"msdt.exe\")\n", "required_fields": [ { @@ -40,7 +40,8 @@ "Host", "Windows", "Threat Detection", - "Initial Access" + "Initial Access", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json index 2b21f26bd82e9..0b21f7c5f2e75 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Suspicious MS Outlook Child Process", - "note": "## Triage and analysis\n\n### Investigating Suspicious MS Outlook Child Process\n\nMicrosoft Outlook is an email client that provides contact, email calendar, and task management features. Outlook is\nwidely used, either standalone or as part of the Office suite.\n\nThis rule looks for suspicious processes spawned by MS Outlook, which can be the result of the execution of malicious\ndocuments and/or exploitation for initial access.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve recently opened files received via email and opened by the user that could cause this behavior. Common\nlocations include but are not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Suspicious MS Outlook Child Process\n\nMicrosoft Outlook is an email client that provides contact, email calendar, and task management features. Outlook is\nwidely used, either standalone or as part of the Office suite.\n\nThis rule looks for suspicious processes spawned by MS Outlook, which can be the result of the execution of malicious\ndocuments and/or exploitation for initial access.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve recently opened files received via email and opened by the user that could cause this behavior. Common\nlocations include but are not limited to, the Downloads and Document folders and the folder configured at the email client.\n- Determine if the collected files are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n - If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.parent.name : \"outlook.exe\" and\n process.name : (\"Microsoft.Workflow.Compiler.exe\", \"arp.exe\", \"atbroker.exe\", \"bginfo.exe\", \"bitsadmin.exe\",\n \"cdb.exe\", \"certutil.exe\", \"cmd.exe\", \"cmstp.exe\", \"cscript.exe\", \"csi.exe\", \"dnx.exe\", \"dsget.exe\",\n \"dsquery.exe\", \"forfiles.exe\", \"fsi.exe\", \"ftp.exe\", \"gpresult.exe\", \"hostname.exe\", \"ieexec.exe\",\n \"iexpress.exe\", \"installutil.exe\", \"ipconfig.exe\", \"mshta.exe\", \"msxsl.exe\", \"nbtstat.exe\", \"net.exe\",\n \"net1.exe\", \"netsh.exe\", \"netstat.exe\", \"nltest.exe\", \"odbcconf.exe\", \"ping.exe\", \"powershell.exe\",\n \"pwsh.exe\", \"qprocess.exe\", \"quser.exe\", \"qwinsta.exe\", \"rcsi.exe\", \"reg.exe\", \"regasm.exe\",\n \"regsvcs.exe\", \"regsvr32.exe\", \"sc.exe\", \"schtasks.exe\", \"systeminfo.exe\", \"tasklist.exe\",\n \"tracert.exe\", \"whoami.exe\", \"wmic.exe\", \"wscript.exe\", \"xwizard.exe\")\n", "required_fields": [ { @@ -40,7 +40,8 @@ "Host", "Windows", "Threat Detection", - "Initial Access" + "Initial Access", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json index cab15fd6b1ed6..a91bdd8faea3e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json @@ -15,7 +15,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Unusual Child Process of dns.exe", - "note": "## Triage and analysis\n\n### Investigating Unusual Child Process of dns.exe\n\nSIGRed (CVE-2020-1350) is a wormable, critical vulnerability in the Windows DNS server that affects Windows Server\nversions 2003 to 2019 and can be triggered by a malicious DNS response. Because the service is running in elevated\nprivileges (SYSTEM), an attacker that successfully exploits it is granted Domain Administrator rights. This can\neffectively compromise the entire corporate infrastructure.\n\nThis rule looks for unusual children of the `dns.exe` process, which can indicate the exploitation of the SIGRed or a\nsimilar remote code execution vulnerability in the DNS server.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes.\n - Any suspicious or abnormal child process spawned from dns.exe should be carefully reviewed and investigated. It's\n impossible to predict what an adversary may deploy as the follow-on process after the exploit, but built-in\n discovery/enumeration utilities should be top of mind (`whoami.exe`, `netstat.exe`, `systeminfo.exe`, `tasklist.exe`).\n - Built-in Windows programs that contain capabilities used to download and execute additional payloads should also be\n considered. This is not an exhaustive list, but ideal candidates to start out would be: `mshta.exe`, `powershell.exe`,\n `regsvr32.exe`, `rundll32.exe`, `wscript.exe`, `wmic.exe`.\n - If a denial-of-service (DoS) exploit is successful and DNS Server service crashes, be mindful of potential child processes related to\n `werfault.exe` occurring.\n- Investigate abnormal behaviors observed by the subject process such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Investigate other alerts associated with the host during the past 48 hours.\n- Check whether the server is vulnerable to CVE-2020-1350.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Reimage the host operating system or restore the compromised server to a clean state.\n- Install the latest patches on systems that run Microsoft DNS Server.\n- Consider the implementation of a patch management system, such as the Windows Server Update Services (WSUS).\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Review the privileges assigned to the user to ensure that the least privilege principle is being followed.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Unusual Child Process of dns.exe\n\nSIGRed (CVE-2020-1350) is a wormable, critical vulnerability in the Windows DNS server that affects Windows Server\nversions 2003 to 2019 and can be triggered by a malicious DNS response. Because the service is running in elevated\nprivileges (SYSTEM), an attacker that successfully exploits it is granted Domain Administrator rights. This can\neffectively compromise the entire corporate infrastructure.\n\nThis rule looks for unusual children of the `dns.exe` process, which can indicate the exploitation of the SIGRed or a\nsimilar remote code execution vulnerability in the DNS server.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes.\n - Any suspicious or abnormal child process spawned from dns.exe should be carefully reviewed and investigated. It's\n impossible to predict what an adversary may deploy as the follow-on process after the exploit, but built-in\n discovery/enumeration utilities should be top of mind (`whoami.exe`, `netstat.exe`, `systeminfo.exe`, `tasklist.exe`).\n - Built-in Windows programs that contain capabilities used to download and execute additional payloads should also be\n considered. This is not an exhaustive list, but ideal candidates to start out would be: `mshta.exe`, `powershell.exe`,\n `regsvr32.exe`, `rundll32.exe`, `wscript.exe`, `wmic.exe`.\n - If a denial-of-service (DoS) exploit is successful and DNS Server service crashes, be mindful of potential child processes related to\n `werfault.exe` occurring.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Investigate other alerts associated with the host during the past 48 hours.\n- Check whether the server is vulnerable to CVE-2020-1350.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Reimage the host operating system or restore the compromised server to a clean state.\n- Install the latest patches on systems that run Microsoft DNS Server.\n- Consider the implementation of a patch management system, such as the Windows Server Update Services (WSUS).\n- Run a full scan using the antimalware tool in place. This scan can reveal additional artifacts left in the system,\npersistence mechanisms, and malware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Review the privileges assigned to the user to ensure that the least privilege principle is being followed.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and process.parent.name : \"dns.exe\" and\n not process.name : \"conhost.exe\"\n", "references": [ "https://research.checkpoint.com/2020/resolving-your-way-into-domain-admin-exploiting-a-17-year-old-bug-in-windows-dns-servers/", @@ -48,7 +48,8 @@ "Host", "Windows", "Threat Detection", - "Initial Access" + "Initial Access", + "has_guide" ], "threat": [ { @@ -69,5 +70,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_system_manager.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_system_manager.json index 1af2502b0034a..78fea7b5dafe2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_system_manager.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_system_manager.json @@ -60,7 +60,8 @@ "Continuous Monitoring", "SecOps", "Log Auditing", - "Initial Access" + "Initial Access", + "has_guide" ], "threat": [ { @@ -88,5 +89,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json index 62d4c160e806f..000e631380307 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Direct Outbound SMB Connection", - "note": "## Triage and analysis\n\n### Investigating Direct Outbound SMB Connection\n\nThis rule looks for unexpected processes making network connections over port 445. Windows file sharing is typically\nimplemented over Server Message Block (SMB), which communicates between hosts using port 445. When legitimate, these\nnetwork connections are established by the kernel (PID 4). Occurrences of non-system processes using this port can indicate\nport scanners, exploits, and tools used to move laterally on the environment.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate abnormal behaviors observed by the subject process such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- If this rule is noisy in your environment due to expected activity, consider adding exceptions \u2014 preferably with a combination\nof user and command line conditions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating Direct Outbound SMB Connection\n\nThis rule looks for unexpected processes making network connections over port 445. Windows file sharing is typically\nimplemented over Server Message Block (SMB), which communicates between hosts using port 445. When legitimate, these\nnetwork connections are established by the kernel (PID 4). Occurrences of non-system processes using this port can indicate\nport scanners, exploits, and tools used to move laterally on the environment.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- If this rule is noisy in your environment due to expected activity, consider adding exceptions \u2014 preferably with a combination\nof user and command line conditions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence by process.entity_id\n [process where event.type == \"start\" and host.os.name == \"Windows\" and process.pid != 4 and\n not (process.executable : \"D:\\\\EnterpriseCare\\\\tools\\\\jre.1\\\\bin\\\\java.exe\" and process.args : \"com.emeraldcube.prism.launcher.Invoker\") and\n not (process.executable : \"C:\\\\Docusnap 11\\\\Tools\\\\nmap\\\\nmap.exe\" and process.args : \"smb-os-discovery.nse\") and\n not process.executable :\n (\"?:\\\\Program Files\\\\SentinelOne\\\\Sentinel Agent *\\\\Ranger\\\\SentinelRanger.exe\",\n \"?:\\\\Program Files\\\\Ivanti\\\\Security Controls\\\\ST.EngineHost.exe\",\n \"?:\\\\Program Files (x86)\\\\Fortinet\\\\FSAE\\\\collectoragent.exe\",\n \"?:\\\\Program Files (x86)\\\\Nmap\\\\nmap.exe\",\n \"?:\\\\Program Files\\\\Azure Advanced Threat Protection Sensor\\\\*\\\\Microsoft.Tri.Sensor.exe\",\n \"?:\\\\Program Files\\\\CloudMatters\\\\auvik\\\\AuvikService-release-*\\\\AuvikService.exe\",\n \"?:\\\\Program Files\\\\uptime software\\\\uptime\\\\UptimeDataCollector.exe\",\n \"?:\\\\Program Files\\\\CloudMatters\\\\auvik\\\\AuvikAgentService.exe\",\n \"?:\\\\Program Files\\\\Rumble\\\\rumble-agent-*.exe\")]\n [network where destination.port == 445 and process.pid != 4 and\n not cidrmatch(destination.ip, \"127.0.0.1\", \"::1\")]\n", "required_fields": [ { @@ -64,7 +64,8 @@ "Host", "Windows", "Threat Detection", - "Lateral Movement" + "Lateral Movement", + "has_guide" ], "threat": [ { @@ -91,5 +92,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dns_server_overflow.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dns_server_overflow.json index be4535a908006..1d985fb800a68 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dns_server_overflow.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dns_server_overflow.json @@ -59,7 +59,8 @@ "Elastic", "Network", "Threat Detection", - "Lateral Movement" + "Lateral Movement", + "has_guide" ], "threat": [ { @@ -80,5 +81,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json index 5c463878f146e..cd1de0b09dc00 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Potential Lateral Tool Transfer via SMB Share", - "note": "## Triage and analysis\n\n### Investigating Potential Lateral Tool Transfer via SMB Share\n\nAdversaries can use network shares to host tooling to support the compromise of other hosts in the environment. These tools\ncan include discovery utilities, credential dumpers, malware, etc. Attackers can also leverage file shares that employees\nfrequently access to host malicious files to gain a foothold in other machines.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve the created file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity can happen legitimately. Consider adding exceptions if it is expected and noisy in your environment.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Review the privileges needed to write to the network share and restrict write access as needed.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating Potential Lateral Tool Transfer via SMB Share\n\nAdversaries can use network shares to host tooling to support the compromise of other hosts in the environment. These tools\ncan include discovery utilities, credential dumpers, malware, etc. Attackers can also leverage file shares that employees\nfrequently access to host malicious files to gain a foothold in other machines.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account owner and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve the created file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity can happen legitimately. Consider adding exceptions if it is expected and noisy in your environment.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Review the privileges needed to write to the network share and restrict write access as needed.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence by host.id with maxspan=30s\n [network where event.type == \"start\" and process.pid == 4 and destination.port == 445 and\n network.direction : (\"incoming\", \"ingress\") and\n network.transport == \"tcp\" and source.ip != \"127.0.0.1\" and source.ip != \"::1\"\n ] by process.entity_id\n /* add more executable extensions here if they are not noisy in your environment */\n [file where event.type in (\"creation\", \"change\") and process.pid == 4 and file.extension : (\"exe\", \"dll\", \"bat\", \"cmd\")] by process.entity_id\n", "required_fields": [ { @@ -69,7 +69,8 @@ "Host", "Windows", "Threat Detection", - "Lateral Movement" + "Lateral Movement", + "has_guide" ], "threat": [ { @@ -101,5 +102,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json index 0e6aab67cf050..301ce56a51f5d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json @@ -12,6 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Remote Execution via File Shares", + "note": "## Triage and analysis\n\n### Investigating Remote Execution via File Shares\n\nAdversaries can use network shares to host tooling to support the compromise of other hosts in the environment. These\ntools can include discovery utilities, credential dumpers, malware, etc.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Review adjacent login events (e.g., 4624) in the alert timeframe to identify the account used to perform this action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity can happen legitimately. Consider adding exceptions if it is expected and noisy in your environment.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Review the privileges needed to write to the network share and restrict write access as needed.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence with maxspan=1m\n [file where event.type in (\"creation\", \"change\") and process.pid == 4 and file.extension : \"exe\"] by host.id, file.path\n [process where event.type == \"start\"] by host.id, process.executable\n", "references": [ "https://blog.menasec.net/2020/08/new-trick-to-detect-lateral-movement.html" diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_enabled_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_enabled_registry.json index bc3a4e3b0ac95..12f9216c7b6ec 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_enabled_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_enabled_registry.json @@ -55,7 +55,8 @@ "Host", "Windows", "Threat Detection", - "Lateral Movement" + "Lateral Movement", + "has_guide" ], "threat": [ { @@ -83,5 +84,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json index d0504020fcad3..45144cc486895 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json @@ -12,7 +12,11 @@ "language": "eql", "license": "Elastic License v2", "name": "Remotely Started Services via RPC", + "note": "## Triage and analysis\n\n### Investigating Remotely Started Services via RPC\n\nThe Service Control Manager Remote Protocol is a client/server protocol used for configuring and controlling service\nprograms running on a remote computer. A remote service management session begins with the client initiating the\nconnection request to the server. If the server grants the request, the connection is established. The client can then\nmake multiple requests to modify, query the configuration, or start and stop services on the server by using the same\nsession until the session is terminated.\n\nThis rule detects the remote creation or start of a service by correlating a `services.exe` network connection and the\nspawn of a child process.\n\n#### Possible investigation steps\n\n- Review login events (e.g., 4624) in the alert timeframe to identify the account used to perform this action. Use the\n`source.address` field to help identify the source system.\n- Review network events from the source system using the source port identified on the alert and try to identify the\nprogram used to initiate the action.\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Validate if the activity is not related to planned patches, updates, network administrator activity, or legitimate\nsoftware installations.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- Remote management software like SCCM may trigger this rule. If noisy on your environment, consider adding exceptions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved hosts to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence with maxspan=1s\n [network where process.name : \"services.exe\" and\n network.direction : (\"incoming\", \"ingress\") and network.transport == \"tcp\" and\n source.port >= 49152 and destination.port >= 49152 and source.ip != \"127.0.0.1\" and source.ip != \"::1\"\n ] by host.id, process.entity_id\n\n [process where event.type == \"start\" and process.parent.name : \"services.exe\" and \n not (process.name : \"svchost.exe\" and process.args : \"tiledatamodelsvc\") and\n not (process.name : \"msiexec.exe\" and process.args : \"/V\") and\n not process.executable :\n (\"?:\\\\Windows\\\\ADCR_Agent\\\\adcrsvc.exe\",\n \"?:\\\\Windows\\\\System32\\\\VSSVC.exe\",\n \"?:\\\\Windows\\\\servicing\\\\TrustedInstaller.exe\",\n \"?:\\\\Windows\\\\System32\\\\svchost.exe\",\n \"?:\\\\Program Files (x86)\\\\*.exe\",\n \"?:\\\\Program Files\\\\*.exe\",\n \"?:\\\\Windows\\\\PSEXESVC.EXE\",\n \"?:\\\\Windows\\\\System32\\\\sppsvc.exe\",\n \"?:\\\\Windows\\\\System32\\\\wbem\\\\WmiApSrv.exe\",\n \"?:\\\\WINDOWS\\\\RemoteAuditService.exe\",\n \"?:\\\\Windows\\\\VeeamVssSupport\\\\VeeamGuestHelper.exe\",\n \"?:\\\\Windows\\\\VeeamLogShipper\\\\VeeamLogShipper.exe\",\n \"?:\\\\Windows\\\\CAInvokerService.exe\",\n \"?:\\\\Windows\\\\System32\\\\upfc.exe\",\n \"?:\\\\Windows\\\\AdminArsenal\\\\PDQ*.exe\",\n \"?:\\\\Windows\\\\System32\\\\vds.exe\",\n \"?:\\\\Windows\\\\Veeam\\\\Backup\\\\VeeamDeploymentSvc.exe\",\n \"?:\\\\Windows\\\\ProPatches\\\\Scheduler\\\\STSchedEx.exe\",\n \"?:\\\\Windows\\\\System32\\\\certsrv.exe\",\n \"?:\\\\Windows\\\\eset-remote-install-service.exe\",\n \"?:\\\\Pella Corporation\\\\Pella Order Management\\\\GPAutoSvc.exe\",\n \"?:\\\\Pella Corporation\\\\OSCToGPAutoService\\\\OSCToGPAutoSvc.exe\",\n \"?:\\\\Pella Corporation\\\\Pella Order Management\\\\GPAutoSvc.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\NwxExeSvc\\\\NwxExeSvc.exe\",\n \"?:\\\\Windows\\\\System32\\\\taskhostex.exe\")\n ] by host.id, process.parent.entity_id\n", + "references": [ + "https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-scmr/705b624a-13de-43cc-b8a2-99573da3635f" + ], "required_fields": [ { "ecs": true, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_scheduled_task_target.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_scheduled_task_target.json index 1896f18299853..06dd1913a6f1b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_scheduled_task_target.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_scheduled_task_target.json @@ -64,7 +64,8 @@ "Host", "Windows", "Threat Detection", - "Lateral Movement" + "Lateral Movement", + "has_guide" ], "threat": [ { @@ -106,5 +107,5 @@ } ], "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_error_message_spike.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_error_message_spike.json index 8ccc5adc9dce2..112767349fb88 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_error_message_spike.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_error_message_spike.json @@ -25,8 +25,9 @@ "Elastic", "Cloud", "AWS", - "ML" + "ML", + "has_guide" ], "type": "machine_learning", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json index eba9e157895ee..649df5bcfb66e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json @@ -25,8 +25,9 @@ "Elastic", "Cloud", "AWS", - "ML" + "ML", + "has_guide" ], "type": "machine_learning", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json index d17e1053e2ccc..1368f04639b5c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json @@ -25,8 +25,9 @@ "Elastic", "Cloud", "AWS", - "ML" + "ML", + "has_guide" ], "type": "machine_learning", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json index c170c6a338b30..4719a47dc5d9d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json @@ -25,8 +25,9 @@ "Elastic", "Cloud", "AWS", - "ML" + "ML", + "has_guide" ], "type": "machine_learning", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json index 22ef1411a537c..74f190786b086 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json @@ -25,8 +25,9 @@ "Elastic", "Cloud", "AWS", - "ML" + "ML", + "has_guide" ], "type": "machine_learning", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json index 02bcc8eff6864..9624d0b995c11 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Adobe Hijack Persistence", - "note": "## Triage and analysis\n\n### Investigating Adobe Hijack Persistence\n\nAttackers can replace the `RdrCEF.exe` executable with their own to maintain their access, which will be launched\nwhenever Adobe Acrobat Reader is executed.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Adobe Hijack Persistence\n\nAttackers can replace the `RdrCEF.exe` executable with their own to maintain their access, which will be launched\nwhenever Adobe Acrobat Reader is executed.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "file where event.type == \"creation\" and\n file.path : (\"?:\\\\Program Files (x86)\\\\Adobe\\\\Acrobat Reader DC\\\\Reader\\\\AcroCEF\\\\RdrCEF.exe\",\n \"?:\\\\Program Files\\\\Adobe\\\\Acrobat Reader DC\\\\Reader\\\\AcroCEF\\\\RdrCEF.exe\") and\n not process.name : \"msiexec.exe\"\n", "references": [ "https://twitter.com/pabraeken/status/997997818362155008" @@ -43,7 +43,8 @@ "Host", "Windows", "Threat Detection", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { @@ -71,5 +72,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json index ca2be5273f8f2..80720e7aff6ce 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json @@ -50,7 +50,8 @@ "Azure", "Continuous Monitoring", "SecOps", - "Identity and Access" + "Identity and Access", + "has_guide" ], "threat": [ { @@ -86,5 +87,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_dontexpirepasswd_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_dontexpirepasswd_account.json index e335f4cea7319..6b20c9653773b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_dontexpirepasswd_account.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_dontexpirepasswd_account.json @@ -51,7 +51,8 @@ "Windows", "Threat Detection", "Persistence", - "Active Directory" + "Active Directory", + "has_guide" ], "threat": [ { @@ -72,5 +73,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json index 6f3aa83b004b6..ab09c9a6cf354 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json @@ -34,7 +34,8 @@ "Host", "Windows", "Threat Detection", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { @@ -62,5 +63,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json index c1547b38e67b6..e1b8862c4424a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json @@ -10,7 +10,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Suspicious Startup Shell Folder Modification", - "note": "## Triage and analysis\n\n### Investigating Suspicious Startup Shell Folder Modification\n\nTechniques used within malware and by adversaries often leverage the Windows registry to store malicious programs for\npersistence. Startup shell folders are often targeted as they are not as prevalent as normal Startup folder paths so this\nbehavior may evade existing AV/EDR solutions. These programs may also run with higher privileges which can be ideal for\nan attacker.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Review the source process and related file tied to the Windows Registry entry.\n- Validate the activity is not related to planned patches, updates, network administrator activity or legitimate software\ninstallations.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- There is a high possibility of benign legitimate programs being added to shell folders. This activity could be based\non new software installations, patches, or other network administrator activity. Before entering further investigation,\nit should be verified that this activity is not benign.\n\n### Related rules\n\n- Startup or Run Key Registry Modification - 97fc44d3-8dae-4019-ae83-298c3015600f\n- Persistent Scripts in the Startup Directory - f7c4dc5a-a58d-491d-9f14-9b66507121c0\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating Suspicious Startup Shell Folder Modification\n\nTechniques used within malware and by adversaries often leverage the Windows registry to store malicious programs for\npersistence. Startup shell folders are often targeted as they are not as prevalent as normal Startup folder paths so this\nbehavior may evade existing AV/EDR solutions. These programs may also run with higher privileges which can be ideal for\nan attacker.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Review the source process and related file tied to the Windows Registry entry.\n- Validate the activity is not related to planned patches, updates, network administrator activity or legitimate software\ninstallations.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- There is a high possibility of benign legitimate programs being added to shell folders. This activity could be based\non new software installations, patches, or other network administrator activity. Before undertaking further investigation,\nit should be verified that this activity is not benign.\n\n### Related rules\n\n- Startup or Run Key Registry Modification - 97fc44d3-8dae-4019-ae83-298c3015600f\n- Persistent Scripts in the Startup Directory - f7c4dc5a-a58d-491d-9f14-9b66507121c0\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- If the malicious file was delivered via phishing:\n - Block the email sender from sending future emails.\n - Block the malicious web pages.\n - Remove emails from the sender from mailboxes.\n - Consider improvements to the security awareness program.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "registry where\n registry.path : (\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\User Shell Folders\\\\Common Startup\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\Shell Folders\\\\Common Startup\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\User Shell Folders\\\\Startup\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\Shell Folders\\\\Startup\"\n ) and\n registry.data.strings != null and\n /* Normal Startup Folder Paths */\n not registry.data.strings : (\n \"C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\",\n \"%ProgramData%\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\",\n \"%USERPROFILE%\\\\AppData\\\\Roaming\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\",\n \"C:\\\\Users\\\\*\\\\AppData\\\\Roaming\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\"\n )\n", "required_fields": [ { @@ -32,7 +32,8 @@ "Host", "Windows", "Threat Detection", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { @@ -60,5 +61,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json index 6d014886b1fa4..36fdb7f9316dd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json @@ -13,7 +13,7 @@ "license": "Elastic License v2", "name": "Creation or Modification of a new GPO Scheduled Task or Service", "note": "", - "query": "file where event.type != \"deletion\" and\n file.path : (\"?:\\\\Windows\\\\SYSVOL\\\\domain\\\\Policies\\\\*\\\\MACHINE\\\\Preferences\\\\ScheduledTasks\\\\ScheduledTasks.xml\",\n \"?:\\\\Windows\\\\SYSVOL\\\\domain\\\\Policies\\\\*\\\\MACHINE\\\\Preferences\\\\Preferences\\\\Services\\\\Services.xml\") and\n not process.name : \"dfsrs.exe\"\n", + "query": "file where event.type != \"deletion\" and\n file.path : (\"?:\\\\Windows\\\\SYSVOL\\\\domain\\\\Policies\\\\*\\\\MACHINE\\\\Preferences\\\\ScheduledTasks\\\\ScheduledTasks.xml\",\n \"?:\\\\Windows\\\\SYSVOL\\\\domain\\\\Policies\\\\*\\\\MACHINE\\\\Preferences\\\\Services\\\\Services.xml\") and\n not process.name : \"dfsrs.exe\"\n", "required_fields": [ { "ecs": true, @@ -68,5 +68,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json index 67c7c9ad84ddc..8b21e5358f71b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json @@ -46,7 +46,8 @@ "Azure", "Continuous Monitoring", "SecOps", - "Identity and Access" + "Identity and Access", + "has_guide" ], "threat": [ { @@ -67,5 +68,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_rare_process_by_host_windows.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_rare_process_by_host_windows.json index 7ae8401cf782d..8c79a775a7779 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_rare_process_by_host_windows.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_rare_process_by_host_windows.json @@ -27,7 +27,8 @@ "Windows", "Threat Detection", "ML", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { @@ -54,5 +55,5 @@ } ], "type": "machine_learning", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json index 30786d630001c..385f0aee4aab5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Potential Modification of Accessibility Binaries", - "note": "## Triage and analysis\n\n### Investigating Potential Modification of Accessibility Binaries\n\nAdversaries may establish persistence and/or elevate privileges by executing malicious content triggered by\naccessibility features. Windows contains accessibility features that may be launched with a key combination before a\nuser has logged in (ex: when the user is on the Windows logon screen). An adversary can modify the way these programs\nare launched to get a command prompt or backdoor without logging in to the system.\n\nMore details can be found [here](https://attack.mitre.org/techniques/T1546/008/).\n\nThis rule looks for the execution of supposed accessibility binaries that don't match any of the accessibility features\nbinaries' original file names, which is likely a custom binary deployed by the attacker.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account and system owners and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity should not happen legitimately. The security team should address any potential benign true positive\n(B-TP), as this configuration can put the user and the domain at risk.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Potential Modification of Accessibility Binaries\n\nAdversaries may establish persistence and/or elevate privileges by executing malicious content triggered by\naccessibility features. Windows contains accessibility features that may be launched with a key combination before a\nuser has logged in (ex: when the user is on the Windows logon screen). An adversary can modify the way these programs\nare launched to get a command prompt or backdoor without logging in to the system.\n\nMore details can be found [here](https://attack.mitre.org/techniques/T1546/008/).\n\nThis rule looks for the execution of supposed accessibility binaries that don't match any of the accessibility features\nbinaries' original file names, which is likely a custom binary deployed by the attacker.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Contact the account and system owners and confirm whether they are aware of this activity.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity should not happen legitimately. The security team should address any potential benign true positive\n(B-TP), as this configuration can put the user and the domain at risk.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.parent.name : (\"Utilman.exe\", \"winlogon.exe\") and user.name == \"SYSTEM\" and\n process.args :\n (\n \"C:\\\\Windows\\\\System32\\\\osk.exe\",\n \"C:\\\\Windows\\\\System32\\\\Magnify.exe\",\n \"C:\\\\Windows\\\\System32\\\\Narrator.exe\",\n \"C:\\\\Windows\\\\System32\\\\Sethc.exe\",\n \"utilman.exe\",\n \"ATBroker.exe\",\n \"DisplaySwitch.exe\",\n \"sethc.exe\"\n )\n and not process.pe.original_file_name in\n (\n \"osk.exe\",\n \"sethc.exe\",\n \"utilman2.exe\",\n \"DisplaySwitch.exe\",\n \"ATBroker.exe\",\n \"ScreenMagnifier.exe\",\n \"SR.exe\",\n \"Narrator.exe\",\n \"magnify.exe\",\n \"MAGNIFY.EXE\"\n )\n\n/* uncomment once in winlogbeat to avoid bypass with rogue process with matching pe original file name */\n/* and process.code_signature.subject_name == \"Microsoft Windows\" and process.code_signature.status == \"trusted\" */\n", "references": [ "https://www.elastic.co/blog/practical-security-engineering-stateful-detection" @@ -53,7 +53,8 @@ "Host", "Windows", "Threat Detection", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json index 7541049e4fd3e..04da402d1caf9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json @@ -10,6 +10,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Startup or Run Key Registry Modification", + "note": "## Triage and analysis\n\n### Investigating Startup or Run Key Registry Modification\n\nAdversaries may achieve persistence by referencing a program with a registry run key. Adding an entry to the run keys\nin the registry will cause the program referenced to be executed when a user logs in. These programs will executed\nunder the context of the user and will have the account's permissions. This rule looks for this behavior by monitoring\na range of registry run keys.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate\nsoftware installations.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- There is a high possibility of benign legitimate programs being added to registry run keys. This activity could be\nbased on new software installations, patches, or any kind of network administrator related activity. Before undertaking\nfurther investigation, verify that this activity is not benign.\n\n### Related rules\n\n- Suspicious Startup Shell Folder Modification - c8b150f0-0164-475b-a75e-74b47800a9ff\n- Persistent Scripts in the Startup Directory - f7c4dc5a-a58d-491d-9f14-9b66507121c0\n- Startup Folder Persistence via Unsigned Process - 2fba96c0-ade5-4bce-b92f-a5df2509da3f\n- Startup Persistence by a Suspicious Process - 440e2db4-bc7f-4c96-a068-65b78da59bde\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "registry where registry.data.strings != null and\n registry.path : (\n /* Machine Hive */\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\*\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnce\\\\*\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnceEx\\\\*\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\Explorer\\\\Run\\\\*\",\n \"HKLM\\\\Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Winlogon\\\\Shell\\\\*\",\n /* Users Hive */\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\\\\*\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnce\\\\*\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\RunOnceEx\\\\*\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\Explorer\\\\Run\\\\*\",\n \"HKEY_USERS\\\\*\\\\Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Winlogon\\\\Shell\\\\*\"\n ) and\n /* add common legitimate changes without being too restrictive as this is one of the most abused AESPs */\n not registry.data.strings : \"ctfmon.exe /n\" and\n not (registry.value : \"Application Restart #*\" and process.name : \"csrss.exe\") and\n user.id not in (\"S-1-5-18\", \"S-1-5-19\", \"S-1-5-20\") and\n not registry.data.strings : (\"?:\\\\Program Files\\\\*.exe\", \"?:\\\\Program Files (x86)\\\\*.exe\") and\n not process.executable : (\"?:\\\\Windows\\\\System32\\\\msiexec.exe\", \"?:\\\\Windows\\\\SysWOW64\\\\msiexec.exe\") and\n not (process.name : \"OneDriveSetup.exe\" and\n registry.value : (\"Delete Cached Standalone Update Binary\", \"Delete Cached Update Binary\", \"amd64\", \"Uninstall *\") and\n registry.data.strings : \"?:\\\\Windows\\\\system32\\\\cmd.exe /q /c * \\\"?:\\\\Users\\\\*\\\\AppData\\\\Local\\\\Microsoft\\\\OneDrive\\\\*\\\"\")\n", "required_fields": [ { @@ -81,5 +82,5 @@ "timeline_title": "Comprehensive Registry Timeline", "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_sdprop_exclusion_dsheuristics.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_sdprop_exclusion_dsheuristics.json index 9d524bd69b5a8..13da283b0097d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_sdprop_exclusion_dsheuristics.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_sdprop_exclusion_dsheuristics.json @@ -49,7 +49,8 @@ "Windows", "Threat Detection", "Persistence", - "Active Directory" + "Active Directory", + "has_guide" ], "threat": [ { @@ -64,5 +65,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json index db214d1b94467..a9375cd4f50ff 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json @@ -14,6 +14,7 @@ "language": "kuery", "license": "Elastic License v2", "name": "Potential Shell via Web Server", + "note": "## Triage and analysis\n\n### Investigating Potential Shell via Web Server\n\nAdversaries may backdoor web servers with web shells to establish persistent access to systems. A web shell is a web\nscript that is placed on an openly accessible web server to allow an adversary to use the web server as a gateway into a\nnetwork. A web shell may provide a set of functions to execute or a command line interface on the system that hosts the\nweb server.\n\nThis rule detects a web server process spawning script and command line interface programs, potentially indicating\nattackers executing commands using the web shell.\n\n#### Possible investigation steps\n\n- Investigate abnormal behaviors observed by the subject process such as network connections, file modifications, and\nany other spawned child processes.\n- Examine the command line to determine which commands or scripts were executed.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- If scripts or executables were dropped, retrieve the files and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - Check if the domain is newly registered or unexpected.\n - Check the reputation of the domain or IP address.\n - File access, modification, and creation activities.\n - Cron jobs, services and other persistence mechanisms.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Any activity that triggered the alert and is not inherently\nmalicious must be monitored by the security team.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "event.category:process and event.type:(start or process_started) and\nprocess.name:(bash or dash or ash or zsh or \"python*\" or \"perl*\" or \"php*\") and\nprocess.parent.name:(\"apache\" or \"nginx\" or \"www\" or \"apache2\" or \"httpd\" or \"www-data\")\n", "references": [ "https://pentestlab.blog/tag/web-shell/" @@ -76,5 +77,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json index d3e19871a157d..b477cd0148352 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Startup Persistence by a Suspicious Process", - "note": "## Triage and analysis\n\n### Investigating Startup Persistence by a Suspicious Process\n\nThe Windows Startup folder is a special folder in Windows. Programs added to this folder are executed during account\nlogon, without user interaction, providing an excellent way for attackers to maintain persistence.\n\nThis rule monitors for commonly abused processes writing to the Startup folder locations.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate\nsoftware installations.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- Administrators may add programs to this mechanism via command-line shells. Before the further investigation,\nverify that this activity is not benign.\n\n### Related rules\n\n- Suspicious Startup Shell Folder Modification - c8b150f0-0164-475b-a75e-74b47800a9ff\n- Persistent Scripts in the Startup Directory - f7c4dc5a-a58d-491d-9f14-9b66507121c0\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Startup Persistence by a Suspicious Process\n\nThe Windows Startup folder is a special folder in Windows. Programs added to this folder are executed during account\nlogon, without user interaction, providing an excellent way for attackers to maintain persistence.\n\nThis rule monitors for commonly abused processes writing to the Startup folder locations.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate\nsoftware installations.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- Administrators may add programs to this mechanism via command-line shells. Before the further investigation,\nverify that this activity is not benign.\n\n### Related rules\n\n- Suspicious Startup Shell Folder Modification - c8b150f0-0164-475b-a75e-74b47800a9ff\n- Persistent Scripts in the Startup Directory - f7c4dc5a-a58d-491d-9f14-9b66507121c0\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "file where event.type != \"deletion\" and\n user.domain != \"NT AUTHORITY\" and\n file.path : (\"C:\\\\Users\\\\*\\\\AppData\\\\Roaming\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\\\\*\",\n \"C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\StartUp\\\\*\") and\n process.name : (\"cmd.exe\",\n \"powershell.exe\",\n \"wmic.exe\",\n \"mshta.exe\",\n \"pwsh.exe\",\n \"cscript.exe\",\n \"wscript.exe\",\n \"regsvr32.exe\",\n \"RegAsm.exe\",\n \"rundll32.exe\",\n \"EQNEDT32.EXE\",\n \"WINWORD.EXE\",\n \"EXCEL.EXE\",\n \"POWERPNT.EXE\",\n \"MSPUB.EXE\",\n \"MSACCESS.EXE\",\n \"iexplore.exe\",\n \"InstallUtil.exe\")\n", "required_fields": [ { @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { @@ -73,5 +74,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json index 8d8a6b31fd0f9..82aa2eba13fe1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json @@ -10,7 +10,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Startup Folder Persistence via Unsigned Process", - "note": "## Triage and analysis\n\n### Investigating Startup Folder Persistence via Unsigned Process\n\nThe Windows Startup folder is a special folder in Windows. Programs added to this folder are executed during account\nlogon, without user interaction, providing an excellent way for attackers to maintain persistence.\n\nThis rule looks for unsigned processes writing to the Startup folder locations.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate\nsoftware installations.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- There is a high possibility of benign legitimate programs being added to Startup folders. This activity could be based\non new software installations, patches, or any kind of network administrator related activity. Before entering further\ninvestigation, verify that this activity is not benign.\n\n### Related rules\n\n- Suspicious Startup Shell Folder Modification - c8b150f0-0164-475b-a75e-74b47800a9ff\n- Persistent Scripts in the Startup Directory - f7c4dc5a-a58d-491d-9f14-9b66507121c0\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", + "note": "## Triage and analysis\n\n### Investigating Startup Folder Persistence via Unsigned Process\n\nThe Windows Startup folder is a special folder in Windows. Programs added to this folder are executed during account\nlogon, without user interaction, providing an excellent way for attackers to maintain persistence.\n\nThis rule looks for unsigned processes writing to the Startup folder locations.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate\nsoftware installations.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- There is a high possibility of benign legitimate programs being added to Startup folders. This activity could be based\non new software installations, patches, or any kind of network administrator related activity. Before undertaking further\ninvestigation, verify that this activity is not benign.\n\n### Related rules\n\n- Suspicious Startup Shell Folder Modification - c8b150f0-0164-475b-a75e-74b47800a9ff\n- Persistent Scripts in the Startup Directory - f7c4dc5a-a58d-491d-9f14-9b66507121c0\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).\n", "query": "sequence by host.id, process.entity_id with maxspan=5s\n [process where event.type == \"start\" and process.code_signature.trusted == false and\n /* suspicious paths can be added here */\n process.executable : (\"C:\\\\Users\\\\*.exe\",\n \"C:\\\\ProgramData\\\\*.exe\",\n \"C:\\\\Windows\\\\Temp\\\\*.exe\",\n \"C:\\\\Windows\\\\Tasks\\\\*.exe\",\n \"C:\\\\Intel\\\\*.exe\",\n \"C:\\\\PerfLogs\\\\*.exe\")\n ]\n [file where event.type != \"deletion\" and user.domain != \"NT AUTHORITY\" and\n file.path : (\"C:\\\\Users\\\\*\\\\AppData\\\\Roaming\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Startup\\\\*\",\n \"C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\StartUp\\\\*\")\n ]\n", "required_fields": [ { @@ -57,7 +57,8 @@ "Host", "Windows", "Threat Detection", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_scripts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_scripts.json index 5fce4a0cacfb0..0ba6a1a05c026 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_scripts.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_scripts.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Persistent Scripts in the Startup Directory", - "note": "## Triage and analysis\n\n### Investigating Persistent Scripts in the Startup Directory\n\nThe Windows Startup folder is a special folder in Windows. Programs added to this folder are executed during account\nlogon, without user interaction, providing an excellent way for attackers to maintain persistence.\n\nThis rule looks for shortcuts created by wscript.exe or cscript.exe, or js/vbs scripts created by any process.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate\nsoftware installations.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Related rules\n\n- Suspicious Startup Shell Folder Modification - c8b150f0-0164-475b-a75e-74b47800a9ff\n- Startup Folder Persistence via Unsigned Process - 2fba96c0-ade5-4bce-b92f-a5df2509da3f\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Persistent Scripts in the Startup Directory\n\nThe Windows Startup folder is a special folder in Windows. Programs added to this folder are executed during account\nlogon, without user interaction, providing an excellent way for attackers to maintain persistence.\n\nThis rule looks for shortcuts created by wscript.exe or cscript.exe, or js/vbs scripts created by any process.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Validate the activity is not related to planned patches, updates, network administrator activity, or legitimate\nsoftware installations.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Related rules\n\n- Suspicious Startup Shell Folder Modification - c8b150f0-0164-475b-a75e-74b47800a9ff\n- Startup Folder Persistence via Unsigned Process - 2fba96c0-ade5-4bce-b92f-a5df2509da3f\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "file where event.type != \"deletion\" and user.domain != \"NT AUTHORITY\" and\n\n /* detect shortcuts created by wscript.exe or cscript.exe */\n (file.path : \"C:\\\\*\\\\Programs\\\\Startup\\\\*.lnk\" and\n process.name : (\"wscript.exe\", \"cscript.exe\")) or\n\n /* detect vbs or js files created by any process */\n file.path : (\"C:\\\\*\\\\Programs\\\\Startup\\\\*.vbs\",\n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.vbe\",\n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.wsh\",\n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.wsf\",\n \"C:\\\\*\\\\Programs\\\\Startup\\\\*.js\")\n", "required_fields": [ { @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { @@ -73,5 +74,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_com_hijack_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_com_hijack_registry.json index a742c05003a0f..35a9201a43fa5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_com_hijack_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_com_hijack_registry.json @@ -10,7 +10,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Component Object Model Hijacking", - "note": "## Triage and analysis\n\n### Investigating Component Object Model Hijacking\n\nAdversaries can insert malicious code that can be executed in place of legitimate software through hijacking the COM references and relationships as a means of persistence.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file referenced in the registry and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- Some Microsoft executables will reference the LocalServer32 registry key value for the location of external COM objects.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Component Object Model Hijacking\n\nAdversaries can insert malicious code that can be executed in place of legitimate software through hijacking the COM references and relationships as a means of persistence.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Identify the user account that performed the action and whether it should perform this kind of action.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file referenced in the registry and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- Some Microsoft executables will reference the LocalServer32 registry key value for the location of external COM objects.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "registry where\n (registry.path : \"HK*}\\\\InprocServer32\\\\\" and registry.data.strings: (\"scrobj.dll\", \"C:\\\\*\\\\scrobj.dll\") and\n not registry.path : \"*\\\\{06290BD*-48AA-11D2-8432-006008C3FBFC}\\\\*\")\n or\n /* in general COM Registry changes on Users Hive is less noisy and worth alerting */\n (registry.path : (\"HKEY_USERS\\\\*Classes\\\\*\\\\InprocServer32\\\\\",\n \"HKEY_USERS\\\\*Classes\\\\*\\\\LocalServer32\\\\\",\n \"HKEY_USERS\\\\*Classes\\\\*\\\\DelegateExecute\\\\\",\n \"HKEY_USERS\\\\*Classes\\\\*\\\\TreatAs\\\\\",\n \"HKEY_USERS\\\\*Classes\\\\CLSID\\\\*\\\\ScriptletURL\\\\\") and\n not (process.executable : \"?:\\\\Program Files*\\\\Veeam\\\\Backup and Replication\\\\Console\\\\veeam.backup.shell.exe\" and\n registry.path : \"HKEY_USERS\\\\S-1-5-21-*_Classes\\\\CLSID\\\\*\\\\LocalServer32\\\\\") and\n /* not necessary but good for filtering privileged installations */\n user.domain != \"NT AUTHORITY\"\n ) and\n /* removes false-positives generated by OneDrive and Teams */\n not process.name : (\"OneDrive.exe\",\"OneDriveSetup.exe\",\"FileSyncConfig.exe\",\"Teams.exe\") and\n /* Teams DLL loaded by regsvr */\n not (process.name: \"regsvr32.exe\" and\n registry.data.strings : \"*Microsoft.Teams.*.dll\")\n", "references": [ "https://bohops.com/2018/08/18/abusing-the-com-registry-structure-part-2-loading-techniques-for-evasion-and-persistence/" @@ -51,7 +51,8 @@ "Host", "Windows", "Threat Detection", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { @@ -79,5 +80,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json index 99f03033656ae..4c52791fc0a9c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json index c0544624f0377..ec9c831670716 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json @@ -38,7 +38,8 @@ "Host", "Windows", "Threat Detection", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { @@ -59,5 +60,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json index 0734ca15c8ba8..85997cb5399cd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json @@ -45,7 +45,8 @@ "Host", "Windows", "Threat Detection", - "Persistence" + "Persistence", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json index 32f295c0e81d1..4836132746057 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Persistence via Update Orchestrator Service Hijack", - "note": "", + "note": "## Triage and analysis\n\n### Investigating Persistence via Update Orchestrator Service Hijack\n\nWindows Update Orchestrator Service is a DCOM service used by other components to install Windows updates that are\nalready downloaded. Windows Update Orchestrator Service was vulnerable to elevation of privileges (any user to local\nsystem) due to an improper authorization of the callers. The vulnerability affected the Windows 10 and Windows Server\nCore products. Fixed by Microsoft on Patch Tuesday June 2020.\n\nThis rule will detect uncommon processes spawned by `svchost.exe` with `UsoSvc` as the command line parameters.\nAttackers can leverage this technique to elevate privileges or maintain persistence.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.parent.executable : \"C:\\\\Windows\\\\System32\\\\svchost.exe\" and\n process.parent.args : \"UsoSvc\" and\n not process.executable :\n (\"?:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\UUS\\\\Packages\\\\*\\\\amd64\\\\MoUsoCoreWorker.exe\",\n \"?:\\\\Windows\\\\System32\\\\UsoClient.exe\",\n \"?:\\\\Windows\\\\System32\\\\MusNotification.exe\",\n \"?:\\\\Windows\\\\System32\\\\MusNotificationUx.exe\",\n \"?:\\\\Windows\\\\System32\\\\MusNotifyIcon.exe\",\n \"?:\\\\Windows\\\\System32\\\\WerFault.exe\",\n \"?:\\\\Windows\\\\System32\\\\WerMgr.exe\",\n \"?:\\\\Windows\\\\UUS\\\\amd64\\\\MoUsoCoreWorker.exe\",\n \"?:\\\\Windows\\\\System32\\\\MoUsoCoreWorker.exe\",\n \"?:\\\\Windows\\\\UUS\\\\amd64\\\\UsoCoreWorker.exe\",\n \"?:\\\\Windows\\\\System32\\\\UsoCoreWorker.exe\",\n \"?:\\\\Program Files\\\\Common Files\\\\microsoft shared\\\\ClickToRun\\\\OfficeC2RClient.exe\") and\n not process.name : (\"MoUsoCoreWorker.exe\", \"OfficeC2RClient.exe\")\n", "references": [ "https://github.com/irsl/CVE-2020-1313" @@ -82,5 +82,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_webshell_detection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_webshell_detection.json index 4bb454dae5cf2..69130e81a668a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_webshell_detection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_webshell_detection.json @@ -14,8 +14,8 @@ ], "language": "eql", "license": "Elastic License v2", - "name": "Webshell Detection: Script Process Child of Common Web Processes", - "note": "## Triage and analysis\n\nDetections should be investigated to identify if the activity corresponds to legitimate activity. As this rule detects post-exploitation process activity, investigations into this should be prioritized.", + "name": "Web Shell Detection: Script Process Child of Common Web Processes", + "note": "## Triage and analysis\n\n### Investigating Web Shell Detection: Script Process Child of Common Web Processes\n\nAdversaries may backdoor web servers with web shells to establish persistent access to systems. A web shell is a web\nscript that is placed on an openly accessible web server to allow an adversary to use the web server as a gateway into a\nnetwork. A web shell may provide a set of functions to execute or a command-line interface on the system that hosts the\nweb server.\n\nThis rule detects a web server process spawning script and command-line interface programs, potentially indicating\nattackers executing commands using the web shell.\n\n#### Possible investigation steps\n\n- Investigate abnormal behaviors observed by the subject process such as network connections, registry or file\nmodifications, and any other spawned child processes.\n- Examine the command line to determine which commands or scripts were executed.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- If scripts or executables were dropped, retrieve the files and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Any activity that triggered the alert and is not inherently\nmalicious must be monitored by the security team.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.parent.name : (\"w3wp.exe\", \"httpd.exe\", \"nginx.exe\", \"php.exe\", \"php-cgi.exe\", \"tomcat.exe\") and\n process.name : (\"cmd.exe\", \"cscript.exe\", \"powershell.exe\", \"pwsh.exe\", \"powershell_ise.exe\", \"wmic.exe\", \"wscript.exe\")\n", "references": [ "https://www.microsoft.com/security/blog/2020/02/04/ghost-in-the-shell-investigating-web-shell-attacks/" @@ -89,5 +89,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_disable_uac_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_disable_uac_registry.json index e54cad33c0830..04291353bfe13 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_disable_uac_registry.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_disable_uac_registry.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Disabling User Account Control via Registry Modification", - "note": "", + "note": "## Triage and analysis\n\n### Investigating Disabling User Account Control via Registry Modification\n\nWindows User Account Control (UAC) allows a program to elevate its privileges (tracked as low to high integrity levels)\nto perform a task under administrator-level permissions, possibly by prompting the user for confirmation.\nUAC can deny an operation under high-integrity enforcement, or allow the user to perform the action if they are in the\nlocal administrators group and enter an administrator password when prompted.\n\nFor more information about the UAC and how it works, check the [official Microsoft docs page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works).\n\nAttackers may disable UAC to execute code directly in high integrity. This rule identifies registry value changes to\nbypass the UAC protection.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behaviors in the alert timeframe.\n- Investigate abnormal behaviors observed by the subject process such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Analyze non-system processes executed with high integrity after UAC was disabled for unknown or suspicious processes.\n- Retrieve the suspicious processes' executables and determine if they are malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Restore UAC settings to the desired state.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "registry where event.type == \"change\" and\n registry.path :\n (\n \"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\System\\\\EnableLUA\",\n \"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\System\\\\ConsentPromptBehaviorAdmin\",\n \"HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Policies\\\\System\\\\PromptOnSecureDesktop\"\n ) and\n registry.data.strings : (\"0\", \"0x00000000\")\n", "references": [ "https://www.greyhathacker.net/?p=796", @@ -95,5 +95,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_iniscript.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_iniscript.json index e7901f8073390..b13f11a0a0994 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_iniscript.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_iniscript.json @@ -67,7 +67,8 @@ "Windows", "Threat Detection", "Privilege Escalation", - "Active Directory" + "Active Directory", + "has_guide" ], "threat": [ { @@ -100,5 +101,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_privileged_groups.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_privileged_groups.json index f5b8c4604f6ac..aa888ff8e3f5e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_privileged_groups.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_privileged_groups.json @@ -43,7 +43,8 @@ "Windows", "Threat Detection", "Privilege Escalation", - "Active Directory" + "Active Directory", + "has_guide" ], "threat": [ { @@ -71,5 +72,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_scheduled_task.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_scheduled_task.json index 6569ffb3bf6bc..f43123163d210 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_scheduled_task.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_scheduled_task.json @@ -66,7 +66,8 @@ "Windows", "Threat Detection", "Privilege Escalation", - "Active Directory" + "Active Directory", + "has_guide" ], "threat": [ { @@ -106,5 +107,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_installertakeover.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_installertakeover.json index 87b5e7f040d5e..66325135325b2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_installertakeover.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_installertakeover.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Potential Privilege Escalation via InstallerFileTakeOver", - "note": "## Triage and analysis\n\n### Investigating Potential Privilege Escalation via InstallerFileTakeOver\n\nInstallerFileTakeOver is a weaponized escalation of privilege proof of concept (EoP PoC) to the CVE-2021-41379 vulnerability. Upon successful exploitation, an\nunprivileged user will escalate privileges to SYSTEM/NT AUTHORITY.\n\nThis rule detects the default execution of the PoC, which overwrites the `elevation_service.exe` DACL and copies itself\nto the location to escalate privileges. An attacker is able to still take over any file that is not in use (locked),\nwhich is outside the scope of this rule.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Look for additional processes spawned by the process, command lines, and network communications.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- Verify whether a digital signature exists in the executable, and if it is valid.\n\n### Related rules\n\n- Suspicious DLL Loaded for Persistence or Privilege Escalation - bfeaf89b-a2a7-48a3-817f-e41829dc61ee\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Potential Privilege Escalation via InstallerFileTakeOver\n\nInstallerFileTakeOver is a weaponized escalation of privilege proof of concept (EoP PoC) to the CVE-2021-41379 vulnerability. Upon successful exploitation, an\nunprivileged user will escalate privileges to SYSTEM/NT AUTHORITY.\n\nThis rule detects the default execution of the PoC, which overwrites the `elevation_service.exe` DACL and copies itself\nto the location to escalate privileges. An attacker is able to still take over any file that is not in use (locked),\nwhich is outside the scope of this rule.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Look for additional processes spawned by the process, command lines, and network communications.\n- Assess whether this behavior is prevalent in the environment by looking for similar occurrences across hosts.\n- Retrieve the file and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- Verify whether a digital signature exists in the executable, and if it is valid.\n\n### Related rules\n\n- Suspicious DLL Loaded for Persistence or Privilege Escalation - bfeaf89b-a2a7-48a3-817f-e41829dc61ee\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "/* This rule is compatible with both Sysmon and Elastic Endpoint */\n\nprocess where event.type == \"start\" and\n (?process.Ext.token.integrity_level_name : \"System\" or\n ?winlog.event_data.IntegrityLevel : \"System\") and\n (\n (process.name : \"elevation_service.exe\" and\n not process.pe.original_file_name == \"elevation_service.exe\") or\n\n (process.parent.name : \"elevation_service.exe\" and\n process.name : (\"rundll32.exe\", \"cmd.exe\", \"powershell.exe\"))\n )\n", "references": [ "https://github.com/klinix5/InstallerFileTakeOver" @@ -58,7 +58,8 @@ "Host", "Windows", "Threat Detection", - "Privilege Escalation" + "Privilege Escalation", + "has_guide" ], "threat": [ { @@ -79,5 +80,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_persistence_phantom_dll.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_persistence_phantom_dll.json index 196676058b1fa..b116edce296b6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_persistence_phantom_dll.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_persistence_phantom_dll.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Suspicious DLL Loaded for Persistence or Privilege Escalation", - "note": "", + "note": "## Triage and analysis\n\n### Investigating Suspicious DLL Loaded for Persistence or Privilege Escalation\n\nAttackers can execute malicious code by abusing missing modules that processes try to load, enabling them to escalate\nprivileges or gain persistence. This rule identifies the loading of a non-Microsoft-signed DLL that is missing on a\ndefault Windows installation or one that can be loaded from a different location by a native Windows process.\n\n#### Possible investigation steps\n\n- Examine the DLL signature and identify the process that created it.\n - Investigate any abnormal behaviors by the process such as network connections, registry or file modifications, and\n any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Retrieve the DLL and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Any activity that triggered the alert and is not inherently\nmalicious must be monitored by the security team.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "any where\n (event.category == \"library\" or (event.category == \"process\" and event.action : \"Image loaded*\")) and\n (\n /* compatible with Elastic Endpoint Library Events */\n (dll.name : (\"wlbsctrl.dll\", \"wbemcomn.dll\", \"WptsExtensions.dll\", \"Tsmsisrv.dll\", \"TSVIPSrv.dll\", \"Msfte.dll\",\n \"wow64log.dll\", \"WindowsCoreDeviceInfo.dll\", \"Ualapi.dll\", \"wlanhlp.dll\", \"phoneinfo.dll\", \"EdgeGdi.dll\",\n \"cdpsgshims.dll\", \"windowsperformancerecordercontrol.dll\", \"diagtrack_win.dll\")\n and (dll.code_signature.trusted == false or dll.code_signature.exists == false)) or\n\n /* compatible with Sysmon EventID 7 - Image Load */\n (file.name : (\"wlbsctrl.dll\", \"wbemcomn.dll\", \"WptsExtensions.dll\", \"Tsmsisrv.dll\", \"TSVIPSrv.dll\", \"Msfte.dll\",\n \"wow64log.dll\", \"WindowsCoreDeviceInfo.dll\", \"Ualapi.dll\", \"wlanhlp.dll\", \"phoneinfo.dll\", \"EdgeGdi.dll\",\n \"cdpsgshims.dll\", \"windowsperformancerecordercontrol.dll\", \"diagtrack_win.dll\")\n and not file.code_signature.status == \"Valid\")\n )\n", "references": [ "https://itm4n.github.io/windows-dll-hijacking-clarified/", @@ -119,5 +119,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json index 03828b39ddf49..365caf6dd1426 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json @@ -2,7 +2,7 @@ "author": [ "Elastic" ], - "description": "Detects attempts to exploit privilege escalation vulnerabilities related to the Print Spooler service including CVE-2020-1048 and CVE-2020-1337. .", + "description": "Detects attempts to exploit privilege escalation vulnerabilities related to the Print Spooler service including CVE-2020-1048 and CVE-2020-1337.", "from": "now-9m", "index": [ "winlogbeat-*", @@ -11,8 +11,8 @@ ], "language": "eql", "license": "Elastic License v2", - "name": "Suspicious PrintSpooler SPL File Created", - "note": "## Threat intel\n\nRefer to CVEs, CVE-2020-1048 and CVE-2020-1337 for further information on the vulnerability and exploit. Verify that the relevant system is patched.", + "name": "Suspicious Print Spooler SPL File Created", + "note": "## Triage and analysis\n\n### Investigating Suspicious Print Spooler SPL File Created\n\nPrint Spooler is a Windows service enabled by default in all Windows clients and servers. The service manages print jobs\nby loading printer drivers, receiving files to be printed, queuing them, scheduling, etc.\n\nThe Print Spooler service has some known vulnerabilities that attackers can abuse to escalate privileges to SYSTEM, like\nCVE-2020-1048 and CVE-2020-1337. This rule looks for unusual processes writing SPL files to the location\n`?:\\Windows\\System32\\spool\\PRINTERS\\`, which is an essential step in exploiting these vulnerabilities.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- If this activity is expected and noisy in your environment, consider adding exceptions \u2014 preferably with a combination\nof process executable and file conditions.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Ensure that the machine has the latest security updates and is not running legacy Windows versions.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "file where event.type != \"deletion\" and\n file.extension : \"spl\" and\n file.path : \"?:\\\\Windows\\\\System32\\\\spool\\\\PRINTERS\\\\*\" and\n not process.name : (\"spoolsv.exe\",\n \"printfilterpipelinesvc.exe\",\n \"PrintIsolationHost.exe\",\n \"splwow64.exe\",\n \"msiexec.exe\",\n \"poqexec.exe\")\n", "references": [ "https://safebreach.com/Post/How-we-bypassed-CVE-2020-1048-Patch-and-got-CVE-2020-1337" @@ -69,5 +69,5 @@ ], "timestamp_override": "event.ingested", "type": "eql", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_root_login_without_mfa.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_root_login_without_mfa.json index 8dc5e6ec6f221..01b6ebd880189 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_root_login_without_mfa.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_root_login_without_mfa.json @@ -69,7 +69,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Identity and Access" + "Identity and Access", + "has_guide" ], "threat": [ { @@ -90,5 +91,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json index 217b774ef77c1..6aeccd8896875 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Bypass UAC via Event Viewer", - "note": "## Triage and analysis\n\n### Investigating Bypass UAC via Event Viewer\n\nWindows User Account Control (UAC) allows a program to elevate its privileges (tracked as low to high integrity levels)\nto perform a task under administrator-level permissions, possibly by prompting the user for confirmation.\nUAC can deny an operation under high-integrity enforcement, or allow the user to perform the action if they are in the\nlocal administrators group and enter an administrator password when prompted.\n\nFor more information about the UAC and how it works, check the [official Microsoft docs page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works).\n\nDuring startup, `eventvwr.exe` checks the registry value of the `HKCU\\Software\\Classes\\mscfile\\shell\\open\\command`\nregistry key for the location of `mmc.exe`, which is used to open the `eventvwr.msc` saved console file. If the location\nof another binary or script is added to this registry value, it will be executed as a high-integrity process without a\nUAC prompt being displayed to the user. This rule detects this UAC bypass by monitoring processes spawned by\n`eventvwr.exe` other than `mmc.exe` and `werfault.exe`.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behaviors in the alert timeframe.\n- Investigate abnormal behaviors observed by the subject process such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Bypass UAC via Event Viewer\n\nWindows User Account Control (UAC) allows a program to elevate its privileges (tracked as low to high integrity levels)\nto perform a task under administrator-level permissions, possibly by prompting the user for confirmation.\nUAC can deny an operation under high-integrity enforcement, or allow the user to perform the action if they are in the\nlocal administrators group and enter an administrator password when prompted.\n\nFor more information about the UAC and how it works, check the [official Microsoft docs page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works).\n\nDuring startup, `eventvwr.exe` checks the registry value of the `HKCU\\Software\\Classes\\mscfile\\shell\\open\\command`\nregistry key for the location of `mmc.exe`, which is used to open the `eventvwr.msc` saved console file. If the location\nof another binary or script is added to this registry value, it will be executed as a high-integrity process without a\nUAC prompt being displayed to the user. This rule detects this UAC bypass by monitoring processes spawned by\n`eventvwr.exe` other than `mmc.exe` and `werfault.exe`.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.parent.name : \"eventvwr.exe\" and\n not process.executable :\n (\"?:\\\\Windows\\\\SysWOW64\\\\mmc.exe\",\n \"?:\\\\Windows\\\\System32\\\\mmc.exe\",\n \"?:\\\\Windows\\\\SysWOW64\\\\WerFault.exe\",\n \"?:\\\\Windows\\\\System32\\\\WerFault.exe\")\n", "required_fields": [ { @@ -40,7 +40,8 @@ "Host", "Windows", "Threat Detection", - "Privilege Escalation" + "Privilege Escalation", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json index a4621ff4b883a..a1ae394cbcd9a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "UAC Bypass Attempt via Windows Directory Masquerading", - "note": "## Triage and analysis\n\n### Investigating UAC Bypass Attempt via Windows Directory Masquerading\n\nWindows User Account Control (UAC) allows a program to elevate its privileges (tracked as low to high integrity levels)\nto perform a task under administrator-level permissions, possibly by prompting the user for confirmation.\nUAC can deny an operation under high-integrity enforcement, or allow the user to perform the action if they are in the\nlocal administrators group and enter an administrator password when prompted.\n\nFor more information about the UAC and how it works, check the [official Microsoft docs page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works).\n\nThis rule identifies an attempt to bypass User Account Control (UAC) by masquerading as a Microsoft trusted Windows\ndirectory. Attackers may bypass UAC to stealthily execute code with elevated permissions.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behaviors in the alert timeframe.\n- Investigate abnormal behaviors observed by the subject process such as network connections, registry or file\nmodifications, and any spawned child processes.\n- If any of the spawned processes are suspicious, retrieve them and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating UAC Bypass Attempt via Windows Directory Masquerading\n\nWindows User Account Control (UAC) allows a program to elevate its privileges (tracked as low to high integrity levels)\nto perform a task under administrator-level permissions, possibly by prompting the user for confirmation.\nUAC can deny an operation under high-integrity enforcement, or allow the user to perform the action if they are in the\nlocal administrators group and enter an administrator password when prompted.\n\nFor more information about the UAC and how it works, check the [official Microsoft docs page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works).\n\nThis rule identifies an attempt to bypass User Account Control (UAC) by masquerading as a Microsoft trusted Windows\ndirectory. Attackers may bypass UAC to stealthily execute code with elevated permissions.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- If any of the spawned processes are suspicious, retrieve them and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.args : (\"C:\\\\Windows \\\\system32\\\\*.exe\", \"C:\\\\Windows \\\\SysWOW64\\\\*.exe\")\n", "references": [ "https://medium.com/tenable-techblog/uac-bypass-by-mocking-trusted-directories-24a96675f6e" @@ -38,7 +38,8 @@ "Host", "Windows", "Threat Detection", - "Privilege Escalation" + "Privilege Escalation", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json index 0ed27cf021601..877d0a3ca31a6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "UAC Bypass via Windows Firewall Snap-In Hijack", - "note": "## Triage and analysis\n\n### Investigating UAC Bypass via Windows Firewall Snap-In Hijack\n\nWindows User Account Control (UAC) allows a program to elevate its privileges (tracked as low to high integrity levels)\nto perform a task under administrator-level permissions, possibly by prompting the user for confirmation.\nUAC can deny an operation under high-integrity enforcement, or allow the user to perform the action if they are in the\nlocal administrators group and enter an administrator password when prompted.\n\nFor more information about the UAC and how it works, check the [official Microsoft docs page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works).\n\nThis rule identifies attempts to bypass User Account Control (UAC) by hijacking the Microsoft Management Console (MMC)\nWindows Firewall snap-in. Attackers bypass UAC to stealthily execute code with elevated permissions.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behaviors in the alert timeframe.\n- Investigate abnormal behaviors observed by the subject process such as network connections, registry or file\nmodifications, and any spawned child processes.\n- If any of the spawned processes are suspicious, retrieve them and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating UAC Bypass via Windows Firewall Snap-In Hijack\n\nWindows User Account Control (UAC) allows a program to elevate its privileges (tracked as low to high integrity levels)\nto perform a task under administrator-level permissions, possibly by prompting the user for confirmation.\nUAC can deny an operation under high-integrity enforcement, or allow the user to perform the action if they are in the\nlocal administrators group and enter an administrator password when prompted.\n\nFor more information about the UAC and how it works, check the [official Microsoft docs page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works).\n\nThis rule identifies attempts to bypass User Account Control (UAC) by hijacking the Microsoft Management Console (MMC)\nWindows Firewall snap-in. Attackers bypass UAC to stealthily execute code with elevated permissions.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Inspect the host for suspicious or abnormal behavior in the alert timeframe.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- If any of the spawned processes are suspicious, retrieve them and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell `Get-FileHash` cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are\nidentified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business\nsystems, and web services.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\n process.parent.name == \"mmc.exe\" and\n /* process.Ext.token.integrity_level_name == \"high\" can be added in future for tuning */\n /* args of the Windows Firewall SnapIn */\n process.parent.args == \"WF.msc\" and process.name != \"WerFault.exe\"\n", "references": [ "https://github.com/AzAgarampur/byeintegrity-uac" @@ -48,7 +48,8 @@ "Host", "Windows", "Threat Detection", - "Privilege Escalation" + "Privilege Escalation", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json index addabf9f61bdd..253a10c4d45a0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json @@ -12,7 +12,7 @@ "language": "eql", "license": "Elastic License v2", "name": "Unusual Parent-Child Relationship", - "note": "## Triage and analysis\n\n### Investigating Unusual Parent-Child Relationship\n\nWindows internal/system processes have some characteristics that can be used to spot suspicious activities. One of these\ncharacteristics is parent-child relationships. These relationships can be used to baseline the typical behavior of the\nsystem and then alert on occurrences that don't comply with the baseline.\n\nThis rule uses this information to spot suspicious parent and child processes.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate abnormal behaviors observed by the subject process such as network connections, registry or file\nmodifications, and any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled tasks creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", + "note": "## Triage and analysis\n\n### Investigating Unusual Parent-Child Relationship\n\nWindows internal/system processes have some characteristics that can be used to spot suspicious activities. One of these\ncharacteristics is parent-child relationships. These relationships can be used to baseline the typical behavior of the\nsystem and then alert on occurrences that don't comply with the baseline.\n\nThis rule uses this information to spot suspicious parent and child processes.\n\n#### Possible investigation steps\n\n- Investigate the process execution chain (parent process tree) for unknown processes. Examine their executable files\nfor prevalence, whether they are located in expected locations, and if they are signed with valid digital signatures.\n- Investigate other alerts associated with the user/host during the past 48 hours.\n- Investigate any abnormal behavior by the subject process such as network connections, registry or file modifications,\nand any spawned child processes.\n- Retrieve the process executable and determine if it is malicious:\n - Use a private sandboxed malware analysis system to perform analysis.\n - Observe and collect information about the following activities:\n - Attempts to contact external domains and addresses.\n - File and registry access, modification, and creation activities.\n - Service creation and launch activities.\n - Scheduled task creation.\n - Use the PowerShell Get-FileHash cmdlet to get the files' SHA-256 hash values.\n - Search for the existence and reputation of the hashes in resources like VirusTotal, Hybrid-Analysis, CISCO Talos, Any.run, etc.\n\n### False positive analysis\n\n- This activity is unlikely to happen legitimately. Benign true positives (B-TPs) can be added as exceptions if necessary.\n\n### Response and remediation\n\n- Initiate the incident response process based on the outcome of the triage.\n- Isolate the involved host to prevent further post-compromise behavior.\n- If the triage identified malware, search the environment for additional compromised hosts.\n - Implement temporary network rules, procedures, and segmentation to contain the malware.\n - Stop suspicious processes.\n - Immediately block the identified indicators of compromise (IoCs).\n - Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that\n attackers could use to reinfect the system.\n- Remove and block malicious artifacts identified during triage.\n- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and\nmalware components.\n- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.\n- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the\nmean time to respond (MTTR).", "query": "process where event.type == \"start\" and\nprocess.parent.name != null and\n (\n /* suspicious parent processes */\n (process.name:\"autochk.exe\" and not process.parent.name:\"smss.exe\") or\n (process.name:(\"fontdrvhost.exe\", \"dwm.exe\") and not process.parent.name:(\"wininit.exe\", \"winlogon.exe\")) or\n (process.name:(\"consent.exe\", \"RuntimeBroker.exe\", \"TiWorker.exe\") and not process.parent.name:\"svchost.exe\") or\n (process.name:\"SearchIndexer.exe\" and not process.parent.name:\"services.exe\") or\n (process.name:\"SearchProtocolHost.exe\" and not process.parent.name:(\"SearchIndexer.exe\", \"dllhost.exe\")) or\n (process.name:\"dllhost.exe\" and not process.parent.name:(\"services.exe\", \"svchost.exe\")) or\n (process.name:\"smss.exe\" and not process.parent.name:(\"System\", \"smss.exe\")) or\n (process.name:\"csrss.exe\" and not process.parent.name:(\"smss.exe\", \"svchost.exe\")) or\n (process.name:\"wininit.exe\" and not process.parent.name:\"smss.exe\") or\n (process.name:\"winlogon.exe\" and not process.parent.name:\"smss.exe\") or\n (process.name:(\"lsass.exe\", \"LsaIso.exe\") and not process.parent.name:\"wininit.exe\") or\n (process.name:\"LogonUI.exe\" and not process.parent.name:(\"wininit.exe\", \"winlogon.exe\")) or\n (process.name:\"services.exe\" and not process.parent.name:\"wininit.exe\") or\n (process.name:\"svchost.exe\" and not process.parent.name:(\"MsMpEng.exe\", \"services.exe\")) or\n (process.name:\"spoolsv.exe\" and not process.parent.name:\"services.exe\") or\n (process.name:\"taskhost.exe\" and not process.parent.name:(\"services.exe\", \"svchost.exe\")) or\n (process.name:\"taskhostw.exe\" and not process.parent.name:(\"services.exe\", \"svchost.exe\")) or\n (process.name:\"userinit.exe\" and not process.parent.name:(\"dwm.exe\", \"winlogon.exe\")) or\n (process.name:(\"wmiprvse.exe\", \"wsmprovhost.exe\", \"winrshost.exe\") and not process.parent.name:\"svchost.exe\") or\n /* suspicious child processes */\n (process.parent.name:(\"SearchProtocolHost.exe\", \"taskhost.exe\", \"csrss.exe\") and not process.name:(\"werfault.exe\", \"wermgr.exe\", \"WerFaultSecure.exe\")) or\n (process.parent.name:\"autochk.exe\" and not process.name:(\"chkdsk.exe\", \"doskey.exe\", \"WerFault.exe\")) or\n (process.parent.name:\"smss.exe\" and not process.name:(\"autochk.exe\", \"smss.exe\", \"csrss.exe\", \"wininit.exe\", \"winlogon.exe\", \"setupcl.exe\", \"WerFault.exe\")) or\n (process.parent.name:\"wermgr.exe\" and not process.name:(\"WerFaultSecure.exe\", \"wermgr.exe\", \"WerFault.exe\")) or\n (process.parent.name:\"conhost.exe\" and not process.name:(\"mscorsvw.exe\", \"wermgr.exe\", \"WerFault.exe\", \"WerFaultSecure.exe\"))\n )\n", "references": [ "https://github.com/sbousseaden/Slides/blob/master/Hunting%20MindMaps/PNG/Windows%20Processes%20TH.map.png", @@ -44,7 +44,8 @@ "Host", "Windows", "Threat Detection", - "Privilege Escalation" + "Privilege Escalation", + "has_guide" ], "threat": [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_updateassumerolepolicy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_updateassumerolepolicy.json index 9045cc9217fbb..b632697515ada 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_updateassumerolepolicy.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_updateassumerolepolicy.json @@ -59,7 +59,8 @@ "AWS", "Continuous Monitoring", "SecOps", - "Identity and Access" + "Identity and Access", + "has_guide" ], "threat": [ { @@ -80,5 +81,5 @@ ], "timestamp_override": "event.ingested", "type": "query", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_filebeat8x.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_filebeat8x.json index 8c4ad87e57532..2e1094d9b4fca 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_filebeat8x.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_filebeat8x.json @@ -63,7 +63,8 @@ "Network", "Continuous Monitoring", "SecOps", - "Monitoring" + "Monitoring", + "has_guide" ], "threat_filters": [ { @@ -226,5 +227,5 @@ "timeline_id": "495ad7a7-316e-4544-8a0f-9c098daee76e", "timeline_title": "Generic Threat Match Timeline", "type": "threat_match", - "version": 100 + "version": 101 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_fleet_integrations.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_fleet_integrations.json index b35e5f72b20fb..62a1da18f9e6f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_fleet_integrations.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_fleet_integrations.json @@ -63,7 +63,8 @@ "Network", "Continuous Monitoring", "SecOps", - "Monitoring" + "Monitoring", + "has_guide" ], "threat_filters": [ { @@ -226,5 +227,5 @@ "timeline_id": "495ad7a7-316e-4544-8a0f-9c098daee76e", "timeline_title": "Generic Threat Match Timeline", "type": "threat_match", - "version": 100 + "version": 101 } From 3598af151ed2112214573f07482ac43f4f82c7eb Mon Sep 17 00:00:00 2001 From: Jiawei Wu <74562234+JiaweiWu@users.noreply.github.com> Date: Mon, 26 Sep 2022 19:29:26 -0600 Subject: [PATCH 41/51] Fix allowing more than 5 snooze schedules on a rule (#141835) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../server/rules_client/rules_client.ts | 26 +++++-- .../rules_client/tests/bulk_edit.test.ts | 2 +- .../panel/base_snooze_panel.test.tsx | 64 ++++++++++++++++ .../rule_snooze/panel/base_snooze_panel.tsx | 13 +++- .../components/rule_snooze/scheduler.tsx | 2 +- .../spaces_only/tests/alerting/snooze.ts | 74 +++++++++++++++++++ 6 files changed, 170 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 79837cdfed4cc..ed330dbd22e08 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -1798,11 +1798,10 @@ export class RulesClient { } if (operation.operation === 'set') { const snoozeAttributes = getSnoozeAttributes(attributes, operation.value); - const schedules = snoozeAttributes.snoozeSchedule.filter((snooze) => snooze.id); - if (schedules.length > 5) { - throw Error( - `Error updating rule: rule cannot have more than 5 snooze schedules` - ); + try { + verifySnoozeScheduleLimit(snoozeAttributes); + } catch (error) { + throw Error(`Error updating rule: could not add snooze - ${error.message}`); } attributes = { ...attributes, @@ -2433,6 +2432,12 @@ export class RulesClient { const newAttrs = getSnoozeAttributes(attributes, snoozeSchedule); + try { + verifySnoozeScheduleLimit(newAttrs); + } catch (error) { + throw Boom.badRequest(error.message); + } + const updateAttributes = this.updateMeta({ ...newAttrs, updatedBy: await this.getUserName(), @@ -3299,3 +3304,14 @@ function clearCurrentActiveSnooze(attributes: RawRule) { }); return clearedSnoozesAndSkippedRecurringSnoozes; } + +function verifySnoozeScheduleLimit(attributes: Partial) { + const schedules = attributes.snoozeSchedule?.filter((snooze) => snooze.id); + if (schedules && schedules.length > 5) { + throw Error( + i18n.translate('xpack.alerting.rulesClient.snoozeSchedule.limitReached', { + defaultMessage: 'Rule cannot have more than 5 snooze schedules', + }) + ); + } +} diff --git a/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts index 5ab3de879c3c9..1cafcd652349a 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts @@ -486,7 +486,7 @@ describe('bulkEdit()', () => { }); expect(response.errors.length).toEqual(1); expect(response.errors[0].message).toEqual( - 'Error updating rule: rule cannot have more than 5 snooze schedules' + 'Error updating rule: could not add snooze - Rule cannot have more than 5 snooze schedules' ); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.test.tsx index eb432522c1188..6749a062a1a22 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.test.tsx @@ -105,6 +105,9 @@ describe('BaseSnoozePanel', () => { expect(wrapper.find('[data-test-subj="ruleAddSchedule"]').exists()).toBeFalsy(); expect(wrapper.find('[data-test-subj="ruleRemoveAllSchedules"]').exists()).toBeTruthy(); expect(wrapper.find('[data-test-subj="ruleSchedulesListAddButton"]').exists()).toBeTruthy(); + expect( + wrapper.find('[data-test-subj="ruleSchedulesListAddButton"]').first().prop('isDisabled') + ).toBeFalsy(); expect( wrapper @@ -114,4 +117,65 @@ describe('BaseSnoozePanel', () => { .filter((e) => Boolean(e.key)).length ).toEqual(2); }); + test('should disable add snooze schedule button if rule has more than 5 schedules', () => { + const wrapper = mountWithIntl( + + ); + + expect(wrapper.find('[data-test-subj="ruleSchedulesListAddButton"]').exists()).toBeTruthy(); + expect( + wrapper.find('[data-test-subj="ruleSchedulesListAddButton"]').first().prop('isDisabled') + ).toBeTruthy(); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.tsx index 2ea8752341ce5..437c75aa3ab2a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/panel/base_snooze_panel.tsx @@ -139,10 +139,14 @@ export const BaseSnoozePanel: React.FunctionComponent = ({ onRemoveAllSchedules(scheduledSnoozes!.filter((s) => s.id).map((s) => s.id as string)); }, [onRemoveAllSchedules, scheduledSnoozes]); - const hasSchedules = useMemo( - () => scheduledSnoozes && scheduledSnoozes.filter((s) => Boolean(s.id)).length > 0, - [scheduledSnoozes] - ); + const numberOfSchedules = useMemo(() => { + if (!scheduledSnoozes) { + return 0; + } + return scheduledSnoozes.filter((s) => Boolean(s.id)).length; + }, [scheduledSnoozes]); + + const hasSchedules = useMemo(() => numberOfSchedules > 0, [numberOfSchedules]); const renderSchedule = () => { if (!showAddSchedule) { @@ -236,6 +240,7 @@ export const BaseSnoozePanel: React.FunctionComponent = ({ = 5} data-test-subj="ruleSchedulesListAddButton" iconType="plusInCircleFilled" onClick={onClickAddSchedule} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/scheduler.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/scheduler.tsx index 179a92b6c7e8e..4b559e262424d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/scheduler.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_snooze/scheduler.tsx @@ -368,7 +368,7 @@ const RuleSnoozeSchedulerPanel: React.FunctionComponent = ({ {i18n.translate('xpack.triggersActionsUI.sections.rulesList.deleteSchedule', { - defaultMessage: 'Delete schedules', + defaultMessage: 'Delete schedule', })} diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/snooze.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/snooze.ts index 02340f69718d6..a7301d1467bf7 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/snooze.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/snooze.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; +import uuid from 'uuid'; import { Spaces } from '../../scenarios'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; import { @@ -240,6 +241,79 @@ export default function createSnoozeRuleTests({ getService }: FtrProviderContext expect(actionsAfter).to.be.greaterThan(0, 'no actions triggered after snooze'); expect(actionsDuring).to.be(0); }); + + it('should prevent more than 5 schedules from being added to a rule', async () => { + const { body: createdRule } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + enabled: false, + }) + ) + .expect(200); + objectRemover.add(Spaces.space1.id, createdRule.id, 'rule', 'alerting'); + + // Creating 5 snooze schedules, using Promise.all is very flaky, therefore + // the schedules are being created 1 at a time + await alertUtils + .getSnoozeRequest(createdRule.id) + .send({ + snooze_schedule: { + ...SNOOZE_SCHEDULE, + id: uuid.v4(), + }, + }) + .expect(204); + await alertUtils + .getSnoozeRequest(createdRule.id) + .send({ + snooze_schedule: { + ...SNOOZE_SCHEDULE, + id: uuid.v4(), + }, + }) + .expect(204); + await alertUtils + .getSnoozeRequest(createdRule.id) + .send({ + snooze_schedule: { + ...SNOOZE_SCHEDULE, + id: uuid.v4(), + }, + }) + .expect(204); + + await alertUtils + .getSnoozeRequest(createdRule.id) + .send({ + snooze_schedule: { + ...SNOOZE_SCHEDULE, + id: uuid.v4(), + }, + }) + .expect(204); + + await alertUtils + .getSnoozeRequest(createdRule.id) + .send({ + snooze_schedule: { + ...SNOOZE_SCHEDULE, + id: uuid.v4(), + }, + }) + .expect(204); + + // Adding the 6th snooze schedule, should fail + const response = await alertUtils.getSnoozeRequest(createdRule.id).send({ + snooze_schedule: { + ...SNOOZE_SCHEDULE, + id: uuid.v4(), + }, + }); + expect(response.statusCode).to.eql(400); + expect(response.body.message).to.eql('Rule cannot have more than 5 snooze schedules'); + }); }); async function getRuleEvents(id: string, minActions: number = 1) { From bded4672f9cd976e7b69593697d9219abba33bf9 Mon Sep 17 00:00:00 2001 From: Marshall Main <55718608+marshallmain@users.noreply.github.com> Date: Mon, 26 Sep 2022 18:48:42 -0700 Subject: [PATCH 42/51] [Security Solution][Alerts] Remove new terms rule type tour (#141293) * Remove new terms rule type tour * Remove unused storage constant --- .../security_solution/common/constants.ts | 3 - .../pages/detection_engine/rules/index.tsx | 25 +++---- .../pages/detection_engine/rules/tour.tsx | 69 ------------------- .../detection_engine/rules/translations.ts | 14 ---- 4 files changed, 11 insertions(+), 100 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/tour.tsx diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index c56170fde9863..967e16d323874 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -450,9 +450,6 @@ export const NEW_FEATURES_TOUR_STORAGE_KEYS = { RULE_MANAGEMENT_PAGE: 'securitySolution.rulesManagementPage.newFeaturesTour.v8.4', }; -export const RULES_MANAGEMENT_FEATURE_TOUR_STORAGE_KEY = - 'securitySolution.rulesManagementPage.newFeaturesTour.v8.4'; - export const RULE_DETAILS_EXECUTION_LOG_TABLE_SHOW_METRIC_COLUMNS_STORAGE_KEY = 'securitySolution.ruleDetails.ruleExecutionLog.showMetrics.v8.2'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx index f771eb46814da..997f40e918cb2 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx @@ -42,7 +42,6 @@ import { useInvalidateRules } from '../../../containers/detection_engine/rules/u import { useBoolState } from '../../../../common/hooks/use_bool_state'; import { RULES_TABLE_ACTIONS } from '../../../../common/lib/apm/user_actions'; import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; -import { RulesPageTourComponent } from './tour'; const RulesPageComponent: React.FC = () => { const [isImportModalVisible, showImportModal, hideImportModal] = useBoolState(); @@ -231,19 +230,17 @@ const RulesPageComponent: React.FC = () => { {i18n.IMPORT_RULE} - - - - {i18n.ADD_NEW_RULE} - - - + + + {i18n.ADD_NEW_RULE} + + {(prePackagedRuleStatus === 'ruleNeedUpdate' || diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/tour.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/tour.tsx deleted file mode 100644 index c13f6a7f67d40..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/tour.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiText, EuiTourStep } from '@elastic/eui'; -import React, { useCallback, useEffect, useState } from 'react'; -import { RULES_MANAGEMENT_FEATURE_TOUR_STORAGE_KEY } from '../../../../../common/constants'; -import { useKibana } from '../../../../common/lib/kibana'; -import * as i18n from './translations'; - -export interface Props { - children: React.ReactElement; -} - -export const RulesPageTourComponent: React.FC = ({ children }) => { - const tourConfig = { - currentTourStep: 1, - isTourActive: true, - tourPopoverWidth: 300, - }; - - const { storage } = useKibana().services; - - const [tourState, setTourState] = useState(() => { - const restoredTourState = storage.get(RULES_MANAGEMENT_FEATURE_TOUR_STORAGE_KEY); - - if (restoredTourState != null) { - return restoredTourState; - } - return tourConfig; - }); - - const demoTourSteps = [ - { - step: 1, - title: i18n.NEW_TERMS_TOUR_TITLE, - content: {i18n.NEW_TERMS_TOUR_CONTENT}, - }, - ]; - const finishTour = useCallback(() => { - setTourState({ - ...tourState, - isTourActive: false, - }); - }, [tourState]); - - useEffect(() => { - storage.set(RULES_MANAGEMENT_FEATURE_TOUR_STORAGE_KEY, tourState); - }, [tourState, storage]); - - return ( - - {children} - - ); -}; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts index 1a5d16f719eba..f49e4695731bc 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/translations.ts @@ -1084,20 +1084,6 @@ export const RULES_BULK_EDIT_FAILURE_DESCRIPTION = (rulesCount: number) => } ); -export const NEW_TERMS_TOUR_TITLE = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.tour.newTermsTitle', - { - defaultMessage: 'A new Security Rule type is available!', - } -); - -export const NEW_TERMS_TOUR_CONTENT = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.tour.newTermsContent', - { - defaultMessage: '"New Terms" rules alert on values that have not previously been seen', - } -); - export const RULE_PREVIEW_TITLE = i18n.translate( 'xpack.securitySolution.detectionEngine.createRule.rulePreviewTitle', { From 159eb81b8d034e50d2dd16101256e83b2096563e Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 26 Sep 2022 22:43:36 -0600 Subject: [PATCH 43/51] [api-docs] Daily api_docs build (#141887) --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/core.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.devdocs.json | 96 + api_docs/data.mdx | 4 +- api_docs/data_query.mdx | 4 +- api_docs/data_search.devdocs.json | 6970 +++++++++++------ api_docs/data_search.mdx | 4 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 2 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/fleet.devdocs.json | 29 + api_docs/fleet.mdx | 4 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerts.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_table_list.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- .../kbn_core_injected_metadata_browser.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_saved_objects_api_browser.mdx | 2 +- .../kbn_core_saved_objects_api_server.mdx | 2 +- ...core_saved_objects_api_server_internal.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_get_repo_files.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.devdocs.json | 36 +- api_docs/kbn_journeys.mdx | 4 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ...solution_io_ts_alerting_types.devdocs.json | 8 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_sort_package_json.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_type_summarizer.mdx | 2 +- api_docs/kbn_type_summarizer_core.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/observability.devdocs.json | 68 +- api_docs/observability.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 12 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.devdocs.json | 4 +- api_docs/security_solution.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.devdocs.json | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_field_list.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.devdocs.json | 14 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualizations.devdocs.json | 1195 ++- api_docs/visualizations.mdx | 4 +- 412 files changed, 6087 insertions(+), 3161 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index ede1ddfd1b090..c298d8a395df6 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index 9dd079407ab6c..6da505acae8b7 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 5bf8f6542ccd1..4e5199b31ef9c 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index d858edbdedf9b..df1ba878d7e68 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 0afb756926159..84c92a1ce8643 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index fc7599f168896..e10dd6028fafe 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index c63dca849d910..504dc027276f0 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index 88da1736d5ebd..5dc73b2b9000b 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 72b9e7b6e447e..aaa279d698443 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 3ead0fe10942f..5e129b2343ca0 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 0de2f3b987f74..5c1a4fea8ca5c 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 8c2b0d3bdda55..6314cca4f901b 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 5fa699f9f0bd2..9c7112ee6e3ad 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index f8d553ceb4bfe..a673eebc1e1c6 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 67c3f4c2c8711..849d5fc71f968 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/core.mdx b/api_docs/core.mdx index 36b55369e5c0a..d63230e7ed586 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core title: "core" image: https://source.unsplash.com/400x175/?github description: API docs for the core plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core'] --- import coreObj from './core.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 8faa9b144c520..7c8ab77b2d5ac 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 1f8a54716d56a..507845391c779 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index 10e75395926d1..ef9680b1325db 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.devdocs.json b/api_docs/data.devdocs.json index bed0278714e2a..10ca74caf4ce6 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -9057,6 +9057,102 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "data", + "id": "def-public.ExpressionFunctionKql", + "type": "Type", + "tags": [], + "label": "ExpressionFunctionKql", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExpressionFunctionDefinition", + "text": "ExpressionFunctionDefinition" + }, + "<\"kql\", null, Arguments, ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.KibanaQueryOutput", + "text": "KibanaQueryOutput" + }, + ", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExecutionContext", + "text": "ExecutionContext" + }, + "<", + { + "pluginId": "inspector", + "scope": "common", + "docId": "kibInspectorPluginApi", + "section": "def-common.Adapters", + "text": "Adapters" + }, + ", ", + "SerializableRecord", + ">>" + ], + "path": "src/plugins/data/common/search/expressions/kql.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-public.ExpressionFunctionLucene", + "type": "Type", + "tags": [], + "label": "ExpressionFunctionLucene", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExpressionFunctionDefinition", + "text": "ExpressionFunctionDefinition" + }, + "<\"lucene\", null, Arguments, ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.KibanaQueryOutput", + "text": "KibanaQueryOutput" + }, + ", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExecutionContext", + "text": "ExecutionContext" + }, + "<", + { + "pluginId": "inspector", + "scope": "common", + "docId": "kibInspectorPluginApi", + "section": "def-common.Adapters", + "text": "Adapters" + }, + ", ", + "SerializableRecord", + ">>" + ], + "path": "src/plugins/data/common/search/expressions/lucene.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "data", "id": "def-public.ExpressionValueSearchContext", diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 59dd44dc07763..f849f08374ded 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3132 | 33 | 2429 | 23 | +| 3211 | 33 | 2508 | 23 | ## Client diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index c8c053c7b5ca5..bb88b05d16a92 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3132 | 33 | 2429 | 23 | +| 3211 | 33 | 2508 | 23 | ## Client diff --git a/api_docs/data_search.devdocs.json b/api_docs/data_search.devdocs.json index c3cfd123f1166..415500b499045 100644 --- a/api_docs/data_search.devdocs.json +++ b/api_docs/data_search.devdocs.json @@ -18687,9 +18687,14 @@ "label": "customMetric", "description": [], "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/bucket_avg.ts", "deprecated": false, @@ -18703,9 +18708,14 @@ "label": "customBucket", "description": [], "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/bucket_avg.ts", "deprecated": false, @@ -18716,18 +18726,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsBucketMax", + "id": "def-common.AggParamsBucketAvgSerialized", "type": "Interface", "tags": [], - "label": "AggParamsBucketMax", + "label": "AggParamsBucketAvgSerialized", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsBucketMax", - "text": "AggParamsBucketMax" + "section": "def-common.AggParamsBucketAvgSerialized", + "text": "AggParamsBucketAvgSerialized" }, " extends ", { @@ -18738,13 +18748,13 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/bucket_max.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_avg.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsBucketMax.customMetric", + "id": "def-common.AggParamsBucketAvgSerialized.customMetric", "type": "Object", "tags": [], "label": "customMetric", @@ -18754,13 +18764,13 @@ "SerializableRecord", " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/bucket_max.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_avg.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsBucketMax.customBucket", + "id": "def-common.AggParamsBucketAvgSerialized.customBucket", "type": "Object", "tags": [], "label": "customBucket", @@ -18770,7 +18780,7 @@ "SerializableRecord", " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/bucket_max.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_avg.ts", "deprecated": false, "trackAdoption": false } @@ -18779,18 +18789,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsBucketMin", + "id": "def-common.AggParamsBucketMax", "type": "Interface", "tags": [], - "label": "AggParamsBucketMin", + "label": "AggParamsBucketMax", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsBucketMin", - "text": "AggParamsBucketMin" + "section": "def-common.AggParamsBucketMax", + "text": "AggParamsBucketMax" }, " extends ", { @@ -18801,39 +18811,49 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/bucket_min.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_max.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsBucketMin.customMetric", + "id": "def-common.AggParamsBucketMax.customMetric", "type": "Object", "tags": [], "label": "customMetric", "description": [], "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/bucket_min.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_max.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsBucketMin.customBucket", + "id": "def-common.AggParamsBucketMax.customBucket", "type": "Object", "tags": [], "label": "customBucket", "description": [], "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/bucket_min.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_max.ts", "deprecated": false, "trackAdoption": false } @@ -18842,18 +18862,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsBucketSum", + "id": "def-common.AggParamsBucketMaxSerialized", "type": "Interface", "tags": [], - "label": "AggParamsBucketSum", + "label": "AggParamsBucketMaxSerialized", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsBucketSum", - "text": "AggParamsBucketSum" + "section": "def-common.AggParamsBucketMaxSerialized", + "text": "AggParamsBucketMaxSerialized" }, " extends ", { @@ -18864,13 +18884,13 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/bucket_sum.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_max.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsBucketSum.customMetric", + "id": "def-common.AggParamsBucketMaxSerialized.customMetric", "type": "Object", "tags": [], "label": "customMetric", @@ -18880,13 +18900,13 @@ "SerializableRecord", " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/bucket_sum.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_max.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsBucketSum.customBucket", + "id": "def-common.AggParamsBucketMaxSerialized.customBucket", "type": "Object", "tags": [], "label": "customBucket", @@ -18896,7 +18916,7 @@ "SerializableRecord", " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/bucket_sum.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_max.ts", "deprecated": false, "trackAdoption": false } @@ -18905,18 +18925,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsCardinality", + "id": "def-common.AggParamsBucketMin", "type": "Interface", "tags": [], - "label": "AggParamsCardinality", + "label": "AggParamsBucketMin", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsCardinality", - "text": "AggParamsCardinality" + "section": "def-common.AggParamsBucketMin", + "text": "AggParamsBucketMin" }, " extends ", { @@ -18927,32 +18947,49 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/cardinality.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_min.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsCardinality.field", - "type": "string", + "id": "def-common.AggParamsBucketMin.customMetric", + "type": "Object", "tags": [], - "label": "field", + "label": "customMetric", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/cardinality.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/bucket_min.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsCardinality.emptyAsNull", - "type": "CompoundType", + "id": "def-common.AggParamsBucketMin.customBucket", + "type": "Object", "tags": [], - "label": "emptyAsNull", + "label": "customBucket", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/cardinality.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_min.ts", "deprecated": false, "trackAdoption": false } @@ -18961,18 +18998,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsCount", + "id": "def-common.AggParamsBucketMinSerialized", "type": "Interface", "tags": [], - "label": "AggParamsCount", + "label": "AggParamsBucketMinSerialized", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsCount", - "text": "AggParamsCount" + "section": "def-common.AggParamsBucketMinSerialized", + "text": "AggParamsBucketMinSerialized" }, " extends ", { @@ -18983,21 +19020,39 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/count.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_min.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsCount.emptyAsNull", - "type": "CompoundType", + "id": "def-common.AggParamsBucketMinSerialized.customMetric", + "type": "Object", "tags": [], - "label": "emptyAsNull", + "label": "customMetric", "description": [], "signature": [ - "boolean | undefined" + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/count.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_min.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsBucketMinSerialized.customBucket", + "type": "Object", + "tags": [], + "label": "customBucket", + "description": [], + "signature": [ + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/bucket_min.ts", "deprecated": false, "trackAdoption": false } @@ -19006,18 +19061,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsCumulativeSum", + "id": "def-common.AggParamsBucketSum", "type": "Interface", "tags": [], - "label": "AggParamsCumulativeSum", + "label": "AggParamsBucketSum", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsCumulativeSum", - "text": "AggParamsCumulativeSum" + "section": "def-common.AggParamsBucketSum", + "text": "AggParamsBucketSum" }, " extends ", { @@ -19028,51 +19083,49 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_sum.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsCumulativeSum.buckets_path", - "type": "string", - "tags": [], - "label": "buckets_path", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsCumulativeSum.customMetric", + "id": "def-common.AggParamsBucketSum.customMetric", "type": "Object", "tags": [], "label": "customMetric", "description": [], "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_sum.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsCumulativeSum.metricAgg", - "type": "string", + "id": "def-common.AggParamsBucketSum.customBucket", + "type": "Object", "tags": [], - "label": "metricAgg", + "label": "customBucket", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_sum.ts", "deprecated": false, "trackAdoption": false } @@ -19081,18 +19134,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram", + "id": "def-common.AggParamsBucketSumSerialized", "type": "Interface", "tags": [], - "label": "AggParamsDateHistogram", + "label": "AggParamsBucketSumSerialized", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsDateHistogram", - "text": "AggParamsDateHistogram" + "section": "def-common.AggParamsBucketSumSerialized", + "text": "AggParamsBucketSumSerialized" }, " extends ", { @@ -19103,199 +19156,140 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_sum.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.field", - "type": "CompoundType", + "id": "def-common.AggParamsBucketSumSerialized.customMetric", + "type": "Object", "tags": [], - "label": "field", + "label": "customMetric", "description": [], "signature": [ - "string | ", - "DataViewFieldBase", - " | undefined" + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_sum.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.timeRange", + "id": "def-common.AggParamsBucketSumSerialized.customBucket", "type": "Object", "tags": [], - "label": "timeRange", + "label": "customBucket", "description": [], "signature": [ - "TimeRange", - " | undefined" + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "path": "src/plugins/data/common/search/aggs/metrics/bucket_sum.ts", "deprecated": false, "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.useNormalizedEsInterval", - "type": "CompoundType", - "tags": [], - "label": "useNormalizedEsInterval", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.scaleMetricValues", - "type": "CompoundType", - "tags": [], - "label": "scaleMetricValues", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.interval", - "type": "string", - "tags": [], - "label": "interval", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", - "deprecated": false, - "trackAdoption": false - }, + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsCardinality", + "type": "Interface", + "tags": [], + "label": "AggParamsCardinality", + "description": [], + "signature": [ { - "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.used_interval", - "type": "string", - "tags": [], - "label": "used_interval", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", - "deprecated": false, - "trackAdoption": false + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsCardinality", + "text": "AggParamsCardinality" }, + " extends ", { - "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.time_zone", - "type": "string", - "tags": [], - "label": "time_zone", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", - "deprecated": false, - "trackAdoption": false - }, + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/cardinality.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.used_time_zone", + "id": "def-common.AggParamsCardinality.field", "type": "string", "tags": [], - "label": "used_time_zone", + "label": "field", "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "path": "src/plugins/data/common/search/aggs/metrics/cardinality.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.drop_partials", + "id": "def-common.AggParamsCardinality.emptyAsNull", "type": "CompoundType", "tags": [], - "label": "drop_partials", + "label": "emptyAsNull", "description": [], "signature": [ "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.format", - "type": "string", - "tags": [], - "label": "format", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "path": "src/plugins/data/common/search/aggs/metrics/cardinality.ts", "deprecated": false, "trackAdoption": false - }, + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsCount", + "type": "Interface", + "tags": [], + "label": "AggParamsCount", + "description": [], + "signature": [ { - "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.min_doc_count", - "type": "number", - "tags": [], - "label": "min_doc_count", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", - "deprecated": false, - "trackAdoption": false + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsCount", + "text": "AggParamsCount" }, + " extends ", { - "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.extended_bounds", - "type": "Object", - "tags": [], - "label": "extended_bounds", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.ExtendedBounds", - "text": "ExtendedBounds" - }, - " | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", - "deprecated": false, - "trackAdoption": false - }, + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/count.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsDateHistogram.extendToTimeRange", + "id": "def-common.AggParamsCount.emptyAsNull", "type": "CompoundType", "tags": [], - "label": "extendToTimeRange", + "label": "emptyAsNull", "description": [], "signature": [ "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "path": "src/plugins/data/common/search/aggs/metrics/count.ts", "deprecated": false, "trackAdoption": false } @@ -19304,78 +19298,50 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsDateRange", + "id": "def-common.AggParamsCumulativeSum", "type": "Interface", "tags": [], - "label": "AggParamsDateRange", + "label": "AggParamsCumulativeSum", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsDateRange", - "text": "AggParamsDateRange" + "section": "def-common.AggParamsCumulativeSum", + "text": "AggParamsCumulativeSum" }, " extends ", { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" + "section": "def-common.CommonAggParamsCumulativeSum", + "text": "CommonAggParamsCumulativeSum" } ], - "path": "src/plugins/data/common/search/aggs/buckets/date_range.ts", + "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsDateRange.field", - "type": "string", - "tags": [], - "label": "field", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_range.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsDateRange.ranges", - "type": "Array", + "id": "def-common.AggParamsCumulativeSum.customMetric", + "type": "Object", "tags": [], - "label": "ranges", + "label": "customMetric", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.DateRange", - "text": "DateRange" + "section": "def-common.AggConfig", + "text": "AggConfig" }, - "[] | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_range.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsDateRange.time_zone", - "type": "string", - "tags": [], - "label": "time_zone", - "description": [], - "signature": [ - "string | undefined" + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/date_range.ts", + "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", "deprecated": false, "trackAdoption": false } @@ -19384,73 +19350,45 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsDerivative", + "id": "def-common.AggParamsCumulativeSumSerialized", "type": "Interface", "tags": [], - "label": "AggParamsDerivative", + "label": "AggParamsCumulativeSumSerialized", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsDerivative", - "text": "AggParamsDerivative" + "section": "def-common.AggParamsCumulativeSumSerialized", + "text": "AggParamsCumulativeSumSerialized" }, " extends ", { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" + "section": "def-common.CommonAggParamsCumulativeSum", + "text": "CommonAggParamsCumulativeSum" } ], - "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", + "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsDerivative.buckets_path", - "type": "string", + "id": "def-common.AggParamsCumulativeSumSerialized.customMetric", + "type": "Object", "tags": [], - "label": "buckets_path", + "label": "customMetric", "description": [], "signature": [ - "string | undefined" + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsDerivative.customMetric", - "type": "Object", - "tags": [], - "label": "customMetric", - "description": [], - "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" - ], - "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsDerivative.metricAgg", - "type": "string", - "tags": [], - "label": "metricAgg", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", + "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", "deprecated": false, "trackAdoption": false } @@ -19459,18 +19397,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsDiversifiedSampler", + "id": "def-common.AggParamsDateHistogram", "type": "Interface", "tags": [], - "label": "AggParamsDiversifiedSampler", + "label": "AggParamsDateHistogram", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsDiversifiedSampler", - "text": "AggParamsDiversifiedSampler" + "section": "def-common.AggParamsDateHistogram", + "text": "AggParamsDateHistogram" }, " extends ", { @@ -19481,139 +19419,199 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/buckets/diversified_sampler.ts", + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsDiversifiedSampler.field", - "type": "string", + "id": "def-common.AggParamsDateHistogram.field", + "type": "CompoundType", "tags": [], "label": "field", - "description": [ - "\nIs used to provide values used for de-duplication" + "description": [], + "signature": [ + "string | ", + "DataViewFieldBase", + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/diversified_sampler.ts", + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsDiversifiedSampler.shard_size", - "type": "number", + "id": "def-common.AggParamsDateHistogram.timeRange", + "type": "Object", "tags": [], - "label": "shard_size", - "description": [ - "\nLimits how many top-scoring documents are collected in the sample processed on each shard." + "label": "timeRange", + "description": [], + "signature": [ + "TimeRange", + " | undefined" ], + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsDateHistogram.useNormalizedEsInterval", + "type": "CompoundType", + "tags": [], + "label": "useNormalizedEsInterval", + "description": [], "signature": [ - "number | undefined" + "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/diversified_sampler.ts", + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsDiversifiedSampler.max_docs_per_value", - "type": "number", + "id": "def-common.AggParamsDateHistogram.scaleMetricValues", + "type": "CompoundType", "tags": [], - "label": "max_docs_per_value", - "description": [ - "\nLimits how many documents are permitted per choice of de-duplicating value" + "label": "scaleMetricValues", + "description": [], + "signature": [ + "boolean | undefined" ], + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsDateHistogram.interval", + "type": "string", + "tags": [], + "label": "interval", + "description": [], "signature": [ - "number | undefined" + "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/diversified_sampler.ts", + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsFilter", - "type": "Interface", - "tags": [], - "label": "AggParamsFilter", - "description": [], - "signature": [ + }, { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsFilter", - "text": "AggParamsFilter" + "parentPluginId": "data", + "id": "def-common.AggParamsDateHistogram.used_interval", + "type": "string", + "tags": [], + "label": "used_interval", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "deprecated": false, + "trackAdoption": false }, - " extends ", { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/buckets/filter.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ + "parentPluginId": "data", + "id": "def-common.AggParamsDateHistogram.time_zone", + "type": "string", + "tags": [], + "label": "time_zone", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "data", - "id": "def-common.AggParamsFilter.geo_bounding_box", + "id": "def-common.AggParamsDateHistogram.used_time_zone", + "type": "string", + "tags": [], + "label": "used_time_zone", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsDateHistogram.drop_partials", "type": "CompoundType", "tags": [], - "label": "geo_bounding_box", + "label": "drop_partials", "description": [], "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.GeoBoundingBox", - "text": "GeoBoundingBox" - }, - " | undefined" + "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/filter.ts", + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsFilter.filter", + "id": "def-common.AggParamsDateHistogram.format", + "type": "string", + "tags": [], + "label": "format", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsDateHistogram.min_doc_count", + "type": "number", + "tags": [], + "label": "min_doc_count", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsDateHistogram.extended_bounds", "type": "Object", "tags": [], - "label": "filter", + "label": "extended_bounds", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.QueryFilter", - "text": "QueryFilter" + "section": "def-common.ExtendedBounds", + "text": "ExtendedBounds" }, " | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/filter.ts", + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsFilter.timeWindow", - "type": "string", + "id": "def-common.AggParamsDateHistogram.extendToTimeRange", + "type": "CompoundType", "tags": [], - "label": "timeWindow", + "label": "extendToTimeRange", "description": [], "signature": [ - "string | undefined" + "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/filter.ts", + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", "deprecated": false, "trackAdoption": false } @@ -19622,18 +19620,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsFilteredMetric", + "id": "def-common.AggParamsDateRange", "type": "Interface", "tags": [], - "label": "AggParamsFilteredMetric", + "label": "AggParamsDateRange", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsFilteredMetric", - "text": "AggParamsFilteredMetric" + "section": "def-common.AggParamsDateRange", + "text": "AggParamsDateRange" }, " extends ", { @@ -19644,39 +19642,56 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/filtered_metric.ts", + "path": "src/plugins/data/common/search/aggs/buckets/date_range.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsFilteredMetric.customMetric", - "type": "Object", + "id": "def-common.AggParamsDateRange.field", + "type": "string", "tags": [], - "label": "customMetric", + "label": "field", "description": [], "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" + "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/filtered_metric.ts", + "path": "src/plugins/data/common/search/aggs/buckets/date_range.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsFilteredMetric.customBucket", - "type": "Object", + "id": "def-common.AggParamsDateRange.ranges", + "type": "Array", "tags": [], - "label": "customBucket", + "label": "ranges", "description": [], "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.DateRange", + "text": "DateRange" + }, + "[] | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/filtered_metric.ts", + "path": "src/plugins/data/common/search/aggs/buckets/date_range.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsDateRange.time_zone", + "type": "string", + "tags": [], + "label": "time_zone", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/date_range.ts", "deprecated": false, "trackAdoption": false } @@ -19685,51 +19700,50 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsFilters", + "id": "def-common.AggParamsDerivative", "type": "Interface", "tags": [], - "label": "AggParamsFilters", + "label": "AggParamsDerivative", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsFilters", - "text": "AggParamsFilters" + "section": "def-common.AggParamsDerivative", + "text": "AggParamsDerivative" }, - " extends Omit<", + " extends ", { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - }, - ", \"customLabel\">" + "section": "def-common.CommonAggParamsDerivative", + "text": "CommonAggParamsDerivative" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/filters.ts", + "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsFilters.filters", - "type": "Array", + "id": "def-common.AggParamsDerivative.customMetric", + "type": "Object", "tags": [], - "label": "filters", + "label": "customMetric", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.QueryFilter", - "text": "QueryFilter" + "section": "def-common.AggConfig", + "text": "AggConfig" }, - "[] | undefined" + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/filters.ts", + "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", "deprecated": false, "trackAdoption": false } @@ -19738,40 +19752,45 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsGeoBounds", + "id": "def-common.AggParamsDerivativeSerialized", "type": "Interface", "tags": [], - "label": "AggParamsGeoBounds", + "label": "AggParamsDerivativeSerialized", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsGeoBounds", - "text": "AggParamsGeoBounds" + "section": "def-common.AggParamsDerivativeSerialized", + "text": "AggParamsDerivativeSerialized" }, " extends ", { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" + "section": "def-common.CommonAggParamsDerivative", + "text": "CommonAggParamsDerivative" } ], - "path": "src/plugins/data/common/search/aggs/metrics/geo_bounds.ts", + "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsGeoBounds.field", - "type": "string", + "id": "def-common.AggParamsDerivativeSerialized.customMetric", + "type": "Object", "tags": [], - "label": "field", + "label": "customMetric", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/geo_bounds.ts", + "signature": [ + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", "deprecated": false, "trackAdoption": false } @@ -19780,18 +19799,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsGeoCentroid", + "id": "def-common.AggParamsDiversifiedSampler", "type": "Interface", "tags": [], - "label": "AggParamsGeoCentroid", + "label": "AggParamsDiversifiedSampler", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsGeoCentroid", - "text": "AggParamsGeoCentroid" + "section": "def-common.AggParamsDiversifiedSampler", + "text": "AggParamsDiversifiedSampler" }, " extends ", { @@ -19802,18 +19821,52 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/geo_centroid.ts", + "path": "src/plugins/data/common/search/aggs/buckets/diversified_sampler.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsGeoCentroid.field", + "id": "def-common.AggParamsDiversifiedSampler.field", "type": "string", "tags": [], "label": "field", - "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/geo_centroid.ts", + "description": [ + "\nIs used to provide values used for de-duplication" + ], + "path": "src/plugins/data/common/search/aggs/buckets/diversified_sampler.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsDiversifiedSampler.shard_size", + "type": "number", + "tags": [], + "label": "shard_size", + "description": [ + "\nLimits how many top-scoring documents are collected in the sample processed on each shard." + ], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/diversified_sampler.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsDiversifiedSampler.max_docs_per_value", + "type": "number", + "tags": [], + "label": "max_docs_per_value", + "description": [ + "\nLimits how many documents are permitted per choice of de-duplicating value" + ], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/diversified_sampler.ts", "deprecated": false, "trackAdoption": false } @@ -19822,18 +19875,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsGeoHash", + "id": "def-common.AggParamsFilter", "type": "Interface", "tags": [], - "label": "AggParamsGeoHash", + "label": "AggParamsFilter", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsGeoHash", - "text": "AggParamsGeoHash" + "section": "def-common.AggParamsFilter", + "text": "AggParamsFilter" }, " extends ", { @@ -19844,95 +19897,63 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", + "path": "src/plugins/data/common/search/aggs/buckets/filter.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsGeoHash.field", - "type": "string", - "tags": [], - "label": "field", - "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsGeoHash.autoPrecision", - "type": "CompoundType", - "tags": [], - "label": "autoPrecision", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsGeoHash.precision", - "type": "number", - "tags": [], - "label": "precision", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsGeoHash.useGeocentroid", + "id": "def-common.AggParamsFilter.geo_bounding_box", "type": "CompoundType", "tags": [], - "label": "useGeocentroid", + "label": "geo_bounding_box", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.GeoBoundingBox", + "text": "GeoBoundingBox" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", + "path": "src/plugins/data/common/search/aggs/buckets/filter.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsGeoHash.isFilteredByCollar", - "type": "CompoundType", + "id": "def-common.AggParamsFilter.filter", + "type": "Object", "tags": [], - "label": "isFilteredByCollar", + "label": "filter", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.QueryFilter", + "text": "QueryFilter" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", + "path": "src/plugins/data/common/search/aggs/buckets/filter.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsGeoHash.boundingBox", - "type": "CompoundType", + "id": "def-common.AggParamsFilter.timeWindow", + "type": "string", "tags": [], - "label": "boundingBox", + "label": "timeWindow", "description": [], "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.GeoBoundingBox", - "text": "GeoBoundingBox" - }, - " | undefined" + "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", + "path": "src/plugins/data/common/search/aggs/buckets/filter.ts", "deprecated": false, "trackAdoption": false } @@ -19941,18 +19962,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsGeoTile", + "id": "def-common.AggParamsFilteredMetric", "type": "Interface", "tags": [], - "label": "AggParamsGeoTile", + "label": "AggParamsFilteredMetric", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsGeoTile", - "text": "AggParamsGeoTile" + "section": "def-common.AggParamsFilteredMetric", + "text": "AggParamsFilteredMetric" }, " extends ", { @@ -19963,46 +19984,49 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/buckets/geo_tile.ts", + "path": "src/plugins/data/common/search/aggs/metrics/filtered_metric.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsGeoTile.field", - "type": "string", + "id": "def-common.AggParamsFilteredMetric.customMetric", + "type": "Object", "tags": [], - "label": "field", - "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/geo_tile.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsGeoTile.useGeocentroid", - "type": "CompoundType", - "tags": [], - "label": "useGeocentroid", + "label": "customMetric", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/geo_tile.ts", + "path": "src/plugins/data/common/search/aggs/metrics/filtered_metric.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsGeoTile.precision", - "type": "number", + "id": "def-common.AggParamsFilteredMetric.customBucket", + "type": "Object", "tags": [], - "label": "precision", + "label": "customBucket", "description": [], "signature": [ - "number | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/geo_tile.ts", + "path": "src/plugins/data/common/search/aggs/metrics/filtered_metric.ts", "deprecated": false, "trackAdoption": false } @@ -20011,18 +20035,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsHistogram", + "id": "def-common.AggParamsFilteredMetricSerialized", "type": "Interface", "tags": [], - "label": "AggParamsHistogram", + "label": "AggParamsFilteredMetricSerialized", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsHistogram", - "text": "AggParamsHistogram" + "section": "def-common.AggParamsFilteredMetricSerialized", + "text": "AggParamsFilteredMetricSerialized" }, " extends ", { @@ -20033,137 +20057,39 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", + "path": "src/plugins/data/common/search/aggs/metrics/filtered_metric.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsHistogram.field", - "type": "string", - "tags": [], - "label": "field", - "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsHistogram.interval", - "type": "CompoundType", - "tags": [], - "label": "interval", - "description": [], - "signature": [ - "string | number" - ], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsHistogram.used_interval", - "type": "CompoundType", - "tags": [], - "label": "used_interval", - "description": [], - "signature": [ - "string | number | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsHistogram.maxBars", - "type": "number", - "tags": [], - "label": "maxBars", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsHistogram.intervalBase", - "type": "number", - "tags": [], - "label": "intervalBase", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsHistogram.min_doc_count", - "type": "CompoundType", - "tags": [], - "label": "min_doc_count", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsHistogram.has_extended_bounds", - "type": "CompoundType", - "tags": [], - "label": "has_extended_bounds", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsHistogram.extended_bounds", + "id": "def-common.AggParamsFilteredMetricSerialized.customMetric", "type": "Object", "tags": [], - "label": "extended_bounds", + "label": "customMetric", "description": [], "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.ExtendedBounds", - "text": "ExtendedBounds" - }, - " | undefined" + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", + "path": "src/plugins/data/common/search/aggs/metrics/filtered_metric.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsHistogram.autoExtendBounds", - "type": "CompoundType", + "id": "def-common.AggParamsFilteredMetricSerialized.customBucket", + "type": "Object", "tags": [], - "label": "autoExtendBounds", + "label": "customBucket", "description": [], "signature": [ - "boolean | undefined" + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", + "path": "src/plugins/data/common/search/aggs/metrics/filtered_metric.ts", "deprecated": false, "trackAdoption": false } @@ -20172,91 +20098,51 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsIpRange", + "id": "def-common.AggParamsFilters", "type": "Interface", "tags": [], - "label": "AggParamsIpRange", + "label": "AggParamsFilters", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsIpRange", - "text": "AggParamsIpRange" + "section": "def-common.AggParamsFilters", + "text": "AggParamsFilters" }, - " extends ", + " extends Omit<", { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", "section": "def-common.BaseAggParams", "text": "BaseAggParams" - } + }, + ", \"customLabel\">" ], - "path": "src/plugins/data/common/search/aggs/buckets/ip_range.ts", + "path": "src/plugins/data/common/search/aggs/buckets/filters.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsIpRange.field", - "type": "string", - "tags": [], - "label": "field", - "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/ip_range.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsIpRange.ipRangeType", - "type": "CompoundType", - "tags": [], - "label": "ipRangeType", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.IP_RANGE_TYPES", - "text": "IP_RANGE_TYPES" - }, - " | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/ip_range.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsIpRange.ranges", - "type": "Object", + "id": "def-common.AggParamsFilters.filters", + "type": "Array", "tags": [], - "label": "ranges", + "label": "filters", "description": [], "signature": [ - "Partial<{ fromTo: ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.RangeIpRangeAggKey", - "text": "RangeIpRangeAggKey" - }, - "[]; mask: ", { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.CidrMaskIpRangeAggKey", - "text": "CidrMaskIpRangeAggKey" + "section": "def-common.QueryFilter", + "text": "QueryFilter" }, - "[]; }> | undefined" + "[] | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/ip_range.ts", + "path": "src/plugins/data/common/search/aggs/buckets/filters.ts", "deprecated": false, "trackAdoption": false } @@ -20265,18 +20151,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsMax", + "id": "def-common.AggParamsGeoBounds", "type": "Interface", "tags": [], - "label": "AggParamsMax", + "label": "AggParamsGeoBounds", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsMax", - "text": "AggParamsMax" + "section": "def-common.AggParamsGeoBounds", + "text": "AggParamsGeoBounds" }, " extends ", { @@ -20287,18 +20173,18 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/max.ts", + "path": "src/plugins/data/common/search/aggs/metrics/geo_bounds.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsMax.field", + "id": "def-common.AggParamsGeoBounds.field", "type": "string", "tags": [], "label": "field", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/max.ts", + "path": "src/plugins/data/common/search/aggs/metrics/geo_bounds.ts", "deprecated": false, "trackAdoption": false } @@ -20307,18 +20193,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsMedian", + "id": "def-common.AggParamsGeoCentroid", "type": "Interface", "tags": [], - "label": "AggParamsMedian", + "label": "AggParamsGeoCentroid", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsMedian", - "text": "AggParamsMedian" + "section": "def-common.AggParamsGeoCentroid", + "text": "AggParamsGeoCentroid" }, " extends ", { @@ -20329,18 +20215,18 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/median.ts", + "path": "src/plugins/data/common/search/aggs/metrics/geo_centroid.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsMedian.field", + "id": "def-common.AggParamsGeoCentroid.field", "type": "string", "tags": [], "label": "field", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/median.ts", + "path": "src/plugins/data/common/search/aggs/metrics/geo_centroid.ts", "deprecated": false, "trackAdoption": false } @@ -20349,18 +20235,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsMin", + "id": "def-common.AggParamsGeoHash", "type": "Interface", "tags": [], - "label": "AggParamsMin", + "label": "AggParamsGeoHash", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsMin", - "text": "AggParamsMin" + "section": "def-common.AggParamsGeoHash", + "text": "AggParamsGeoHash" }, " extends ", { @@ -20371,121 +20257,95 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/min.ts", + "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsMin.field", + "id": "def-common.AggParamsGeoHash.field", "type": "string", "tags": [], "label": "field", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/min.ts", + "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsMovingAvg", - "type": "Interface", - "tags": [], - "label": "AggParamsMovingAvg", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsMovingAvg", - "text": "AggParamsMovingAvg" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsMovingAvg.buckets_path", - "type": "string", + "id": "def-common.AggParamsGeoHash.autoPrecision", + "type": "CompoundType", "tags": [], - "label": "buckets_path", + "label": "autoPrecision", "description": [], "signature": [ - "string | undefined" + "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", + "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsMovingAvg.window", + "id": "def-common.AggParamsGeoHash.precision", "type": "number", "tags": [], - "label": "window", + "label": "precision", "description": [], "signature": [ "number | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", + "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsMovingAvg.script", - "type": "string", + "id": "def-common.AggParamsGeoHash.useGeocentroid", + "type": "CompoundType", "tags": [], - "label": "script", + "label": "useGeocentroid", "description": [], "signature": [ - "string | undefined" + "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", + "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsMovingAvg.customMetric", - "type": "Object", + "id": "def-common.AggParamsGeoHash.isFilteredByCollar", + "type": "CompoundType", "tags": [], - "label": "customMetric", + "label": "isFilteredByCollar", "description": [], "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" + "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", + "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsMovingAvg.metricAgg", - "type": "string", + "id": "def-common.AggParamsGeoHash.boundingBox", + "type": "CompoundType", "tags": [], - "label": "metricAgg", + "label": "boundingBox", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.GeoBoundingBox", + "text": "GeoBoundingBox" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", + "path": "src/plugins/data/common/search/aggs/buckets/geo_hash.ts", "deprecated": false, "trackAdoption": false } @@ -20494,18 +20354,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsMultiTerms", + "id": "def-common.AggParamsGeoTile", "type": "Interface", "tags": [], - "label": "AggParamsMultiTerms", + "label": "AggParamsGeoTile", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsMultiTerms", - "text": "AggParamsMultiTerms" + "section": "def-common.AggParamsGeoTile", + "text": "AggParamsGeoTile" }, " extends ", { @@ -20516,132 +20376,207 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", + "path": "src/plugins/data/common/search/aggs/buckets/geo_tile.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsMultiTerms.fields", - "type": "Array", + "id": "def-common.AggParamsGeoTile.field", + "type": "string", "tags": [], - "label": "fields", + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/geo_tile.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsGeoTile.useGeocentroid", + "type": "CompoundType", + "tags": [], + "label": "useGeocentroid", "description": [], "signature": [ - "string[]" + "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", + "path": "src/plugins/data/common/search/aggs/buckets/geo_tile.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsGeoTile.precision", + "type": "number", + "tags": [], + "label": "precision", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/geo_tile.ts", "deprecated": false, "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsHistogram", + "type": "Interface", + "tags": [], + "label": "AggParamsHistogram", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsHistogram", + "text": "AggParamsHistogram" }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsMultiTerms.orderBy", + "id": "def-common.AggParamsHistogram.field", "type": "string", "tags": [], - "label": "orderBy", + "label": "field", "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsMultiTerms.orderAgg", - "type": "Object", + "id": "def-common.AggParamsHistogram.interval", + "type": "CompoundType", "tags": [], - "label": "orderAgg", + "label": "interval", "description": [], "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" + "string | number" ], - "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsMultiTerms.order", + "id": "def-common.AggParamsHistogram.used_interval", "type": "CompoundType", "tags": [], - "label": "order", + "label": "used_interval", "description": [], "signature": [ - "\"asc\" | \"desc\" | undefined" + "string | number | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsMultiTerms.size", + "id": "def-common.AggParamsHistogram.maxBars", "type": "number", "tags": [], - "label": "size", + "label": "maxBars", "description": [], "signature": [ "number | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsMultiTerms.shardSize", + "id": "def-common.AggParamsHistogram.intervalBase", "type": "number", "tags": [], - "label": "shardSize", + "label": "intervalBase", "description": [], "signature": [ "number | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsMultiTerms.otherBucket", + "id": "def-common.AggParamsHistogram.min_doc_count", "type": "CompoundType", "tags": [], - "label": "otherBucket", + "label": "min_doc_count", "description": [], "signature": [ "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsMultiTerms.otherBucketLabel", - "type": "string", + "id": "def-common.AggParamsHistogram.has_extended_bounds", + "type": "CompoundType", "tags": [], - "label": "otherBucketLabel", + "label": "has_extended_bounds", "description": [], "signature": [ - "string | undefined" + "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsMultiTerms.separatorLabel", - "type": "string", + "id": "def-common.AggParamsHistogram.extended_bounds", + "type": "Object", "tags": [], - "label": "separatorLabel", + "label": "extended_bounds", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.ExtendedBounds", + "text": "ExtendedBounds" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsHistogram.autoExtendBounds", + "type": "CompoundType", + "tags": [], + "label": "autoExtendBounds", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", "deprecated": false, "trackAdoption": false } @@ -20650,18 +20585,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsPercentileRanks", + "id": "def-common.AggParamsIpRange", "type": "Interface", "tags": [], - "label": "AggParamsPercentileRanks", + "label": "AggParamsIpRange", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsPercentileRanks", - "text": "AggParamsPercentileRanks" + "section": "def-common.AggParamsIpRange", + "text": "AggParamsIpRange" }, " extends ", { @@ -20672,32 +20607,69 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/percentile_ranks.ts", + "path": "src/plugins/data/common/search/aggs/buckets/ip_range.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsPercentileRanks.field", + "id": "def-common.AggParamsIpRange.field", "type": "string", "tags": [], "label": "field", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/percentile_ranks.ts", + "path": "src/plugins/data/common/search/aggs/buckets/ip_range.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsPercentileRanks.values", - "type": "Array", + "id": "def-common.AggParamsIpRange.ipRangeType", + "type": "CompoundType", "tags": [], - "label": "values", + "label": "ipRangeType", "description": [], "signature": [ - "number[] | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.IP_RANGE_TYPES", + "text": "IP_RANGE_TYPES" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/percentile_ranks.ts", + "path": "src/plugins/data/common/search/aggs/buckets/ip_range.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsIpRange.ranges", + "type": "Object", + "tags": [], + "label": "ranges", + "description": [], + "signature": [ + "Partial<{ fromTo: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.RangeIpRangeAggKey", + "text": "RangeIpRangeAggKey" + }, + "[]; mask: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CidrMaskIpRangeAggKey", + "text": "CidrMaskIpRangeAggKey" + }, + "[]; }> | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/ip_range.ts", "deprecated": false, "trackAdoption": false } @@ -20706,932 +20678,852 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsPercentiles", + "id": "def-common.AggParamsMapping", "type": "Interface", "tags": [], - "label": "AggParamsPercentiles", + "label": "AggParamsMapping", "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsPercentiles", - "text": "AggParamsPercentiles" - }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/metrics/percentiles.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsPercentiles.field", - "type": "string", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.RANGE", + "type": "Object", "tags": [], - "label": "field", + "label": "[BUCKET_TYPES.RANGE]", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/percentiles.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsRange", + "text": "AggParamsRange" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsPercentiles.percents", - "type": "Array", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.IP_RANGE", + "type": "Object", "tags": [], - "label": "percents", + "label": "[BUCKET_TYPES.IP_RANGE]", "description": [], "signature": [ - "number[] | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsIpRange", + "text": "AggParamsIpRange" + } ], - "path": "src/plugins/data/common/search/aggs/metrics/percentiles.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsRange", - "type": "Interface", - "tags": [], - "label": "AggParamsRange", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsRange", - "text": "AggParamsRange" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/buckets/range.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsRange.field", - "type": "string", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.DATE_RANGE", + "type": "Object", "tags": [], - "label": "field", + "label": "[BUCKET_TYPES.DATE_RANGE]", "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/range.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsDateRange", + "text": "AggParamsDateRange" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsRange.ranges", - "type": "Array", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.FILTER", + "type": "Object", "tags": [], - "label": "ranges", + "label": "[BUCKET_TYPES.FILTER]", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.NumericalRange", - "text": "NumericalRange" - }, - "[] | undefined" + "section": "def-common.AggParamsFilter", + "text": "AggParamsFilter" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/range.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsRareTerms", - "type": "Interface", - "tags": [], - "label": "AggParamsRareTerms", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsRareTerms", - "text": "AggParamsRareTerms" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/buckets/rare_terms.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsRareTerms.field", - "type": "string", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.FILTERS", + "type": "Object", "tags": [], - "label": "field", + "label": "[BUCKET_TYPES.FILTERS]", "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/rare_terms.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsFilters", + "text": "AggParamsFilters" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsRareTerms.max_doc_count", - "type": "number", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.SIGNIFICANT_TERMS", + "type": "Object", "tags": [], - "label": "max_doc_count", + "label": "[BUCKET_TYPES.SIGNIFICANT_TERMS]", "description": [], "signature": [ - "number | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSignificantTerms", + "text": "AggParamsSignificantTerms" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/rare_terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsSampler", - "type": "Interface", - "tags": [], - "label": "AggParamsSampler", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsSampler", - "text": "AggParamsSampler" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/buckets/sampler.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsSampler.shard_size", - "type": "number", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.SIGNIFICANT_TEXT", + "type": "Object", "tags": [], - "label": "shard_size", - "description": [ - "\nLimits how many top-scoring documents are collected in the sample processed on each shard." - ], + "label": "[BUCKET_TYPES.SIGNIFICANT_TEXT]", + "description": [], "signature": [ - "number | undefined" - ], - "path": "src/plugins/data/common/search/aggs/buckets/sampler.ts", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSignificantText", + "text": "AggParamsSignificantText" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsSerialDiff", - "type": "Interface", - "tags": [], - "label": "AggParamsSerialDiff", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsSerialDiff", - "text": "AggParamsSerialDiff" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsSerialDiff.buckets_path", - "type": "string", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.GEOTILE_GRID", + "type": "Object", "tags": [], - "label": "buckets_path", + "label": "[BUCKET_TYPES.GEOTILE_GRID]", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsGeoTile", + "text": "AggParamsGeoTile" + } ], - "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSerialDiff.customMetric", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.GEOHASH_GRID", "type": "Object", "tags": [], - "label": "customMetric", + "label": "[BUCKET_TYPES.GEOHASH_GRID]", "description": [], "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsGeoHash", + "text": "AggParamsGeoHash" + } ], - "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSerialDiff.metricAgg", - "type": "string", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.HISTOGRAM", + "type": "Object", "tags": [], - "label": "metricAgg", + "label": "[BUCKET_TYPES.HISTOGRAM]", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsHistogram", + "text": "AggParamsHistogram" + } ], - "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsSignificantTerms", - "type": "Interface", - "tags": [], - "label": "AggParamsSignificantTerms", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsSignificantTerms", - "text": "AggParamsSignificantTerms" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/buckets/significant_terms.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsSignificantTerms.field", - "type": "string", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.DATE_HISTOGRAM", + "type": "Object", "tags": [], - "label": "field", + "label": "[BUCKET_TYPES.DATE_HISTOGRAM]", "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/significant_terms.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsDateHistogram", + "text": "AggParamsDateHistogram" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSignificantTerms.size", - "type": "number", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.TERMS", + "type": "Object", "tags": [], - "label": "size", + "label": "[BUCKET_TYPES.TERMS]", "description": [], "signature": [ - "number | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsTerms", + "text": "AggParamsTerms" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/significant_terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSignificantTerms.exclude", - "type": "string", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.MULTI_TERMS", + "type": "Object", "tags": [], - "label": "exclude", + "label": "[BUCKET_TYPES.MULTI_TERMS]", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsMultiTerms", + "text": "AggParamsMultiTerms" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/significant_terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSignificantTerms.include", - "type": "string", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.RARE_TERMS", + "type": "Object", "tags": [], - "label": "include", + "label": "[BUCKET_TYPES.RARE_TERMS]", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsRareTerms", + "text": "AggParamsRareTerms" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/significant_terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsSignificantText", - "type": "Interface", - "tags": [], - "label": "AggParamsSignificantText", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsSignificantText", - "text": "AggParamsSignificantText" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsSignificantText.field", - "type": "string", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.SAMPLER", + "type": "Object", "tags": [], - "label": "field", + "label": "[BUCKET_TYPES.SAMPLER]", "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSampler", + "text": "AggParamsSampler" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSignificantText.size", - "type": "number", + "id": "def-common.AggParamsMapping.BUCKET_TYPES.DIVERSIFIED_SAMPLER", + "type": "Object", "tags": [], - "label": "size", + "label": "[BUCKET_TYPES.DIVERSIFIED_SAMPLER]", "description": [], "signature": [ - "number | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsDiversifiedSampler", + "text": "AggParamsDiversifiedSampler" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSignificantText.min_doc_count", - "type": "number", + "id": "def-common.AggParamsMapping.METRIC_TYPES.AVG", + "type": "Object", "tags": [], - "label": "min_doc_count", + "label": "[METRIC_TYPES.AVG]", "description": [], "signature": [ - "number | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsAvg", + "text": "AggParamsAvg" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSignificantText.filter_duplicate_text", - "type": "CompoundType", + "id": "def-common.AggParamsMapping.METRIC_TYPES.CARDINALITY", + "type": "Object", "tags": [], - "label": "filter_duplicate_text", + "label": "[METRIC_TYPES.CARDINALITY]", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsCardinality", + "text": "AggParamsCardinality" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSignificantText.exclude", - "type": "string", + "id": "def-common.AggParamsMapping.METRIC_TYPES.COUNT", + "type": "Object", "tags": [], - "label": "exclude", + "label": "[METRIC_TYPES.COUNT]", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsCount", + "text": "AggParamsCount" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSignificantText.include", - "type": "string", + "id": "def-common.AggParamsMapping.METRIC_TYPES.VALUE_COUNT", + "type": "Object", "tags": [], - "label": "include", + "label": "[METRIC_TYPES.VALUE_COUNT]", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsValueCount", + "text": "AggParamsValueCount" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsSinglePercentile", - "type": "Interface", - "tags": [], - "label": "AggParamsSinglePercentile", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsSinglePercentile", - "text": "AggParamsSinglePercentile" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/metrics/single_percentile.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsSinglePercentile.field", - "type": "string", + "id": "def-common.AggParamsMapping.METRIC_TYPES.GEO_BOUNDS", + "type": "Object", "tags": [], - "label": "field", + "label": "[METRIC_TYPES.GEO_BOUNDS]", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/single_percentile.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsGeoBounds", + "text": "AggParamsGeoBounds" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSinglePercentile.percentile", - "type": "number", + "id": "def-common.AggParamsMapping.METRIC_TYPES.GEO_CENTROID", + "type": "Object", "tags": [], - "label": "percentile", + "label": "[METRIC_TYPES.GEO_CENTROID]", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/single_percentile.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsGeoCentroid", + "text": "AggParamsGeoCentroid" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsSinglePercentileRank", - "type": "Interface", - "tags": [], - "label": "AggParamsSinglePercentileRank", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsSinglePercentileRank", - "text": "AggParamsSinglePercentileRank" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/metrics/single_percentile_rank.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsSinglePercentileRank.field", - "type": "string", + "id": "def-common.AggParamsMapping.METRIC_TYPES.MAX", + "type": "Object", "tags": [], - "label": "field", + "label": "[METRIC_TYPES.MAX]", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/single_percentile_rank.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsMax", + "text": "AggParamsMax" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSinglePercentileRank.value", - "type": "number", + "id": "def-common.AggParamsMapping.METRIC_TYPES.MEDIAN", + "type": "Object", "tags": [], - "label": "value", + "label": "[METRIC_TYPES.MEDIAN]", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/single_percentile_rank.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsMedian", + "text": "AggParamsMedian" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsStdDeviation", - "type": "Interface", - "tags": [], - "label": "AggParamsStdDeviation", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsStdDeviation", - "text": "AggParamsStdDeviation" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/metrics/std_deviation.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsStdDeviation.field", - "type": "string", + "id": "def-common.AggParamsMapping.METRIC_TYPES.SINGLE_PERCENTILE", + "type": "Object", "tags": [], - "label": "field", + "label": "[METRIC_TYPES.SINGLE_PERCENTILE]", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/std_deviation.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSinglePercentile", + "text": "AggParamsSinglePercentile" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsStdDeviation.showBounds", - "type": "CompoundType", + "id": "def-common.AggParamsMapping.METRIC_TYPES.SINGLE_PERCENTILE_RANK", + "type": "Object", "tags": [], - "label": "showBounds", + "label": "[METRIC_TYPES.SINGLE_PERCENTILE_RANK]", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSinglePercentileRank", + "text": "AggParamsSinglePercentileRank" + } ], - "path": "src/plugins/data/common/search/aggs/metrics/std_deviation.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsSum", - "type": "Interface", - "tags": [], - "label": "AggParamsSum", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsSum", - "text": "AggParamsSum" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/metrics/sum.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsSum.field", - "type": "string", + "id": "def-common.AggParamsMapping.METRIC_TYPES.MIN", + "type": "Object", "tags": [], - "label": "field", + "label": "[METRIC_TYPES.MIN]", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/sum.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsMin", + "text": "AggParamsMin" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsSum.emptyAsNull", - "type": "CompoundType", + "id": "def-common.AggParamsMapping.METRIC_TYPES.STD_DEV", + "type": "Object", "tags": [], - "label": "emptyAsNull", + "label": "[METRIC_TYPES.STD_DEV]", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsStdDeviation", + "text": "AggParamsStdDeviation" + } ], - "path": "src/plugins/data/common/search/aggs/metrics/sum.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsTerms", - "type": "Interface", - "tags": [], - "label": "AggParamsTerms", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsTerms", - "text": "AggParamsTerms" }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" - } - ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.field", - "type": "string", + "id": "def-common.AggParamsMapping.METRIC_TYPES.SUM", + "type": "Object", "tags": [], - "label": "field", + "label": "[METRIC_TYPES.SUM]", "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSum", + "text": "AggParamsSum" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.orderBy", - "type": "string", + "id": "def-common.AggParamsMapping.METRIC_TYPES.AVG_BUCKET", + "type": "Object", "tags": [], - "label": "orderBy", + "label": "[METRIC_TYPES.AVG_BUCKET]", "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsBucketAvg", + "text": "AggParamsBucketAvg" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.orderAgg", + "id": "def-common.AggParamsMapping.METRIC_TYPES.MAX_BUCKET", "type": "Object", "tags": [], - "label": "orderAgg", + "label": "[METRIC_TYPES.MAX_BUCKET]", "description": [], "signature": [ - "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableRecord", - " | undefined; schema?: string | undefined; } | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsBucketMax", + "text": "AggParamsBucketMax" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.order", - "type": "CompoundType", + "id": "def-common.AggParamsMapping.METRIC_TYPES.MIN_BUCKET", + "type": "Object", "tags": [], - "label": "order", + "label": "[METRIC_TYPES.MIN_BUCKET]", "description": [], "signature": [ - "\"asc\" | \"desc\" | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsBucketMin", + "text": "AggParamsBucketMin" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.size", - "type": "number", + "id": "def-common.AggParamsMapping.METRIC_TYPES.SUM_BUCKET", + "type": "Object", "tags": [], - "label": "size", + "label": "[METRIC_TYPES.SUM_BUCKET]", "description": [], "signature": [ - "number | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsBucketSum", + "text": "AggParamsBucketSum" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.shardSize", - "type": "number", + "id": "def-common.AggParamsMapping.METRIC_TYPES.FILTERED_METRIC", + "type": "Object", "tags": [], - "label": "shardSize", + "label": "[METRIC_TYPES.FILTERED_METRIC]", "description": [], "signature": [ - "number | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsFilteredMetric", + "text": "AggParamsFilteredMetric" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.missingBucket", - "type": "CompoundType", + "id": "def-common.AggParamsMapping.METRIC_TYPES.CUMULATIVE_SUM", + "type": "Object", "tags": [], - "label": "missingBucket", + "label": "[METRIC_TYPES.CUMULATIVE_SUM]", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsCumulativeSum", + "text": "AggParamsCumulativeSum" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.missingBucketLabel", - "type": "string", + "id": "def-common.AggParamsMapping.METRIC_TYPES.DERIVATIVE", + "type": "Object", "tags": [], - "label": "missingBucketLabel", + "label": "[METRIC_TYPES.DERIVATIVE]", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsDerivative", + "text": "AggParamsDerivative" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.otherBucket", - "type": "CompoundType", + "id": "def-common.AggParamsMapping.METRIC_TYPES.MOVING_FN", + "type": "Object", "tags": [], - "label": "otherBucket", + "label": "[METRIC_TYPES.MOVING_FN]", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsMovingAvg", + "text": "AggParamsMovingAvg" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.otherBucketLabel", - "type": "string", + "id": "def-common.AggParamsMapping.METRIC_TYPES.PERCENTILE_RANKS", + "type": "Object", "tags": [], - "label": "otherBucketLabel", + "label": "[METRIC_TYPES.PERCENTILE_RANKS]", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsPercentileRanks", + "text": "AggParamsPercentileRanks" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.exclude", - "type": "CompoundType", + "id": "def-common.AggParamsMapping.METRIC_TYPES.PERCENTILES", + "type": "Object", "tags": [], - "label": "exclude", + "label": "[METRIC_TYPES.PERCENTILES]", "description": [], "signature": [ - "string[] | number[] | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsPercentiles", + "text": "AggParamsPercentiles" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.include", - "type": "CompoundType", + "id": "def-common.AggParamsMapping.METRIC_TYPES.SERIAL_DIFF", + "type": "Object", "tags": [], - "label": "include", + "label": "[METRIC_TYPES.SERIAL_DIFF]", "description": [], "signature": [ - "string[] | number[] | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSerialDiff", + "text": "AggParamsSerialDiff" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.includeIsRegex", - "type": "CompoundType", + "id": "def-common.AggParamsMapping.METRIC_TYPES.TOP_HITS", + "type": "Object", "tags": [], - "label": "includeIsRegex", + "label": "[METRIC_TYPES.TOP_HITS]", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsTopHit", + "text": "AggParamsTopHit" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggParamsTerms.excludeIsRegex", - "type": "CompoundType", + "id": "def-common.AggParamsMapping.METRIC_TYPES.TOP_METRICS", + "type": "Object", "tags": [], - "label": "excludeIsRegex", + "label": "[METRIC_TYPES.TOP_METRICS]", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsTopMetrics", + "text": "AggParamsTopMetrics" + } ], - "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false } @@ -21640,18 +21532,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsTopHit", + "id": "def-common.AggParamsMax", "type": "Interface", "tags": [], - "label": "AggParamsTopHit", + "label": "AggParamsMax", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsTopHit", - "text": "AggParamsTopHit" + "section": "def-common.AggParamsMax", + "text": "AggParamsMax" }, " extends ", { @@ -21662,74 +21554,18 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", + "path": "src/plugins/data/common/search/aggs/metrics/max.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsTopHit.field", + "id": "def-common.AggParamsMax.field", "type": "string", "tags": [], "label": "field", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsTopHit.aggregate", - "type": "CompoundType", - "tags": [], - "label": "aggregate", - "description": [], - "signature": [ - "\"min\" | \"max\" | \"sum\" | \"average\" | \"concat\"" - ], - "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsTopHit.sortField", - "type": "string", - "tags": [], - "label": "sortField", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsTopHit.size", - "type": "number", - "tags": [], - "label": "size", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsTopHit.sortOrder", - "type": "CompoundType", - "tags": [], - "label": "sortOrder", - "description": [], - "signature": [ - "\"asc\" | \"desc\" | undefined" - ], - "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", + "path": "src/plugins/data/common/search/aggs/metrics/max.ts", "deprecated": false, "trackAdoption": false } @@ -21738,18 +21574,18 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsTopMetrics", + "id": "def-common.AggParamsMedian", "type": "Interface", "tags": [], - "label": "AggParamsTopMetrics", + "label": "AggParamsMedian", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsTopMetrics", - "text": "AggParamsTopMetrics" + "section": "def-common.AggParamsMedian", + "text": "AggParamsMedian" }, " extends ", { @@ -21760,60 +21596,112 @@ "text": "BaseAggParams" } ], - "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", + "path": "src/plugins/data/common/search/aggs/metrics/median.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsTopMetrics.field", + "id": "def-common.AggParamsMedian.field", "type": "string", "tags": [], "label": "field", "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", + "path": "src/plugins/data/common/search/aggs/metrics/median.ts", "deprecated": false, "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsMin", + "type": "Interface", + "tags": [], + "label": "AggParamsMin", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsMin", + "text": "AggParamsMin" }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/min.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsTopMetrics.sortField", + "id": "def-common.AggParamsMin.field", "type": "string", "tags": [], - "label": "sortField", + "label": "field", "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", + "path": "src/plugins/data/common/search/aggs/metrics/min.ts", "deprecated": false, "trackAdoption": false - }, + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsMovingAvg", + "type": "Interface", + "tags": [], + "label": "AggParamsMovingAvg", + "description": [], + "signature": [ { - "parentPluginId": "data", - "id": "def-common.AggParamsTopMetrics.sortOrder", - "type": "CompoundType", - "tags": [], - "label": "sortOrder", - "description": [], - "signature": [ - "\"asc\" | \"desc\" | undefined" - ], - "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", - "deprecated": false, - "trackAdoption": false + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsMovingAvg", + "text": "AggParamsMovingAvg" }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CommonAggParamsMovingAvg", + "text": "CommonAggParamsMovingAvg" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsTopMetrics.size", - "type": "number", + "id": "def-common.AggParamsMovingAvg.customMetric", + "type": "Object", "tags": [], - "label": "size", + "label": "customMetric", "description": [], "signature": [ - "number | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", + "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", "deprecated": false, "trackAdoption": false } @@ -21822,54 +21710,45 @@ }, { "parentPluginId": "data", - "id": "def-common.AggParamsValueCount", + "id": "def-common.AggParamsMovingAvgSerialized", "type": "Interface", "tags": [], - "label": "AggParamsValueCount", + "label": "AggParamsMovingAvgSerialized", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamsValueCount", - "text": "AggParamsValueCount" + "section": "def-common.AggParamsMovingAvgSerialized", + "text": "AggParamsMovingAvgSerialized" }, " extends ", { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseAggParams", - "text": "BaseAggParams" + "section": "def-common.CommonAggParamsMovingAvg", + "text": "CommonAggParamsMovingAvg" } ], - "path": "src/plugins/data/common/search/aggs/metrics/value_count.ts", + "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggParamsValueCount.field", - "type": "string", - "tags": [], - "label": "field", - "description": [], - "path": "src/plugins/data/common/search/aggs/metrics/value_count.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggParamsValueCount.emptyAsNull", - "type": "CompoundType", + "id": "def-common.AggParamsMovingAvgSerialized.customMetric", + "type": "Object", "tags": [], - "label": "emptyAsNull", + "label": "customMetric", "description": [], "signature": [ - "boolean | undefined" + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/metrics/value_count.ts", + "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", "deprecated": false, "trackAdoption": false } @@ -21878,58 +21757,43 @@ }, { "parentPluginId": "data", - "id": "def-common.AggsCommonSetup", + "id": "def-common.AggParamsMultiTerms", "type": "Interface", "tags": [], - "label": "AggsCommonSetup", + "label": "AggParamsMultiTerms", "description": [], - "path": "src/plugins/data/common/search/aggs/types.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsMultiTerms", + "text": "AggParamsMultiTerms" + }, + " extends CommonAggParamsMultiTerms" + ], + "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggsCommonSetup.types", + "id": "def-common.AggParamsMultiTerms.orderAgg", "type": "Object", "tags": [], - "label": "types", + "label": "orderAgg", "description": [], "signature": [ - "{ registerBucket: ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BucketAggType", - "text": "BucketAggType" - }, - ">(name: N, type: T) => void; registerMetric: ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.MetricAggType", - "text": "MetricAggType" + "section": "def-common.AggConfig", + "text": "AggConfig" }, - ">(name: N, type: T) => void; }" + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/types.ts", + "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", "deprecated": false, "trackAdoption": false } @@ -21938,337 +21802,2275 @@ }, { "parentPluginId": "data", - "id": "def-common.AggsCommonSetupDependencies", + "id": "def-common.AggParamsMultiTermsSerialized", "type": "Interface", "tags": [], - "label": "AggsCommonSetupDependencies", + "label": "AggParamsMultiTermsSerialized", "description": [], - "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsMultiTermsSerialized", + "text": "AggParamsMultiTermsSerialized" + }, + " extends CommonAggParamsMultiTerms" + ], + "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggsCommonSetupDependencies.registerFunction", - "type": "Function", + "id": "def-common.AggParamsMultiTermsSerialized.orderAgg", + "type": "Object", "tags": [], - "label": "registerFunction", + "label": "orderAgg", "description": [], "signature": [ - "(functionDefinition: ", - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.AnyExpressionFunctionDefinition", - "text": "AnyExpressionFunctionDefinition" - }, - " | (() => ", - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.AnyExpressionFunctionDefinition", - "text": "AnyExpressionFunctionDefinition" - }, - ")) => void" + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" ], - "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "path": "src/plugins/data/common/search/aggs/buckets/multi_terms.ts", "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "data", - "id": "def-common.AggsCommonSetupDependencies.registerFunction.$1", - "type": "CompoundType", - "tags": [], - "label": "functionDefinition", - "description": [], - "signature": [ - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.AnyExpressionFunctionDefinition", - "text": "AnyExpressionFunctionDefinition" - }, - " | (() => ", - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.AnyExpressionFunctionDefinition", - "text": "AnyExpressionFunctionDefinition" - }, - ")" - ], - "path": "src/plugins/expressions/common/service/expressions_services.ts", - "deprecated": false, - "trackAdoption": false - } - ] + "trackAdoption": false } ], "initialIsOpen": false }, { "parentPluginId": "data", - "id": "def-common.AggsCommonStart", + "id": "def-common.AggParamsPercentileRanks", "type": "Interface", "tags": [], - "label": "AggsCommonStart", + "label": "AggParamsPercentileRanks", "description": [], - "path": "src/plugins/data/common/search/aggs/types.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsPercentileRanks", + "text": "AggParamsPercentileRanks" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/percentile_ranks.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggsCommonStart.calculateAutoTimeExpression", - "type": "Function", + "id": "def-common.AggParamsPercentileRanks.field", + "type": "string", "tags": [], - "label": "calculateAutoTimeExpression", + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/metrics/percentile_ranks.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsPercentileRanks.values", + "type": "Array", + "tags": [], + "label": "values", "description": [], "signature": [ - "(range: ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataQueryPluginApi", - "section": "def-common.TimeRange", - "text": "TimeRange" - }, - ") => string | undefined" + "number[] | undefined" ], - "path": "src/plugins/data/common/search/aggs/types.ts", + "path": "src/plugins/data/common/search/aggs/metrics/percentile_ranks.ts", "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "data", - "id": "def-common.AggsCommonStart.calculateAutoTimeExpression.$1", - "type": "Object", - "tags": [], - "label": "range", - "description": [], - "signature": [ - "{ from: string; to: string; mode?: \"absolute\" | \"relative\" | undefined; }" - ], - "path": "src/plugins/data/common/search/aggs/utils/calculate_auto_time_expression.ts", - "deprecated": false, - "trackAdoption": false - } - ] + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsPercentiles", + "type": "Interface", + "tags": [], + "label": "AggParamsPercentiles", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsPercentiles", + "text": "AggParamsPercentiles" }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/percentiles.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggsCommonStart.createAggConfigs", - "type": "Function", + "id": "def-common.AggParamsPercentiles.field", + "type": "string", "tags": [], - "label": "createAggConfigs", + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/metrics/percentiles.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsPercentiles.percents", + "type": "Array", + "tags": [], + "label": "percents", "description": [], "signature": [ - "(indexPattern: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" - }, - ", configStates?: ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.CreateAggConfigParams", - "text": "CreateAggConfigParams" - }, - "[] | undefined, options?: Partial<", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggConfigsOptions", - "text": "AggConfigsOptions" - }, - "> | undefined) => ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggConfigs", - "text": "AggConfigs" - } + "number[] | undefined" ], - "path": "src/plugins/data/common/search/aggs/types.ts", + "path": "src/plugins/data/common/search/aggs/metrics/percentiles.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.AggsCommonStart.createAggConfigs.$1", - "type": "Object", - "tags": [], - "label": "indexPattern", - "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" - } - ], - "path": "src/plugins/data/common/search/aggs/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "data", - "id": "def-common.AggsCommonStart.createAggConfigs.$2", - "type": "Array", - "tags": [], - "label": "configStates", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.CreateAggConfigParams", - "text": "CreateAggConfigParams" - }, - "[] | undefined" - ], - "path": "src/plugins/data/common/search/aggs/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggsCommonStart.createAggConfigs.$3", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "signature": [ - "Partial<", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggConfigsOptions", - "text": "AggConfigsOptions" - }, - "> | undefined" - ], - "path": "src/plugins/data/common/search/aggs/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": false - } - ], - "returnComment": [] + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsRange", + "type": "Interface", + "tags": [], + "label": "AggParamsRange", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsRange", + "text": "AggParamsRange" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/buckets/range.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsRange.field", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/range.ts", + "deprecated": false, + "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggsCommonStart.types", - "type": "Object", + "id": "def-common.AggParamsRange.ranges", + "type": "Array", "tags": [], - "label": "types", + "label": "ranges", "description": [], "signature": [ - "{ get: (name: string) => ", { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.BucketAggType", - "text": "BucketAggType" + "section": "def-common.NumericalRange", + "text": "NumericalRange" }, - " | ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.MetricAggType", - "text": "MetricAggType" - }, - "; getAll: () => { buckets: ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BucketAggType", - "text": "BucketAggType" - }, - "[]; metrics: ", + "[] | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/range.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsRareTerms", + "type": "Interface", + "tags": [], + "label": "AggParamsRareTerms", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsRareTerms", + "text": "AggParamsRareTerms" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/buckets/rare_terms.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsRareTerms.field", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/rare_terms.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsRareTerms.max_doc_count", + "type": "number", + "tags": [], + "label": "max_doc_count", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/rare_terms.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSampler", + "type": "Interface", + "tags": [], + "label": "AggParamsSampler", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSampler", + "text": "AggParamsSampler" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/buckets/sampler.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsSampler.shard_size", + "type": "number", + "tags": [], + "label": "shard_size", + "description": [ + "\nLimits how many top-scoring documents are collected in the sample processed on each shard." + ], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/sampler.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSerialDiff", + "type": "Interface", + "tags": [], + "label": "AggParamsSerialDiff", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSerialDiff", + "text": "AggParamsSerialDiff" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CommonAggParamsSerialDiff", + "text": "CommonAggParamsSerialDiff" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsSerialDiff.customMetric", + "type": "Object", + "tags": [], + "label": "customMetric", + "description": [], + "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.MetricAggType", - "text": "MetricAggType" + "section": "def-common.AggConfig", + "text": "AggConfig" }, - "[]; }; }" + " | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSerialDiffSerialized", + "type": "Interface", + "tags": [], + "label": "AggParamsSerialDiffSerialized", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSerialDiffSerialized", + "text": "AggParamsSerialDiffSerialized" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CommonAggParamsSerialDiff", + "text": "CommonAggParamsSerialDiff" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsSerialDiffSerialized.customMetric", + "type": "Object", + "tags": [], + "label": "customMetric", + "description": [], + "signature": [ + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantTerms", + "type": "Interface", + "tags": [], + "label": "AggParamsSignificantTerms", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSignificantTerms", + "text": "AggParamsSignificantTerms" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/buckets/significant_terms.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantTerms.field", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/significant_terms.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantTerms.size", + "type": "number", + "tags": [], + "label": "size", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/significant_terms.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantTerms.exclude", + "type": "string", + "tags": [], + "label": "exclude", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/significant_terms.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantTerms.include", + "type": "string", + "tags": [], + "label": "include", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/significant_terms.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantText", + "type": "Interface", + "tags": [], + "label": "AggParamsSignificantText", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSignificantText", + "text": "AggParamsSignificantText" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantText.field", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantText.size", + "type": "number", + "tags": [], + "label": "size", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantText.min_doc_count", + "type": "number", + "tags": [], + "label": "min_doc_count", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantText.filter_duplicate_text", + "type": "CompoundType", + "tags": [], + "label": "filter_duplicate_text", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantText.exclude", + "type": "string", + "tags": [], + "label": "exclude", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSignificantText.include", + "type": "string", + "tags": [], + "label": "include", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/significant_text.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSinglePercentile", + "type": "Interface", + "tags": [], + "label": "AggParamsSinglePercentile", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSinglePercentile", + "text": "AggParamsSinglePercentile" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/single_percentile.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsSinglePercentile.field", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/metrics/single_percentile.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSinglePercentile.percentile", + "type": "number", + "tags": [], + "label": "percentile", + "description": [], + "path": "src/plugins/data/common/search/aggs/metrics/single_percentile.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSinglePercentileRank", + "type": "Interface", + "tags": [], + "label": "AggParamsSinglePercentileRank", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSinglePercentileRank", + "text": "AggParamsSinglePercentileRank" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/single_percentile_rank.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsSinglePercentileRank.field", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/metrics/single_percentile_rank.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSinglePercentileRank.value", + "type": "number", + "tags": [], + "label": "value", + "description": [], + "path": "src/plugins/data/common/search/aggs/metrics/single_percentile_rank.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsStdDeviation", + "type": "Interface", + "tags": [], + "label": "AggParamsStdDeviation", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsStdDeviation", + "text": "AggParamsStdDeviation" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/std_deviation.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsStdDeviation.field", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/metrics/std_deviation.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsStdDeviation.showBounds", + "type": "CompoundType", + "tags": [], + "label": "showBounds", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/std_deviation.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSum", + "type": "Interface", + "tags": [], + "label": "AggParamsSum", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsSum", + "text": "AggParamsSum" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/sum.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsSum.field", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/metrics/sum.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsSum.emptyAsNull", + "type": "CompoundType", + "tags": [], + "label": "emptyAsNull", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/sum.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTerms", + "type": "Interface", + "tags": [], + "label": "AggParamsTerms", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsTerms", + "text": "AggParamsTerms" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CommonAggParamsTerms", + "text": "CommonAggParamsTerms" + } + ], + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsTerms.orderAgg", + "type": "Object", + "tags": [], + "label": "orderAgg", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + " | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTerms.order", + "type": "Object", + "tags": [], + "label": "order", + "description": [], + "signature": [ + "{ value: \"asc\" | \"desc\"; text: string; } | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTermsSerialized", + "type": "Interface", + "tags": [], + "label": "AggParamsTermsSerialized", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsTermsSerialized", + "text": "AggParamsTermsSerialized" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CommonAggParamsTerms", + "text": "CommonAggParamsTerms" + } + ], + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsTermsSerialized.orderAgg", + "type": "Object", + "tags": [], + "label": "orderAgg", + "description": [], + "signature": [ + "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", + "SerializableRecord", + " | undefined; schema?: string | undefined; } | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTermsSerialized.order", + "type": "CompoundType", + "tags": [], + "label": "order", + "description": [], + "signature": [ + "\"asc\" | \"desc\" | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopHit", + "type": "Interface", + "tags": [], + "label": "AggParamsTopHit", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsTopHit", + "text": "AggParamsTopHit" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParamsTopHit", + "text": "BaseAggParamsTopHit" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopHit.sortOrder", + "type": "Object", + "tags": [], + "label": "sortOrder", + "description": [], + "signature": [ + "{ value: \"asc\" | \"desc\"; text: string; } | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopHit.sortField", + "type": "Object", + "tags": [], + "label": "sortField", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + }, + " | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopHitSerialized", + "type": "Interface", + "tags": [], + "label": "AggParamsTopHitSerialized", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsTopHitSerialized", + "text": "AggParamsTopHitSerialized" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParamsTopHit", + "text": "BaseAggParamsTopHit" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopHitSerialized.sortOrder", + "type": "CompoundType", + "tags": [], + "label": "sortOrder", + "description": [], + "signature": [ + "\"asc\" | \"desc\" | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopHitSerialized.sortField", + "type": "string", + "tags": [], + "label": "sortField", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopMetrics", + "type": "Interface", + "tags": [], + "label": "AggParamsTopMetrics", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsTopMetrics", + "text": "AggParamsTopMetrics" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParamsTopMetrics", + "text": "BaseAggParamsTopMetrics" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopMetrics.sortOrder", + "type": "Object", + "tags": [], + "label": "sortOrder", + "description": [], + "signature": [ + "{ value: \"asc\" | \"desc\"; text: string; } | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopMetrics.sortField", + "type": "Object", + "tags": [], + "label": "sortField", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + }, + " | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopMetricsSerialized", + "type": "Interface", + "tags": [], + "label": "AggParamsTopMetricsSerialized", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsTopMetricsSerialized", + "text": "AggParamsTopMetricsSerialized" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParamsTopMetrics", + "text": "BaseAggParamsTopMetrics" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopMetricsSerialized.sortOrder", + "type": "CompoundType", + "tags": [], + "label": "sortOrder", + "description": [], + "signature": [ + "\"asc\" | \"desc\" | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsTopMetricsSerialized.sortField", + "type": "string", + "tags": [], + "label": "sortField", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsValueCount", + "type": "Interface", + "tags": [], + "label": "AggParamsValueCount", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsValueCount", + "text": "AggParamsValueCount" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/value_count.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggParamsValueCount.field", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "path": "src/plugins/data/common/search/aggs/metrics/value_count.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggParamsValueCount.emptyAsNull", + "type": "CompoundType", + "tags": [], + "label": "emptyAsNull", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/value_count.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonSetup", + "type": "Interface", + "tags": [], + "label": "AggsCommonSetup", + "description": [], + "path": "src/plugins/data/common/search/aggs/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggsCommonSetup.types", + "type": "Object", + "tags": [], + "label": "types", + "description": [], + "signature": [ + "{ registerBucket: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BucketAggType", + "text": "BucketAggType" + }, + ">(name: N, type: T) => void; registerMetric: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.MetricAggType", + "text": "MetricAggType" + }, + ">(name: N, type: T) => void; }" + ], + "path": "src/plugins/data/common/search/aggs/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonSetupDependencies", + "type": "Interface", + "tags": [], + "label": "AggsCommonSetupDependencies", + "description": [], + "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggsCommonSetupDependencies.registerFunction", + "type": "Function", + "tags": [], + "label": "registerFunction", + "description": [], + "signature": [ + "(functionDefinition: ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.AnyExpressionFunctionDefinition", + "text": "AnyExpressionFunctionDefinition" + }, + " | (() => ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.AnyExpressionFunctionDefinition", + "text": "AnyExpressionFunctionDefinition" + }, + ")) => void" + ], + "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggsCommonSetupDependencies.registerFunction.$1", + "type": "CompoundType", + "tags": [], + "label": "functionDefinition", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.AnyExpressionFunctionDefinition", + "text": "AnyExpressionFunctionDefinition" + }, + " | (() => ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.AnyExpressionFunctionDefinition", + "text": "AnyExpressionFunctionDefinition" + }, + ")" + ], + "path": "src/plugins/expressions/common/service/expressions_services.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStart", + "type": "Interface", + "tags": [], + "label": "AggsCommonStart", + "description": [], + "path": "src/plugins/data/common/search/aggs/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStart.calculateAutoTimeExpression", + "type": "Function", + "tags": [], + "label": "calculateAutoTimeExpression", + "description": [], + "signature": [ + "(range: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRange", + "text": "TimeRange" + }, + ") => string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStart.calculateAutoTimeExpression.$1", + "type": "Object", + "tags": [], + "label": "range", + "description": [], + "signature": [ + "{ from: string; to: string; mode?: \"absolute\" | \"relative\" | undefined; }" + ], + "path": "src/plugins/data/common/search/aggs/utils/calculate_auto_time_expression.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStart.createAggConfigs", + "type": "Function", + "tags": [], + "label": "createAggConfigs", + "description": [], + "signature": [ + "(indexPattern: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + ", configStates?: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CreateAggConfigParams", + "text": "CreateAggConfigParams" + }, + "[] | undefined, options?: Partial<", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfigsOptions", + "text": "AggConfigsOptions" + }, + "> | undefined) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfigs", + "text": "AggConfigs" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStart.createAggConfigs.$1", + "type": "Object", + "tags": [], + "label": "indexPattern", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + } + ], + "path": "src/plugins/data/common/search/aggs/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStart.createAggConfigs.$2", + "type": "Array", + "tags": [], + "label": "configStates", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CreateAggConfigParams", + "text": "CreateAggConfigParams" + }, + "[] | undefined" + ], + "path": "src/plugins/data/common/search/aggs/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStart.createAggConfigs.$3", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "Partial<", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfigsOptions", + "text": "AggConfigsOptions" + }, + "> | undefined" + ], + "path": "src/plugins/data/common/search/aggs/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStart.types", + "type": "Object", + "tags": [], + "label": "types", + "description": [], + "signature": [ + "{ get: (name: string) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BucketAggType", + "text": "BucketAggType" + }, + " | ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.MetricAggType", + "text": "MetricAggType" + }, + "; getAll: () => { buckets: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BucketAggType", + "text": "BucketAggType" + }, + "[]; metrics: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.MetricAggType", + "text": "MetricAggType" + }, + "[]; }; }" + ], + "path": "src/plugins/data/common/search/aggs/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStartDependencies", + "type": "Interface", + "tags": [], + "label": "AggsCommonStartDependencies", + "description": [], + "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStartDependencies.getIndexPattern", + "type": "Function", + "tags": [], + "label": "getIndexPattern", + "description": [], + "signature": [ + "(id: string) => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + ">" + ], + "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStartDependencies.getIndexPattern.$1", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string" + ], + "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStartDependencies.getConfig", + "type": "Function", + "tags": [], + "label": "getConfig", + "description": [], + "signature": [ + "(key: string, defaultOverride?: T | undefined) => T" + ], + "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStartDependencies.getConfig.$1", + "type": "string", + "tags": [], + "label": "key", + "description": [], + "path": "src/plugins/data/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStartDependencies.getConfig.$2", + "type": "Uncategorized", + "tags": [], + "label": "defaultOverride", + "description": [], + "signature": [ + "T | undefined" + ], + "path": "src/plugins/data/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStartDependencies.fieldFormats", + "type": "Object", + "tags": [], + "label": "fieldFormats", + "description": [], + "signature": [ + "{ deserialize: ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FormatFactory", + "text": "FormatFactory" + }, + "; getDefaultConfig: (fieldType: ", + "KBN_FIELD_TYPES", + ", esTypes?: ", + "ES_FIELD_TYPES", + "[] | undefined) => ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatConfig", + "text": "FieldFormatConfig" + }, + "; getType: (formatId: string) => ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatInstanceType", + "text": "FieldFormatInstanceType" + }, + " | undefined; getTypeWithoutMetaParams: (formatId: string) => ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatInstanceType", + "text": "FieldFormatInstanceType" + }, + " | undefined; getDefaultType: (fieldType: ", + "KBN_FIELD_TYPES", + ", esTypes?: ", + "ES_FIELD_TYPES", + "[] | undefined) => ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatInstanceType", + "text": "FieldFormatInstanceType" + }, + " | undefined; getTypeNameByEsTypes: (esTypes: ", + "ES_FIELD_TYPES", + "[] | undefined) => ", + "ES_FIELD_TYPES", + " | undefined; getDefaultTypeName: (fieldType: ", + "KBN_FIELD_TYPES", + ", esTypes?: ", + "ES_FIELD_TYPES", + "[] | undefined) => ", + "ES_FIELD_TYPES", + " | ", + "KBN_FIELD_TYPES", + "; getInstance: (formatId: string, params?: ", + "SerializableRecord", + ") => ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormat", + "text": "FieldFormat" + }, + "; getDefaultInstancePlain: (fieldType: ", + "KBN_FIELD_TYPES", + ", esTypes?: ", + "ES_FIELD_TYPES", + "[] | undefined, params?: ", + "SerializableRecord", + ") => ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormat", + "text": "FieldFormat" + }, + "; getDefaultInstanceCacheResolver: (fieldType: ", + "KBN_FIELD_TYPES", + ", esTypes?: ", + "ES_FIELD_TYPES", + "[] | undefined) => string; getByFieldType: (fieldType: ", + "KBN_FIELD_TYPES", + ") => ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatInstanceType", + "text": "FieldFormatInstanceType" + }, + "[]; getDefaultInstance: (fieldType: ", + "KBN_FIELD_TYPES", + ", esTypes?: ", + "ES_FIELD_TYPES", + "[] | undefined, params?: ", + "SerializableRecord", + ") => ", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormat", + "text": "FieldFormat" + }, + "; parseDefaultTypeMap: (value: Record) => void; has: (id: string) => boolean; }" + ], + "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStartDependencies.calculateBounds", + "type": "Function", + "tags": [], + "label": "calculateBounds", + "description": [], + "signature": [ + "(timeRange: ", + "TimeRange", + ") => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRangeBounds", + "text": "TimeRangeBounds" + } + ], + "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggsCommonStartDependencies.calculateBounds.$1", + "type": "Object", + "tags": [], + "label": "timeRange", + "description": [], + "signature": [ + "{ from: string; to: string; mode?: \"absolute\" | \"relative\" | undefined; }" + ], + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig", + "type": "Interface", + "tags": [], + "label": "AggTypeConfig", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggTypeConfig", + "text": "AggTypeConfig" + }, + "" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.createFilter", + "type": "Function", + "tags": [], + "label": "createFilter", + "description": [], + "signature": [ + "((aggConfig: TAggConfig, key: any, params?: any) => any) | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.createFilter.$1", + "type": "Uncategorized", + "tags": [], + "label": "aggConfig", + "description": [], + "signature": [ + "TAggConfig" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.createFilter.$2", + "type": "Any", + "tags": [], + "label": "key", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.createFilter.$3", + "type": "Any", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.dslName", + "type": "string", + "tags": [], + "label": "dslName", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.expressionName", + "type": "string", + "tags": [], + "label": "expressionName", + "description": [], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.makeLabel", + "type": "CompoundType", + "tags": [], + "label": "makeLabel", + "description": [], + "signature": [ + "((aggConfig: TAggConfig) => string) | (() => string) | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.ordered", + "type": "Any", + "tags": [], + "label": "ordered", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.hasNoDsl", + "type": "CompoundType", + "tags": [], + "label": "hasNoDsl", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.hasNoDslParams", + "type": "CompoundType", + "tags": [], + "label": "hasNoDslParams", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.params", + "type": "Array", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "Partial[] | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.valueType", + "type": "CompoundType", + "tags": [], + "label": "valueType", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.DatatableColumnType", + "text": "DatatableColumnType" + }, + " | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.getRequestAggs", + "type": "CompoundType", + "tags": [], + "label": "getRequestAggs", + "description": [], + "signature": [ + "((aggConfig: TAggConfig) => TAggConfig[]) | (() => void | TAggConfig[]) | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.getResponseAggs", + "type": "CompoundType", + "tags": [], + "label": "getResponseAggs", + "description": [], + "signature": [ + "((aggConfig: TAggConfig) => TAggConfig[]) | (() => void | TAggConfig[]) | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.customLabels", + "type": "CompoundType", + "tags": [], + "label": "customLabels", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.json", + "type": "CompoundType", + "tags": [], + "label": "json", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.decorateAggConfig", + "type": "Function", + "tags": [], + "label": "decorateAggConfig", + "description": [], + "signature": [ + "(() => any) | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.postFlightRequest", + "type": "Function", + "tags": [], + "label": "postFlightRequest", + "description": [], + "signature": [ + "PostFlightRequestFn | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.hasPrecisionError", + "type": "Function", + "tags": [], + "label": "hasPrecisionError", + "description": [], + "signature": [ + "((aggBucket: Record) => boolean) | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.hasPrecisionError.$1", + "type": "Object", + "tags": [], + "label": "aggBucket", + "description": [], + "signature": [ + "Record" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } ], - "path": "src/plugins/data/common/search/aggs/types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggsCommonStartDependencies", - "type": "Interface", - "tags": [], - "label": "AggsCommonStartDependencies", - "description": [], - "path": "src/plugins/data/common/search/aggs/aggs_service.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ + "returnComment": [] + }, { "parentPluginId": "data", - "id": "def-common.AggsCommonStartDependencies.getIndexPattern", + "id": "def-common.AggTypeConfig.getSerializedFormat", "type": "Function", "tags": [], - "label": "getIndexPattern", + "label": "getSerializedFormat", "description": [], "signature": [ - "(id: string) => Promise<", + "((agg: TAggConfig) => ", { - "pluginId": "dataViews", + "pluginId": "fieldFormats", "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.SerializedFieldFormat", + "text": "SerializedFieldFormat" }, - ">" + "<{}, ", + "SerializableRecord", + ">) | undefined" ], - "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "path": "src/plugins/data/common/search/aggs/agg_type.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggsCommonStartDependencies.getIndexPattern.$1", - "type": "string", + "id": "def-common.AggTypeConfig.getSerializedFormat.$1", + "type": "Uncategorized", "tags": [], - "label": "id", + "label": "agg", "description": [], "signature": [ - "string" + "TAggConfig" ], - "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "path": "src/plugins/data/common/search/aggs/agg_type.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -22278,321 +24080,256 @@ }, { "parentPluginId": "data", - "id": "def-common.AggsCommonStartDependencies.getConfig", + "id": "def-common.AggTypeConfig.getValue", "type": "Function", "tags": [], - "label": "getConfig", + "label": "getValue", "description": [], "signature": [ - "(key: string, defaultOverride?: T | undefined) => T" + "((agg: TAggConfig, bucket: any) => any) | undefined" ], - "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "path": "src/plugins/data/common/search/aggs/agg_type.ts", "deprecated": false, "trackAdoption": false, - "returnComment": [], "children": [ { "parentPluginId": "data", - "id": "def-common.AggsCommonStartDependencies.getConfig.$1", - "type": "string", + "id": "def-common.AggTypeConfig.getValue.$1", + "type": "Uncategorized", "tags": [], - "label": "key", + "label": "agg", "description": [], - "path": "src/plugins/data/common/types.ts", + "signature": [ + "TAggConfig" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", "deprecated": false, - "trackAdoption": false + "trackAdoption": false, + "isRequired": true }, { "parentPluginId": "data", - "id": "def-common.AggsCommonStartDependencies.getConfig.$2", - "type": "Uncategorized", + "id": "def-common.AggTypeConfig.getValue.$2", + "type": "Any", "tags": [], - "label": "defaultOverride", + "label": "bucket", "description": [], "signature": [ - "T | undefined" + "any" ], - "path": "src/plugins/data/common/types.ts", + "path": "src/plugins/data/common/search/aggs/agg_type.ts", "deprecated": false, - "trackAdoption": false + "trackAdoption": false, + "isRequired": true } - ] + ], + "returnComment": [] }, { "parentPluginId": "data", - "id": "def-common.AggsCommonStartDependencies.fieldFormats", - "type": "Object", + "id": "def-common.AggTypeConfig.getKey", + "type": "Function", "tags": [], - "label": "fieldFormats", + "label": "getKey", "description": [], "signature": [ - "{ deserialize: ", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FormatFactory", - "text": "FormatFactory" - }, - "; getDefaultConfig: (fieldType: ", - "KBN_FIELD_TYPES", - ", esTypes?: ", - "ES_FIELD_TYPES", - "[] | undefined) => ", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormatConfig", - "text": "FieldFormatConfig" - }, - "; getType: (formatId: string) => ", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormatInstanceType", - "text": "FieldFormatInstanceType" - }, - " | undefined; getTypeWithoutMetaParams: (formatId: string) => ", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormatInstanceType", - "text": "FieldFormatInstanceType" - }, - " | undefined; getDefaultType: (fieldType: ", - "KBN_FIELD_TYPES", - ", esTypes?: ", - "ES_FIELD_TYPES", - "[] | undefined) => ", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormatInstanceType", - "text": "FieldFormatInstanceType" - }, - " | undefined; getTypeNameByEsTypes: (esTypes: ", - "ES_FIELD_TYPES", - "[] | undefined) => ", - "ES_FIELD_TYPES", - " | undefined; getDefaultTypeName: (fieldType: ", - "KBN_FIELD_TYPES", - ", esTypes?: ", - "ES_FIELD_TYPES", - "[] | undefined) => ", - "ES_FIELD_TYPES", - " | ", - "KBN_FIELD_TYPES", - "; getInstance: (formatId: string, params?: ", - "SerializableRecord", - ") => ", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormat", - "text": "FieldFormat" - }, - "; getDefaultInstancePlain: (fieldType: ", - "KBN_FIELD_TYPES", - ", esTypes?: ", - "ES_FIELD_TYPES", - "[] | undefined, params?: ", - "SerializableRecord", - ") => ", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormat", - "text": "FieldFormat" - }, - "; getDefaultInstanceCacheResolver: (fieldType: ", - "KBN_FIELD_TYPES", - ", esTypes?: ", - "ES_FIELD_TYPES", - "[] | undefined) => string; getByFieldType: (fieldType: ", - "KBN_FIELD_TYPES", - ") => ", + "((bucket: any, key: any, agg: TAggConfig) => any) | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormatInstanceType", - "text": "FieldFormatInstanceType" + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.getKey.$1", + "type": "Any", + "tags": [], + "label": "bucket", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true }, - "[]; getDefaultInstance: (fieldType: ", - "KBN_FIELD_TYPES", - ", esTypes?: ", - "ES_FIELD_TYPES", - "[] | undefined, params?: ", - "SerializableRecord", - ") => ", { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormat", - "text": "FieldFormat" + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.getKey.$2", + "type": "Any", + "tags": [], + "label": "key", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true }, - "; parseDefaultTypeMap: (value: Record) => void; has: (id: string) => boolean; }" + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.getKey.$3", + "type": "Uncategorized", + "tags": [], + "label": "agg", + "description": [], + "signature": [ + "TAggConfig" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } ], - "path": "src/plugins/data/common/search/aggs/aggs_service.ts", - "deprecated": false, - "trackAdoption": false + "returnComment": [] }, { "parentPluginId": "data", - "id": "def-common.AggsCommonStartDependencies.calculateBounds", + "id": "def-common.AggTypeConfig.getValueBucketPath", "type": "Function", "tags": [], - "label": "calculateBounds", + "label": "getValueBucketPath", "description": [], "signature": [ - "(timeRange: ", - "TimeRange", - ") => ", + "((agg: TAggConfig) => string) | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { - "pluginId": "data", - "scope": "common", - "docId": "kibDataQueryPluginApi", - "section": "def-common.TimeRangeBounds", - "text": "TimeRangeBounds" + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.getValueBucketPath.$1", + "type": "Uncategorized", + "tags": [], + "label": "agg", + "description": [], + "signature": [ + "TAggConfig" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true } ], - "path": "src/plugins/data/common/search/aggs/aggs_service.ts", + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypeConfig.getResponseId", + "type": "Function", + "tags": [], + "label": "getResponseId", + "description": [], + "signature": [ + "((agg: TAggConfig) => string) | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_type.ts", "deprecated": false, "trackAdoption": false, - "returnComment": [], "children": [ { "parentPluginId": "data", - "id": "def-common.AggsCommonStartDependencies.calculateBounds.$1", - "type": "Object", + "id": "def-common.AggTypeConfig.getResponseId.$1", + "type": "Uncategorized", "tags": [], - "label": "timeRange", + "label": "agg", "description": [], "signature": [ - "{ from: string; to: string; mode?: \"absolute\" | \"relative\" | undefined; }" + "TAggConfig" ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", + "path": "src/plugins/data/common/search/aggs/agg_type.ts", "deprecated": false, - "trackAdoption": false + "trackAdoption": false, + "isRequired": true } - ] + ], + "returnComment": [] } ], "initialIsOpen": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig", + "id": "def-common.AggTypesDependencies", "type": "Interface", "tags": [], - "label": "AggTypeConfig", + "label": "AggTypesDependencies", "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggTypeConfig", - "text": "AggTypeConfig" - }, - "" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/agg_types.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.name", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.title", - "type": "string", - "tags": [], - "label": "title", - "description": [], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.createFilter", + "id": "def-common.AggTypesDependencies.calculateBounds", "type": "Function", "tags": [], - "label": "createFilter", + "label": "calculateBounds", "description": [], "signature": [ - "((aggConfig: TAggConfig, key: any, params?: any) => any) | undefined" + "(timeRange: ", + "TimeRange", + ") => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataQueryPluginApi", + "section": "def-common.TimeRangeBounds", + "text": "TimeRangeBounds" + } ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/agg_types.ts", "deprecated": false, "trackAdoption": false, + "returnComment": [], "children": [ { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.createFilter.$1", - "type": "Uncategorized", + "id": "def-common.AggTypesDependencies.calculateBounds.$1", + "type": "Object", "tags": [], - "label": "aggConfig", + "label": "timeRange", "description": [], "signature": [ - "TAggConfig" + "{ from: string; to: string; mode?: \"absolute\" | \"relative\" | undefined; }" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, + "trackAdoption": false + } + ] + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypesDependencies.getConfig", + "type": "Function", + "tags": [], + "label": "getConfig", + "description": [], + "signature": [ + "(key: string) => T" + ], + "path": "src/plugins/data/common/search/aggs/agg_types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.createFilter.$2", - "type": "Any", + "id": "def-common.AggTypesDependencies.getConfig.$1", + "type": "string", "tags": [], "label": "key", "description": [], "signature": [ - "any" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.createFilter.$3", - "type": "Any", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "any" + "string" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/agg_types.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -22602,588 +24339,625 @@ }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.type", + "id": "def-common.AggTypesDependencies.getFieldFormatsStart", + "type": "Function", + "tags": [], + "label": "getFieldFormatsStart", + "description": [], + "signature": [ + "() => Pick<", + { + "pluginId": "fieldFormats", + "scope": "common", + "docId": "kibFieldFormatsPluginApi", + "section": "def-common.FieldFormatsStartCommon", + "text": "FieldFormatsStartCommon" + }, + ", \"deserialize\" | \"getDefaultInstance\">" + ], + "path": "src/plugins/data/common/search/aggs/agg_types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "data", + "id": "def-common.AggTypesDependencies.aggExecutionContext", + "type": "Object", + "tags": [], + "label": "aggExecutionContext", + "description": [], + "signature": [ + "{ shouldDetectTimeZone?: boolean | undefined; } | undefined" + ], + "path": "src/plugins/data/common/search/aggs/agg_types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.AutoBounds", + "type": "Interface", + "tags": [], + "label": "AutoBounds", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.AutoBounds.min", + "type": "number", + "tags": [], + "label": "min", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.AutoBounds.max", + "type": "number", + "tags": [], + "label": "max", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.BaseAggParams", + "type": "Interface", + "tags": [], + "label": "BaseAggParams", + "description": [], + "path": "src/plugins/data/common/search/aggs/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.BaseAggParams.json", "type": "string", "tags": [], - "label": "type", + "label": "json", "description": [], "signature": [ "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.dslName", + "id": "def-common.BaseAggParams.customLabel", "type": "string", "tags": [], - "label": "dslName", + "label": "customLabel", "description": [], "signature": [ "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.expressionName", + "id": "def-common.BaseAggParams.timeShift", "type": "string", "tags": [], - "label": "expressionName", + "label": "timeShift", "description": [], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/types.ts", "deprecated": false, "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.BaseAggParamsTopHit", + "type": "Interface", + "tags": [], + "label": "BaseAggParamsTopHit", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParamsTopHit", + "text": "BaseAggParamsTopHit" }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.makeLabel", - "type": "CompoundType", + "id": "def-common.BaseAggParamsTopHit.field", + "type": "string", "tags": [], - "label": "makeLabel", + "label": "field", "description": [], - "signature": [ - "((aggConfig: TAggConfig) => string) | (() => string) | undefined" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.ordered", - "type": "Any", + "id": "def-common.BaseAggParamsTopHit.aggregate", + "type": "CompoundType", "tags": [], - "label": "ordered", + "label": "aggregate", "description": [], "signature": [ - "any" + "\"min\" | \"max\" | \"sum\" | \"average\" | \"concat\"" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.hasNoDsl", - "type": "CompoundType", + "id": "def-common.BaseAggParamsTopHit.size", + "type": "number", "tags": [], - "label": "hasNoDsl", + "label": "size", "description": [], "signature": [ - "boolean | undefined" + "number | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/metrics/top_hit.ts", "deprecated": false, "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.BaseAggParamsTopMetrics", + "type": "Interface", + "tags": [], + "label": "BaseAggParamsTopMetrics", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParamsTopMetrics", + "text": "BaseAggParamsTopMetrics" }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.hasNoDslParams", - "type": "CompoundType", + "id": "def-common.BaseAggParamsTopMetrics.field", + "type": "string", "tags": [], - "label": "hasNoDslParams", + "label": "field", "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.params", - "type": "Array", + "id": "def-common.BaseAggParamsTopMetrics.size", + "type": "number", "tags": [], - "label": "params", + "label": "size", "description": [], "signature": [ - "Partial[] | undefined" + "number | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/metrics/top_metrics.ts", "deprecated": false, "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.BaseHit", + "type": "Interface", + "tags": [], + "label": "BaseHit", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseHit", + "text": "BaseHit" }, + "" + ], + "path": "src/plugins/data/common/search/expressions/eql_raw_response.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.valueType", - "type": "CompoundType", + "id": "def-common.BaseHit._index", + "type": "string", "tags": [], - "label": "valueType", + "label": "_index", "description": [], - "signature": [ - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.DatatableColumnType", - "text": "DatatableColumnType" - }, - " | undefined" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/expressions/eql_raw_response.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getRequestAggs", - "type": "CompoundType", + "id": "def-common.BaseHit._id", + "type": "string", "tags": [], - "label": "getRequestAggs", + "label": "_id", "description": [], - "signature": [ - "((aggConfig: TAggConfig) => TAggConfig[]) | (() => void | TAggConfig[]) | undefined" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/expressions/eql_raw_response.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getResponseAggs", - "type": "CompoundType", + "id": "def-common.BaseHit._source", + "type": "Uncategorized", "tags": [], - "label": "getResponseAggs", + "label": "_source", "description": [], "signature": [ - "((aggConfig: TAggConfig) => TAggConfig[]) | (() => void | TAggConfig[]) | undefined" + "T" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/expressions/eql_raw_response.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.customLabels", - "type": "CompoundType", + "id": "def-common.BaseHit.fields", + "type": "Object", "tags": [], - "label": "customLabels", + "label": "fields", "description": [], "signature": [ - "boolean | undefined" + "Record | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/expressions/eql_raw_response.ts", "deprecated": false, "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.BucketAggParam", + "type": "Interface", + "tags": [], + "label": "BucketAggParam", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BucketAggParam", + "text": "BucketAggParam" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamType", + "text": "AggParamType" }, + "" + ], + "path": "src/plugins/data/common/search/aggs/buckets/bucket_agg_type.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.json", + "id": "def-common.BucketAggParam.scriptable", "type": "CompoundType", "tags": [], - "label": "json", + "label": "scriptable", "description": [], "signature": [ "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/buckets/bucket_agg_type.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.decorateAggConfig", - "type": "Function", + "id": "def-common.BucketAggParam.filterFieldTypes", + "type": "CompoundType", "tags": [], - "label": "decorateAggConfig", + "label": "filterFieldTypes", "description": [], "signature": [ - "(() => any) | undefined" + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.FieldTypes", + "text": "FieldTypes" + }, + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/buckets/bucket_agg_type.ts", "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] + "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.postFlightRequest", - "type": "Function", + "id": "def-common.BucketAggParam.onlyAggregatable", + "type": "CompoundType", "tags": [], - "label": "postFlightRequest", + "label": "onlyAggregatable", "description": [], "signature": [ - "PostFlightRequestFn | undefined" + "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/buckets/bucket_agg_type.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.hasPrecisionError", + "id": "def-common.BucketAggParam.filterField", "type": "Function", "tags": [], - "label": "hasPrecisionError", - "description": [], - "signature": [ - "((aggBucket: Record) => boolean) | undefined" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.hasPrecisionError.$1", - "type": "Object", - "tags": [], - "label": "aggBucket", - "description": [], - "signature": [ - "Record" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } + "label": "filterField", + "description": [ + "\nFilter available fields by passing filter fn on a {@link DataViewField}\nIf used, takes precedence over filterFieldTypes and other filter params" ], - "returnComment": [] - }, - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getSerializedFormat", - "type": "Function", - "tags": [], - "label": "getSerializedFormat", - "description": [], "signature": [ - "((agg: TAggConfig) => ", { - "pluginId": "fieldFormats", + "pluginId": "data", "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.SerializedFieldFormat", - "text": "SerializedFieldFormat" + "docId": "kibDataSearchPluginApi", + "section": "def-common.FilterFieldFn", + "text": "FilterFieldFn" }, - "<{}, ", - "SerializableRecord", - ">) | undefined" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getSerializedFormat.$1", - "type": "Uncategorized", - "tags": [], - "label": "agg", - "description": [], - "signature": [ - "TAggConfig" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getValue", - "type": "Function", - "tags": [], - "label": "getValue", - "description": [], - "signature": [ - "((agg: TAggConfig, bucket: any) => any) | undefined" + " | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/buckets/bucket_agg_type.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getValue.$1", - "type": "Uncategorized", - "tags": [], - "label": "agg", - "description": [], - "signature": [ - "TAggConfig" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getValue.$2", - "type": "Any", - "tags": [], - "label": "bucket", - "description": [], - "signature": [ - "any" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.Cidr", + "type": "Interface", + "tags": [], + "label": "Cidr", + "description": [], + "path": "src/plugins/data/common/search/expressions/cidr.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getKey", - "type": "Function", + "id": "def-common.Cidr.mask", + "type": "string", "tags": [], - "label": "getKey", + "label": "mask", "description": [], - "signature": [ - "((bucket: any, key: any, agg: TAggConfig) => any) | undefined" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/expressions/cidr.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getKey.$1", - "type": "Any", - "tags": [], - "label": "bucket", - "description": [], - "signature": [ - "any" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getKey.$2", - "type": "Any", - "tags": [], - "label": "key", - "description": [], - "signature": [ - "any" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getKey.$3", - "type": "Uncategorized", - "tags": [], - "label": "agg", - "description": [], - "signature": [ - "TAggConfig" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.CidrMaskIpRangeAggKey", + "type": "Interface", + "tags": [], + "label": "CidrMaskIpRangeAggKey", + "description": [], + "path": "src/plugins/data/common/search/aggs/buckets/lib/ip_range.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getValueBucketPath", - "type": "Function", + "id": "def-common.CidrMaskIpRangeAggKey.type", + "type": "string", "tags": [], - "label": "getValueBucketPath", + "label": "type", "description": [], "signature": [ - "((agg: TAggConfig) => string) | undefined" + "\"mask\"" ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/buckets/lib/ip_range.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getValueBucketPath.$1", - "type": "Uncategorized", - "tags": [], - "label": "agg", - "description": [], - "signature": [ - "TAggConfig" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] + "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getResponseId", - "type": "Function", + "id": "def-common.CidrMaskIpRangeAggKey.mask", + "type": "string", "tags": [], - "label": "getResponseId", + "label": "mask", "description": [], - "signature": [ - "((agg: TAggConfig) => string) | undefined" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", + "path": "src/plugins/data/common/search/aggs/buckets/lib/ip_range.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.AggTypeConfig.getResponseId.$1", - "type": "Uncategorized", - "tags": [], - "label": "agg", - "description": [], - "signature": [ - "TAggConfig" - ], - "path": "src/plugins/data/common/search/aggs/agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] + "trackAdoption": false } ], "initialIsOpen": false }, { "parentPluginId": "data", - "id": "def-common.AggTypesDependencies", + "id": "def-common.CommonAggParamsCumulativeSum", "type": "Interface", "tags": [], - "label": "AggTypesDependencies", + "label": "CommonAggParamsCumulativeSum", "description": [], - "path": "src/plugins/data/common/search/aggs/agg_types.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CommonAggParamsCumulativeSum", + "text": "CommonAggParamsCumulativeSum" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AggTypesDependencies.calculateBounds", - "type": "Function", + "id": "def-common.CommonAggParamsCumulativeSum.buckets_path", + "type": "string", "tags": [], - "label": "calculateBounds", + "label": "buckets_path", "description": [], "signature": [ - "(timeRange: ", - "TimeRange", - ") => ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataQueryPluginApi", - "section": "def-common.TimeRangeBounds", - "text": "TimeRangeBounds" - } + "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_types.ts", + "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "data", - "id": "def-common.AggTypesDependencies.calculateBounds.$1", - "type": "Object", - "tags": [], - "label": "timeRange", - "description": [], - "signature": [ - "{ from: string; to: string; mode?: \"absolute\" | \"relative\" | undefined; }" - ], - "path": "src/plugins/data/common/search/aggs/buckets/date_histogram.ts", - "deprecated": false, - "trackAdoption": false - } - ] + "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypesDependencies.getConfig", - "type": "Function", + "id": "def-common.CommonAggParamsCumulativeSum.metricAgg", + "type": "string", "tags": [], - "label": "getConfig", + "label": "metricAgg", "description": [], "signature": [ - "(key: string) => T" + "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_types.ts", + "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.AggTypesDependencies.getConfig.$1", - "type": "string", - "tags": [], - "label": "key", - "description": [], - "signature": [ - "string" - ], - "path": "src/plugins/data/common/search/aggs/agg_types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.CommonAggParamsDerivative", + "type": "Interface", + "tags": [], + "label": "CommonAggParamsDerivative", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CommonAggParamsDerivative", + "text": "CommonAggParamsDerivative" }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "data", - "id": "def-common.AggTypesDependencies.getFieldFormatsStart", - "type": "Function", + "id": "def-common.CommonAggParamsDerivative.buckets_path", + "type": "string", "tags": [], - "label": "getFieldFormatsStart", + "label": "buckets_path", "description": [], "signature": [ - "() => Pick<", - { - "pluginId": "fieldFormats", - "scope": "common", - "docId": "kibFieldFormatsPluginApi", - "section": "def-common.FieldFormatsStartCommon", - "text": "FieldFormatsStartCommon" - }, - ", \"deserialize\" | \"getDefaultInstance\">" + "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_types.ts", + "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] + "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AggTypesDependencies.aggExecutionContext", - "type": "Object", + "id": "def-common.CommonAggParamsDerivative.metricAgg", + "type": "string", "tags": [], - "label": "aggExecutionContext", + "label": "metricAgg", "description": [], "signature": [ - "{ shouldDetectTimeZone?: boolean | undefined; } | undefined" + "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/agg_types.ts", + "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", "deprecated": false, "trackAdoption": false } @@ -23192,34 +24966,85 @@ }, { "parentPluginId": "data", - "id": "def-common.AutoBounds", + "id": "def-common.CommonAggParamsMovingAvg", "type": "Interface", "tags": [], - "label": "AutoBounds", + "label": "CommonAggParamsMovingAvg", "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CommonAggParamsMovingAvg", + "text": "CommonAggParamsMovingAvg" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.AutoBounds.min", - "type": "number", + "id": "def-common.CommonAggParamsMovingAvg.buckets_path", + "type": "string", "tags": [], - "label": "min", + "label": "buckets_path", "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.AutoBounds.max", + "id": "def-common.CommonAggParamsMovingAvg.window", "type": "number", "tags": [], - "label": "max", + "label": "window", "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/histogram.ts", + "signature": [ + "number | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.CommonAggParamsMovingAvg.script", + "type": "string", + "tags": [], + "label": "script", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.CommonAggParamsMovingAvg.metricAgg", + "type": "string", + "tags": [], + "label": "metricAgg", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", "deprecated": false, "trackAdoption": false } @@ -23228,54 +25053,57 @@ }, { "parentPluginId": "data", - "id": "def-common.BaseAggParams", + "id": "def-common.CommonAggParamsSerialDiff", "type": "Interface", "tags": [], - "label": "BaseAggParams", + "label": "CommonAggParamsSerialDiff", "description": [], - "path": "src/plugins/data/common/search/aggs/types.ts", + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.CommonAggParamsSerialDiff", + "text": "CommonAggParamsSerialDiff" + }, + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } + ], + "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.BaseAggParams.json", - "type": "string", - "tags": [], - "label": "json", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data/common/search/aggs/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.BaseAggParams.customLabel", + "id": "def-common.CommonAggParamsSerialDiff.buckets_path", "type": "string", "tags": [], - "label": "customLabel", + "label": "buckets_path", "description": [], "signature": [ "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/types.ts", + "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.BaseAggParams.timeShift", + "id": "def-common.CommonAggParamsSerialDiff.metricAgg", "type": "string", "tags": [], - "label": "timeShift", + "label": "metricAgg", "description": [], "signature": [ "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/types.ts", + "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", "deprecated": false, "trackAdoption": false } @@ -23284,248 +25112,191 @@ }, { "parentPluginId": "data", - "id": "def-common.BaseHit", + "id": "def-common.CommonAggParamsTerms", "type": "Interface", "tags": [], - "label": "BaseHit", + "label": "CommonAggParamsTerms", "description": [], "signature": [ { "pluginId": "data", "scope": "common", "docId": "kibDataSearchPluginApi", - "section": "def-common.BaseHit", - "text": "BaseHit" + "section": "def-common.CommonAggParamsTerms", + "text": "CommonAggParamsTerms" }, - "" + " extends ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BaseAggParams", + "text": "BaseAggParams" + } ], - "path": "src/plugins/data/common/search/expressions/eql_raw_response.ts", + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.BaseHit._index", + "id": "def-common.CommonAggParamsTerms.field", "type": "string", "tags": [], - "label": "_index", + "label": "field", "description": [], - "path": "src/plugins/data/common/search/expressions/eql_raw_response.ts", + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.BaseHit._id", + "id": "def-common.CommonAggParamsTerms.orderBy", "type": "string", "tags": [], - "label": "_id", + "label": "orderBy", "description": [], - "path": "src/plugins/data/common/search/expressions/eql_raw_response.ts", + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.BaseHit._source", - "type": "Uncategorized", + "id": "def-common.CommonAggParamsTerms.size", + "type": "number", "tags": [], - "label": "_source", + "label": "size", "description": [], "signature": [ - "T" + "number | undefined" ], - "path": "src/plugins/data/common/search/expressions/eql_raw_response.ts", + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.BaseHit.fields", - "type": "Object", + "id": "def-common.CommonAggParamsTerms.shardSize", + "type": "number", "tags": [], - "label": "fields", + "label": "shardSize", "description": [], "signature": [ - "Record | undefined" + "number | undefined" ], - "path": "src/plugins/data/common/search/expressions/eql_raw_response.ts", + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.BucketAggParam", - "type": "Interface", - "tags": [], - "label": "BucketAggParam", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.BucketAggParam", - "text": "BucketAggParam" - }, - " extends ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.AggParamType", - "text": "AggParamType" }, - "" - ], - "path": "src/plugins/data/common/search/aggs/buckets/bucket_agg_type.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "data", - "id": "def-common.BucketAggParam.scriptable", + "id": "def-common.CommonAggParamsTerms.missingBucket", "type": "CompoundType", "tags": [], - "label": "scriptable", + "label": "missingBucket", "description": [], "signature": [ "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/bucket_agg_type.ts", + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.BucketAggParam.filterFieldTypes", - "type": "CompoundType", + "id": "def-common.CommonAggParamsTerms.missingBucketLabel", + "type": "string", "tags": [], - "label": "filterFieldTypes", + "label": "missingBucketLabel", "description": [], "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.FieldTypes", - "text": "FieldTypes" - }, - " | undefined" + "string | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/bucket_agg_type.ts", + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.BucketAggParam.onlyAggregatable", + "id": "def-common.CommonAggParamsTerms.otherBucket", "type": "CompoundType", "tags": [], - "label": "onlyAggregatable", + "label": "otherBucket", "description": [], "signature": [ "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/bucket_agg_type.ts", + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.BucketAggParam.filterField", - "type": "Function", + "id": "def-common.CommonAggParamsTerms.otherBucketLabel", + "type": "string", "tags": [], - "label": "filterField", - "description": [ - "\nFilter available fields by passing filter fn on a {@link DataViewField}\nIf used, takes precedence over filterFieldTypes and other filter params" + "label": "otherBucketLabel", + "description": [], + "signature": [ + "string | undefined" ], + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-common.CommonAggParamsTerms.exclude", + "type": "CompoundType", + "tags": [], + "label": "exclude", + "description": [], "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.FilterFieldFn", - "text": "FilterFieldFn" - }, - " | undefined" + "string | string[] | number[] | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/bucket_agg_type.ts", + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.Cidr", - "type": "Interface", - "tags": [], - "label": "Cidr", - "description": [], - "path": "src/plugins/data/common/search/expressions/cidr.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ + }, { "parentPluginId": "data", - "id": "def-common.Cidr.mask", - "type": "string", + "id": "def-common.CommonAggParamsTerms.include", + "type": "CompoundType", "tags": [], - "label": "mask", + "label": "include", "description": [], - "path": "src/plugins/data/common/search/expressions/cidr.ts", + "signature": [ + "string | string[] | number[] | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "data", - "id": "def-common.CidrMaskIpRangeAggKey", - "type": "Interface", - "tags": [], - "label": "CidrMaskIpRangeAggKey", - "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/lib/ip_range.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ + }, { "parentPluginId": "data", - "id": "def-common.CidrMaskIpRangeAggKey.type", - "type": "string", + "id": "def-common.CommonAggParamsTerms.includeIsRegex", + "type": "CompoundType", "tags": [], - "label": "type", + "label": "includeIsRegex", "description": [], "signature": [ - "\"mask\"" + "boolean | undefined" ], - "path": "src/plugins/data/common/search/aggs/buckets/lib/ip_range.ts", + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "data", - "id": "def-common.CidrMaskIpRangeAggKey.mask", - "type": "string", + "id": "def-common.CommonAggParamsTerms.excludeIsRegex", + "type": "CompoundType", "tags": [], - "label": "mask", + "label": "excludeIsRegex", "description": [], - "path": "src/plugins/data/common/search/aggs/buckets/lib/ip_range.ts", + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", "deprecated": false, "trackAdoption": false } @@ -31653,6 +33424,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "data", + "id": "def-common.SHARD_DELAY_AGG_NAME", + "type": "string", + "tags": [], + "label": "SHARD_DELAY_AGG_NAME", + "description": [], + "signature": [ + "\"shard_delay\"" + ], + "path": "src/plugins/data/common/search/aggs/buckets/shard_delay.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "data", "id": "def-common.siblingPipelineType", diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 15b457e57a329..3cf065a957729 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3132 | 33 | 2429 | 23 | +| 3211 | 33 | 2508 | 23 | ## Client diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 1ed2c22bd9856..6fca87db82f91 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 2ca0a8d2f0ba2..9e4d3deac15c4 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 5277f71f1d3dd..cf43b6fa9dd9e 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index d47a4f9daa55f..a5ea60ca6db86 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index ce2cd5119ddb0..797cd5596c31f 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 826b95556b7c5..ec45435a4e875 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 849c6c1c88fc4..430ba54813520 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index cebc81eaa7f7e..30143657a7b1e 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index b7d3c963abf2b..95bc923cc9da0 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 2fa566f082091..8f51330d8bc6d 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 01d16f604fd83..7263ed936315a 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index ac1db5c87cca3..f5d8586e5194b 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 74f016f3f94c8..326d612509b6c 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index 6e5dd4305864a..e5a8bb47a0520 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index 0df7233b53270..23ae523bade64 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 50d60e1a1f2c9..d5982b5a2a865 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 73847652b7034..705fa73b04c1d 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 0fbe81013238d..53b40226f0d78 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 54c128a3a1609..51a1fd22bc039 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index cf24875c1242d..c23d6a727bb38 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index 45b092ac58bdf..1196f07945026 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 2c755fa2fc81f..046b3c31f107b 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index 8b20c473d5514..9a3e6bd0dc825 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index bce9a08357803..76fd8a4068f19 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index cdc56d029f4b0..337717de0a65a 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 5b04089ad0f1a..32c3971bd0909 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index 1a25a412c39d0..ca6a5be21ec3a 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index a56fc83dd26a3..90854571dc71c 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 120617e54501e..898224f9aba1a 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index 444c05f6ceb5a..f6686201cb138 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index 213d1edd926fd..c090283f69746 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 2d96611dfeb39..cc0dfccc59154 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index d98963fe4d66a..116d58a6218b9 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index 36a7e6d4685c1..dbb19f977cc78 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 044c6e58328ae..31c1b78e94389 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.mdx b/api_docs/files.mdx index 7b6e21054a85e..149bec1a8acb5 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/fleet.devdocs.json b/api_docs/fleet.devdocs.json index 66f288b6ca432..a35508ec3930f 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -9086,6 +9086,20 @@ "path": "x-pack/plugins/fleet/common/authz.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.FleetAuthz.packagePrivileges", + "type": "Object", + "tags": [], + "label": "packagePrivileges", + "description": [], + "signature": [ + "{ [packageName: string]: { actions: { [key: string]: { executePackageAction: boolean; }; }; }; } | undefined" + ], + "path": "x-pack/plugins/fleet/common/authz.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -14188,6 +14202,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.ENDPOINT_PRIVILEGES", + "type": "Array", + "tags": [], + "label": "ENDPOINT_PRIVILEGES", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/fleet/common/constants/authz.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.EsAssetReference", diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 374d04b3e52e5..173f9f76092f4 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Fleet](https://github.com/orgs/elastic/teams/fleet) for questions regar | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 986 | 3 | 886 | 17 | +| 988 | 3 | 888 | 17 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 6c708f5ad470c..c689891e7444b 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index 604c7acbae0fd..5dfb91864c060 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index 68678af8f9ee5..62db97259ee59 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 1621311ffc7df..87bd3e83a63b9 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 407e7732ad947..eee8cda64e245 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 39d7876c10861..fd32cbab99193 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index a4aaec9817ae3..00175e67b30b5 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index a3fecbf61097d..33ee5123bb5cd 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 10ea930d88d01..bf08287ddc424 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index f15645592bed5..d4cb51aa5139f 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 18c46827b5775..389117150bd55 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx index d6d2fc6b2ce87..749a781cf0e47 100644 --- a/api_docs/kbn_alerts.mdx +++ b/api_docs/kbn_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts title: "@kbn/alerts" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts'] --- import kbnAlertsObj from './kbn_alerts.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index 0c6d93303734f..c0f7031e47a7a 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index fb40c3a6d1ebb..1595bab913e80 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index bb08718097b9f..ba7823ee64ac1 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index a2a61c275f4e5..105ff1b565b71 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index baf43cc906d1c..ef9a534fa3470 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 287bfd2ff5d81..6a263b0defbb9 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 8d826cc0958c1..defb49cbe69ea 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 0b76528343988..0a80a8f9d7c64 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 2cbf87044cd77..f87f80a173bee 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index 234d6104f601c..465473d3ef7cd 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index 46f49b9660db4..8bc8181b1c666 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index 1459132fe2c97..26ac1ad8da546 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 68990474b42c1..79c65aec69dbb 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 24a14d2aef1c2..4b5645cc4b132 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index c589ecba7e2df..fb74c109385e8 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index fed58f168d8be..6dfdbdc6a7e19 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index 08c49c3eb81aa..e5787da85b661 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index 92b4083a9bb43..9f30996b585d7 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 805071e48d605..97256b7516108 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list.mdx b/api_docs/kbn_content_management_table_list.mdx index ab69cd4d6a69f..12779749648df 100644 --- a/api_docs/kbn_content_management_table_list.mdx +++ b/api_docs/kbn_content_management_table_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list title: "@kbn/content-management-table-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list'] --- import kbnContentManagementTableListObj from './kbn_content_management_table_list.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 697f32d5a32c1..89fc744b1c703 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index 909e9933df071..bad36ac54b215 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index d89fb32724da4..5db786b7754f0 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 00ec4b5ef0b87..0141718a2ccd2 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 6d43aaea5d4a8..2d21be701e133 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index ca795d6887d01..1dc30aff04e5d 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index feb8249b263af..7e999f21f3e1a 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 6353b853b75da..c957561aa4eca 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index 4ccd910e9c854..6ba6188770d4c 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index 57ca826ee2790..09bb2339c9782 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index 6edee369dba21..a036a5bb51c0e 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index eafdf4b402b44..42db1a2581375 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index cc36f15b1ebc3..cd0875458844d 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 96b693c7772ed..468ebd13bf1b3 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index 0bdb1a2fd6024..c986f9acf0ef3 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index 3a8a11486b91d..d6cd91c67140a 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index 73fa79e82d723..7a6ba37310aaf 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index 83cb7a3a226b7..24b234f7f811d 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index db2f37634a36a..c5359e8345a38 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 6a9175ac9e6d8..b847a51cd7a0d 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 6791dfa422f31..cc02f6073ea91 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 7ddb5fa99580a..b1d46f4e5fe8c 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index b282941a27a0e..ee601e6352e35 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index aa9990a0b855c..6eec129fe2615 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index cd0ed8c810ef9..983047e82691a 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index daa193327e0b1..0190b56cf9739 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index 156fdda6dc807..60d444ced08da 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index b093eedb0c3a9..e9f8e03e21a24 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index ad30901f82030..cd76ecc1e5de7 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index 9d57d94f5a07c..adcf635bd0895 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index 1e8cf6217f00c..d8f11b0a78906 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index d0f14840512f3..04891d7eee772 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index 2bc0611b6ba88..a211477391f89 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index bf2faaedb09e5..cabbd8bcaf86c 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 2b10ea2601b1e..c6a7f734219d8 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index c3b9a1bbceb2d..7af48bcbf5f1b 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index 137bb7f40b9d6..ca2a47bc99331 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index b1ec099e96222..5c6a4b84856c7 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index aabccea0ba2d9..dd0e97e30fc7c 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index 32511431d67ed..2d4f36ed093a2 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index b428f24f8a449..587243bb64061 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index 608f4b7dfd1d8..96b79793ed095 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index 154d3ddd0c6f7..d8cfe4d9f349d 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 4c8d0fe979c03..fe90efd441051 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index 865624983d3a9..e7b47436fa761 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index 85b0cd0b15092..8fa86908f719d 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index d9a881ae38e33..76ca7ae6c111b 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 19733f115b02c..3e17e9ed94637 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index 2d09cd0aedb2b..01d683396e2b7 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index 3cc3aee2a0d6e..891c8d8767547 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index 13da3a5ec6169..a935d019adeb4 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index d7651228361cf..04f71c530c9a5 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index 9e013dc8fe0e7..53f1d9fe670a0 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index 2a05b8a951bdd..f8ff0087dbbfc 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 5d4f4c33489ac..c93bb2546524b 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index 223d1f48f38d7..6121b09f8c1b4 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index 394b7517d61f8..49dffda39dcc6 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 9501a0ec85e8a..74c3216b75ebc 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index 5c499f63e4164..50ebcbe4058b9 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 5e53a8611610d..c7649dcf597cf 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index aaaaa91454760..7e8106d7e3c66 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index a516c58bfc4c7..32e6b9184dbe1 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index e11acda897e25..4e5cbf65974a7 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index bd3eae858db51..93c620cca65a7 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index c8dfa3b6b28a6..13734215059b0 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser.mdx b/api_docs/kbn_core_injected_metadata_browser.mdx index 5a7f145e9f9f8..08dbe296b4323 100644 --- a/api_docs/kbn_core_injected_metadata_browser.mdx +++ b/api_docs/kbn_core_injected_metadata_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser title: "@kbn/core-injected-metadata-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser'] --- import kbnCoreInjectedMetadataBrowserObj from './kbn_core_injected_metadata_browser.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 69a77c8c4f96f..b88675d50c204 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index 62c5882d56a6a..fc53dc77eda1c 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index a3850e7f23e98..2526e6dc2b6b9 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index 093ac2d0c1a13..8b557e2e502b2 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index d9e591359ab58..74231286ffe09 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 51db906dd4743..a4e8cb4241bef 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 86cc637cdf6a8..f56eecbd69552 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index c7464858aae94..2067fdbc72fda 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index eb3c5ebe3c362..a7e7a11ae05ea 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index 1be122dec707e..febc5d3038933 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index 6af293e6fdae8..47cc583e2df0e 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index bf82eb7970b55..9e16d8304decd 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index a696921789baf..5db83c7383b67 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index b69a8a4a78e95..8fafac5831639 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index d6c392f44c42f..9fbffa9c5df93 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index ce324b10707bb..d253278b97f15 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index e92985c2847d0..5dd3d790c3eaa 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index b9d2d41ad3c6f..ed0c7c4e240ce 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index 1b3c4b7c97006..5c44022f60828 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index c6c249f893682..ef4b9a440b592 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index adfde3eb57935..559df72a076e4 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index e5b665a749de4..6160c98032fef 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index b9857a22a4aa5..5765d85478d62 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index d9d2d411504ec..09d09fe708575 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index 16067815b76ab..5416044cac958 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index ee51fe5d501b1..962d718e0042b 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index 2621608fb4385..07d55b8bdc9ad 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index 95e59f965436e..f31451fde9e77 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index 47b96c57a4d99..97d1f20eba7af 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index eb621d99fa2e3..1c1ec6407d249 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_internal.mdx b/api_docs/kbn_core_saved_objects_api_server_internal.mdx index de1c53c1af13d..678cf37d24e81 100644 --- a/api_docs/kbn_core_saved_objects_api_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-internal title: "@kbn/core-saved-objects-api-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-internal'] --- import kbnCoreSavedObjectsApiServerInternalObj from './kbn_core_saved_objects_api_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index bd3799e8d44b0..da93d1e0b8552 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index bfae0d9378d37..73d6c70c1a9ac 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index ebb26601a4699..2b499a47657b8 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index 09baa5daf0aa1..fcec7c16e5f85 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index fcaebe64cd996..197152a6dae02 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index 0fde59191c733..80320e7312485 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index ff0a3055cf443..63fa1e47ac1bf 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index 3b4570f7c036b..127679f751476 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index a76df96a31831..f633f52c6174d 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index c70c8ca947e65..bc446d004b249 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index 66e637f6c3f6a..ecbb1447d1e5c 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index ba2752d9b3405..c694b3c9f6584 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 26a690d05280a..39099151043aa 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index 3260ae2e31a22..73e0b05504386 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index 441ed1b3c2600..0012db4e553fb 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index cd33f1d1f0502..1ef8c6abfc97a 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 06e62aeef187e..7c9440c92271b 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index 7151aacf2084d..bd5556b6ce877 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index 354e4d93b9370..364b20ab80d66 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index d5992e345f9b5..aa7990a556b57 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index d1e1d00ed8ed0..d4a0a789572fb 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index 93528eb3bfbf1..826ee5d1b3459 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index 6ba05ca53fd8a..e68a43d0ce9fe 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 6275d70c17032..8c938db4082e1 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 625810a6cc773..0cbb8955ac42e 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index cd3eda1a2203b..67a42c6099d97 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index 2c9f352ccd8d4..791006e8cea6b 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 1e513b3ad0f7e..b1ae46812b1d2 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index dd9cb93ed4e4e..ef778256b7997 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index 24945054119c8..545b597ef2b8b 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index b3a148ab80f22..99402f8c657ce 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index d492abb2efc12..a5081a8a512eb 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index a01955f4262bf..b490e18b99885 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index a33d80bd4cd2f..01b13b900344a 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index 50a975d51e964..90ea1b666c8aa 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index 7a7927ec2f4ae..a9fb17b3cd06f 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index 03d3a1246b3ce..0afac1bca8d36 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 8c0d3ce762be5..d2e4558115131 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index d1722a8bf5614..42e02f9783509 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index 6aefed8871217..5169411f49a2a 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index c1b894325cd54..5872d911b8f47 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 80533016c1c97..8f8299fb3972b 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 3258c848c7d36..93faea017a0fb 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index 61fbb56f1a171..f29fe40eb21d1 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 78e17c86e33d3..2d7b26292e0e8 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index b2bbf6fdc00b0..da7db13bb38b1 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index a7e2be8113fac..3d7f8993dd9fb 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index 572d41cd16fa3..db9354454f22f 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 3ab838c7557e4..5bee2fdbf5f66 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 613b02bd58925..f6c2a308c267e 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 2e71f587b78f1..52dcd1a4217e9 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 6354505d65347..e8d91e141f195 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 9c7b4486fe151..93882b49ca42b 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 85e406eb02adb..5955c7f01158f 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_get_repo_files.mdx b/api_docs/kbn_get_repo_files.mdx index a0c6fe024ffe7..e50741bdb3a60 100644 --- a/api_docs/kbn_get_repo_files.mdx +++ b/api_docs/kbn_get_repo_files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-get-repo-files title: "@kbn/get-repo-files" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/get-repo-files plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/get-repo-files'] --- import kbnGetRepoFilesObj from './kbn_get_repo_files.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index ece22c3ff7096..24eedfb0387a4 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 91b1a139c1a9c..1d4fddcc02250 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 0f7cef5022e7c..59d37e8a5d09f 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index 263994dcecb74..5e218789e57f1 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index c4721c56b46c4..15647319a90f0 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 428a6a2fd3411..56039851af766 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 1e3755ae194ca..807a82e9cbff7 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 0c90d5d563dfe..dfb4aea12e2d7 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 37eb518ebfb80..28487fab71400 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.devdocs.json b/api_docs/kbn_journeys.devdocs.json index d34c75a453efb..601334a03f8e8 100644 --- a/api_docs/kbn_journeys.devdocs.json +++ b/api_docs/kbn_journeys.devdocs.json @@ -792,7 +792,7 @@ "signature": [ "(step: ", "AnyStep", - ", screenshot: Buffer) => Promise" + ", screenshot: Buffer, fullscreenScreenshot: Buffer) => Promise" ], "path": "packages/kbn-journeys/journey/journey_screenshots.ts", "deprecated": false, @@ -827,6 +827,21 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/journeys", + "id": "def-server.JourneyScreenshots.addError.$3", + "type": "Object", + "tags": [], + "label": "fullscreenScreenshot", + "description": [], + "signature": [ + "Buffer" + ], + "path": "packages/kbn-journeys/journey/journey_screenshots.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true } ], "returnComment": [] @@ -841,7 +856,7 @@ "signature": [ "(step: ", "AnyStep", - ", screenshot: Buffer) => Promise" + ", screenshot: Buffer, fullscreenScreenshot: Buffer) => Promise" ], "path": "packages/kbn-journeys/journey/journey_screenshots.ts", "deprecated": false, @@ -876,6 +891,21 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "@kbn/journeys", + "id": "def-server.JourneyScreenshots.addSuccess.$3", + "type": "Object", + "tags": [], + "label": "fullscreenScreenshot", + "description": [], + "signature": [ + "Buffer" + ], + "path": "packages/kbn-journeys/journey/journey_screenshots.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true } ], "returnComment": [] @@ -888,7 +918,7 @@ "label": "get", "description": [], "signature": [ - "() => { path: string; type: \"success\" | \"failure\"; title: string; filename: string; }[]" + "() => { path: string; fullscreenPath: string; type: \"success\" | \"failure\"; title: string; filename: string; fullscreenFilename: string; }[]" ], "path": "packages/kbn-journeys/journey/journey_screenshots.ts", "deprecated": false, diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index a8348f70822d4..01244be181bf2 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 62 | 0 | 57 | 5 | +| 64 | 0 | 59 | 5 | ## Server diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 10fae76d04b1e..7d70916d448e4 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 7ff3186afb099..63d9dc96362af 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 34569da5d7028..6b1049cee9be2 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 8e29bd95f0456..a175904d02573 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 9e17319c10337..ca5e2566d884c 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index cceee4bc2eb2e..78c0d9fbb8369 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 78eda05c5b44f..ffdc48a0fb0d3 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index d197afe74668f..a1f168d3fc91d 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index abf0f29de3277..7da86649ddf39 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 52929cddf140f..29b3596a8bc29 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index 6a156288e0d69..fb729fc0747ed 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index 053dfb0beb5d5..54d57200bd5a1 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 86d5c3669cd80..ba91201a52c6c 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index cf2e35c77d2a7..493ca235ab7a9 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index 125bda46f869c..b16b234ee0f50 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index b950dc5c5fe54..f7d3bada225b9 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index eca63370271b2..65a1a0d424f15 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 08f9cfb7699d9..ef453ad073e4f 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 771ef4c3664dd..f441cc10aa506 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index bc9e95fce1374..c81350b38632b 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 2d5f008c026bb..8e6bdc15f9807 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.devdocs.json b/api_docs/kbn_securitysolution_io_ts_alerting_types.devdocs.json index e313879791dd2..b42cebbc4fb84 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.devdocs.json +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.devdocs.json @@ -227,7 +227,7 @@ "label": "Language", "description": [], "signature": [ - "\"eql\" | \"kuery\" | \"lucene\"" + "\"eql\" | \"lucene\" | \"kuery\"" ], "path": "packages/kbn-securitysolution-io-ts-alerting-types/src/language/index.ts", "deprecated": false, @@ -242,7 +242,7 @@ "label": "LanguageOrUndefined", "description": [], "signature": [ - "\"eql\" | \"kuery\" | \"lucene\" | undefined" + "\"eql\" | \"lucene\" | \"kuery\" | undefined" ], "path": "packages/kbn-securitysolution-io-ts-alerting-types/src/language/index.ts", "deprecated": false, @@ -660,7 +660,7 @@ "label": "ThreatLanguage", "description": [], "signature": [ - "\"eql\" | \"kuery\" | \"lucene\" | undefined" + "\"eql\" | \"lucene\" | \"kuery\" | undefined" ], "path": "packages/kbn-securitysolution-io-ts-alerting-types/src/threat_mapping/index.ts", "deprecated": false, @@ -675,7 +675,7 @@ "label": "ThreatLanguageOrUndefined", "description": [], "signature": [ - "\"eql\" | \"kuery\" | \"lucene\" | undefined" + "\"eql\" | \"lucene\" | \"kuery\" | undefined" ], "path": "packages/kbn-securitysolution-io-ts-alerting-types/src/threat_mapping/index.ts", "deprecated": false, diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 0638d5f8bf083..4066f50c33520 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index b1a1a3fc64da3..720ede9fa9e87 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index b03d18fec4ced..f2220252df9f4 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index 7c360b9333e54..4ddd805beceec 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index f18f2b1aead14..837b102f35b7c 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index b7433466578b1..5e117e7fdd5ff 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 2654598d4dcc9..a0d87f4a94bbb 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 91475331ebad8..a42cbdfe87318 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 79adceb20aeae..c978507107c7d 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index a5bb0c13967e9..d7cd694497c7f 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index c0b27f428d0b7..c6c4f053e9525 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 1c193a552796d..fc18c7757d1d9 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index b521420154f80..2c9d51b468868 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index f5eb308795aca..1a40ade046a8a 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 42a0beca9e7ea..6d9064ab9d9ac 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index 2df8ddd83c85d..e28b92febd738 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index b305a644f9271..3515b5ee35bf4 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index f0c440f375743..ba2f64392e72c 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index 82f90f66491df..6942dcbd38fca 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index bccf44bcdb7d1..69a6794fbccd5 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 1de00675c4406..a8465df7126e6 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index a74f39651be04..9e930a85deb81 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index 357f925da370f..d96c9079cf5fd 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index 8752e5a774370..86595fb7cfb1f 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index d939e7321db44..9132796651764 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index e914e2f8a891c..e5b6a7845bbeb 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index e193d62f4ee6b..09f6ed5cf1fa0 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index dc7bc516665c5..ef0e7d2b60bf3 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index bbd8f3cca0e03..43ef0de76bb28 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index ca8e953699da6..eecbe82f148c7 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index 3dfe50049855e..001790b9086e2 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index f20ef222d9e8e..42efbc3a489cc 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index f1dfbd73ce704..71404d9e00a6f 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 5bbf41024b26d..a24b3d7d985a9 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index cd7b6bfac4e7c..b833764dfacbc 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index b12315abf9fc6..bf5525e9d8ea8 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index b7e0841ee703d..16c867044187d 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 9c495c4aa7743..ef2f54962c583 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index 7b767e626b7c9..8fa73d4c68dad 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_sort_package_json.mdx b/api_docs/kbn_sort_package_json.mdx index ab4be4010f901..8a049d4872b72 100644 --- a/api_docs/kbn_sort_package_json.mdx +++ b/api_docs/kbn_sort_package_json.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-package-json title: "@kbn/sort-package-json" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-package-json plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-package-json'] --- import kbnSortPackageJsonObj from './kbn_sort_package_json.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 43a7444c0c030..f1ba970a48042 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index 020326e9a0c53..2ff62c2d04f35 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index 72fb4fa068c7e..b77c7bfc44e93 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 140c6462d2e78..f81111a502799 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 229feacde942d..eaf2d94c9a05d 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 691a582e60a70..96f5d4d6ab2a7 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index e4f3ab2faf109..db3273ea8883f 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 1bfcb9c72707a..fe4e9cade439f 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer.mdx b/api_docs/kbn_type_summarizer.mdx index 8910379b7ebe3..9744d7e40941f 100644 --- a/api_docs/kbn_type_summarizer.mdx +++ b/api_docs/kbn_type_summarizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer title: "@kbn/type-summarizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer'] --- import kbnTypeSummarizerObj from './kbn_type_summarizer.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer_core.mdx b/api_docs/kbn_type_summarizer_core.mdx index 2f874f70f25c7..5bf8d7c641755 100644 --- a/api_docs/kbn_type_summarizer_core.mdx +++ b/api_docs/kbn_type_summarizer_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer-core title: "@kbn/type-summarizer-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer-core plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer-core'] --- import kbnTypeSummarizerCoreObj from './kbn_type_summarizer_core.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 0d8d08d774ef7..24144f46636bc 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 09f25106acbcf..fe7f2f02b8192 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 85eb0e283b7a7..7855bb68d62db 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 65c18d1961171..5adb3b961a126 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index c6acb5b0fbc56..879d594892e8b 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 5ec4f40c0dae5..13a63d5a655f6 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index ee036d3e7c04b..17c5bc67927ee 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 7471c9772caa9..661dda80a0227 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index fffdeb850c4c8..3a54ee39d7116 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 4873a6d3d2afc..62af983d79330 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 3f7dbbba241a9..c101218ee3f45 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index d183dd7fce455..e6eb90ca75ba8 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 0fbef0861888c..745b2e56c1c9d 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index f942edc6beb32..3aa129254bb54 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index 0b0b6996ac826..f4406dfe719d8 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index e8ff8b692628b..6aa4f4f225193 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 13c0aab065080..92b5f7e806788 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index b5d5c37c7c2d4..2e5da06f70dd9 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index a2e0b0c3660d1..a2dd183ea48bc 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index d9b70e1d9a354..55b3f0eff7da0 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index e5a8151f36d80..dbf1d15ca06df 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index 3ceb6a607ee4f..16eb11d15bbf2 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index b6fa1bd6b9520..e9f3d869a2077 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 28d4231ae4121..95e0ce94137e7 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 625317137d6c3..7d399eaa890b1 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -7737,13 +7737,35 @@ "section": "def-server.ObservabilityRouteCreateOptions", "text": "ObservabilityRouteCreateOptions" }, + "> | undefined; \"GET /api/observability/slos/{id}\"?: ", + "ServerRoute", + "<\"GET /api/observability/slos/{id}\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ id: ", + "StringC", + "; }>; }>, ", + { + "pluginId": "observability", + "scope": "server", + "docId": "kibObservabilityPluginApi", + "section": "def-server.ObservabilityRouteHandlerResources", + "text": "ObservabilityRouteHandlerResources" + }, + ", { id: string; } & { name: string; description: string; indicator: { type: \"slo.apm.transaction_duration\"; params: { environment: string; service: string; transaction_type: string; transaction_name: string; 'threshold.us': number; }; } | { type: \"slo.apm.transaction_error_rate\"; params: { environment: string; service: string; transaction_type: string; transaction_name: string; } & { good_status_codes?: (\"2xx\" | \"3xx\" | \"4xx\" | \"5xx\")[] | undefined; }; }; time_window: { duration: string; is_rolling: true; }; budgeting_method: \"occurrences\"; objective: { target: number; }; }, ", + { + "pluginId": "observability", + "scope": "server", + "docId": "kibObservabilityPluginApi", + "section": "def-server.ObservabilityRouteCreateOptions", + "text": "ObservabilityRouteCreateOptions" + }, "> | undefined; \"POST /api/observability/slos\"?: ", "ServerRoute", "<\"POST /api/observability/slos\", ", "TypeC", "<{ body: ", - "IntersectionC", - "<[", "TypeC", "<{ name: ", "StringC", @@ -7841,13 +7863,7 @@ "TypeC", "<{ target: ", "NumberC", - "; }>; }>, ", - "PartialC", - "<{ settings: ", - "PartialC", - "<{ destination_index: ", - "StringC", - "; }>; }>]>; }>, ", + "; }>; }>; }>, ", { "pluginId": "observability", "scope": "server", @@ -7949,13 +7965,35 @@ "section": "def-server.ObservabilityRouteCreateOptions", "text": "ObservabilityRouteCreateOptions" }, + "> | undefined; \"GET /api/observability/slos/{id}\"?: ", + "ServerRoute", + "<\"GET /api/observability/slos/{id}\", ", + "TypeC", + "<{ path: ", + "TypeC", + "<{ id: ", + "StringC", + "; }>; }>, ", + { + "pluginId": "observability", + "scope": "server", + "docId": "kibObservabilityPluginApi", + "section": "def-server.ObservabilityRouteHandlerResources", + "text": "ObservabilityRouteHandlerResources" + }, + ", { id: string; } & { name: string; description: string; indicator: { type: \"slo.apm.transaction_duration\"; params: { environment: string; service: string; transaction_type: string; transaction_name: string; 'threshold.us': number; }; } | { type: \"slo.apm.transaction_error_rate\"; params: { environment: string; service: string; transaction_type: string; transaction_name: string; } & { good_status_codes?: (\"2xx\" | \"3xx\" | \"4xx\" | \"5xx\")[] | undefined; }; }; time_window: { duration: string; is_rolling: true; }; budgeting_method: \"occurrences\"; objective: { target: number; }; }, ", + { + "pluginId": "observability", + "scope": "server", + "docId": "kibObservabilityPluginApi", + "section": "def-server.ObservabilityRouteCreateOptions", + "text": "ObservabilityRouteCreateOptions" + }, "> | undefined; \"POST /api/observability/slos\"?: ", "ServerRoute", "<\"POST /api/observability/slos\", ", "TypeC", "<{ body: ", - "IntersectionC", - "<[", "TypeC", "<{ name: ", "StringC", @@ -8053,13 +8091,7 @@ "TypeC", "<{ target: ", "NumberC", - "; }>; }>, ", - "PartialC", - "<{ settings: ", - "PartialC", - "<{ destination_index: ", - "StringC", - "; }>; }>]>; }>, ", + "; }>; }>; }>, ", { "pluginId": "observability", "scope": "server", diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index ede6a978b1972..afdb6cd4fbb3c 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 33f2325a9d42b..a634c2e2206cc 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index f52aa4bd15337..00a92aa5b8132 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 31641 | 179 | 21224 | 998 | +| 31772 | 179 | 21354 | 1002 | ## Plugin Directory @@ -47,7 +47,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 103 | 0 | 84 | 1 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 144 | 0 | 139 | 10 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 52 | 0 | 51 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3132 | 33 | 2429 | 23 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3211 | 33 | 2508 | 23 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | This plugin provides the ability to create data views via a modal flyout inside Kibana apps | 15 | 0 | 7 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Reusable data view field editor across Kibana | 60 | 0 | 30 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data view management app | 2 | 0 | 2 | 0 | @@ -81,7 +81,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 5 | 249 | 3 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 | | | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 263 | 0 | 15 | 2 | -| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 986 | 3 | 886 | 17 | +| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 988 | 3 | 888 | 17 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | globalSearchProviders | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | @@ -175,7 +175,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the vega visualization. Is the elastic version of vega and vega-lite libraries. | 2 | 0 | 2 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the vislib visualizations. These are the classical area/line/bar, pie, gauge/goal and heatmap charts. We want to replace them with elastic-charts. | 26 | 0 | 25 | 1 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the new xy-axis chart using the elastic-charts library, which will eventually replace the vislib xy-axis charts including bar, area, and line. | 53 | 0 | 50 | 5 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 631 | 12 | 602 | 14 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 679 | 12 | 649 | 18 | | watcher | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | ## Package Directory @@ -367,7 +367,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | App Services | - | 35 | 4 | 35 | 0 | | | [Owner missing] | - | 20 | 0 | 20 | 2 | | | [Owner missing] | - | 13 | 0 | 13 | 0 | -| | [Owner missing] | - | 62 | 0 | 57 | 5 | +| | [Owner missing] | - | 64 | 0 | 59 | 5 | | | [Owner missing] | - | 96 | 0 | 95 | 0 | | | Kibana Core | - | 30 | 0 | 5 | 37 | | | Kibana Core | - | 8 | 0 | 8 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 8bd637653c617..971ed39aee0ed 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index cb52176e574d2..8d2be8c0f9dd7 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 41f98b3aa5474..916ffb9e1e4e0 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 9de91bdd316fe..aa8b69de45190 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index e881b7e1d8d1d..7ecab5c862bf0 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index b3f7b8baeea0d..42e1a51c2ed9f 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 84762f6833dfc..4c4a4a4be8d7f 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 5297a1c4dfeab..d180b9df678f8 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index b48dac4d77ca7..d8ee1bd800f99 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index da2c95cf361b5..a57ba63fec003 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 50cc4890609aa..785d7f8ea6a32 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index d308998e912cf..bf65a9aa5c648 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index ee3015be49b3b..5e294d8d6ea59 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index 1ab87605dcb7b..4c436c7b23e66 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index b978b8ae17757..5bc1fcd058003 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 43109981e1bd7..952c20eac620f 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index 1d69c84ad5c82..8ad8f2f5fe218 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -58,7 +58,7 @@ "label": "experimentalFeatures", "description": [], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly disableIsolationUIPendingStatuses: boolean; readonly pendingActionResponsesWithAck: boolean; readonly policyListEnabled: boolean; readonly policyResponseInFleetEnabled: boolean; readonly threatIntelligenceEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly responseActionsConsoleEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly disableIsolationUIPendingStatuses: boolean; readonly pendingActionResponsesWithAck: boolean; readonly policyListEnabled: boolean; readonly policyResponseInFleetEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly responseActionsConsoleEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointRbacEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/public/plugin.tsx", "deprecated": false, @@ -1061,7 +1061,7 @@ "label": "ConfigType", "description": [], "signature": [ - "Readonly<{} & { signalsIndex: string; maxRuleImportExportSize: number; maxRuleImportPayloadBytes: number; maxTimelineImportExportSize: number; maxTimelineImportPayloadBytes: number; alertMergeStrategy: \"allFields\" | \"missingFields\" | \"noFields\"; alertIgnoreFields: string[]; enableExperimental: string[]; packagerTaskInterval: string; prebuiltRulesFromFileSystem: boolean; prebuiltRulesFromSavedObjects: boolean; }> & { experimentalFeatures: Readonly<{ tGridEnabled: boolean; tGridEventRenderedViewEnabled: boolean; excludePoliciesInFilterEnabled: boolean; kubernetesEnabled: boolean; disableIsolationUIPendingStatuses: boolean; pendingActionResponsesWithAck: boolean; policyListEnabled: boolean; policyResponseInFleetEnabled: boolean; threatIntelligenceEnabled: boolean; previewTelemetryUrlEnabled: boolean; responseActionsConsoleEnabled: boolean; insightsRelatedAlertsByProcessAncestry: boolean; extendedRuleExecutionLoggingEnabled: boolean; socTrendsEnabled: boolean; responseActionsEnabled: boolean; }>; }" + "Readonly<{} & { signalsIndex: string; maxRuleImportExportSize: number; maxRuleImportPayloadBytes: number; maxTimelineImportExportSize: number; maxTimelineImportPayloadBytes: number; alertMergeStrategy: \"allFields\" | \"missingFields\" | \"noFields\"; alertIgnoreFields: string[]; enableExperimental: string[]; packagerTaskInterval: string; prebuiltRulesFromFileSystem: boolean; prebuiltRulesFromSavedObjects: boolean; }> & { experimentalFeatures: Readonly<{ tGridEnabled: boolean; tGridEventRenderedViewEnabled: boolean; excludePoliciesInFilterEnabled: boolean; kubernetesEnabled: boolean; disableIsolationUIPendingStatuses: boolean; pendingActionResponsesWithAck: boolean; policyListEnabled: boolean; policyResponseInFleetEnabled: boolean; previewTelemetryUrlEnabled: boolean; responseActionsConsoleEnabled: boolean; insightsRelatedAlertsByProcessAncestry: boolean; extendedRuleExecutionLoggingEnabled: boolean; socTrendsEnabled: boolean; responseActionsEnabled: boolean; endpointRbacEnabled: boolean; }>; }" ], "path": "x-pack/plugins/security_solution/server/config.ts", "deprecated": false, diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 12f05e5363bc6..9cf5459a07a3e 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index b44a921a532cb..23f8e18b5e278 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index a9333634f6450..7ba452349a66b 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 39bb856edb320..194b818f081bf 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 8614e0abbad77..95118ea8b8058 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index fbfeb304d9bab..b3467e6a698dc 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index 0941e34da7c6b..aabbd1805b61d 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 268f95227b6b2..d35966ac57c9c 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index 8710f593cbf06..1dbef1ee43f39 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index b8aacfc863f72..438e8d307b1de 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index 42d0c24ed78a8..f032f6eee5e0a 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index b42450f650ec3..0b1523b1a10d3 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 0604fc8cf5698..b584556618afe 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.devdocs.json b/api_docs/timelines.devdocs.json index be005c7cd4081..5875aa47c1309 100644 --- a/api_docs/timelines.devdocs.json +++ b/api_docs/timelines.devdocs.json @@ -6073,7 +6073,7 @@ "label": "language", "description": [], "signature": [ - "\"eql\" | \"kuery\" | \"lucene\"" + "\"eql\" | \"lucene\" | \"kuery\"" ], "path": "x-pack/plugins/timelines/common/search_strategy/timeline/events/all/index.ts", "deprecated": false, diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 9791e2787c44a..14ef93c594cc2 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index ec5f484f4641c..b66dc03b52acd 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 541b2194d3f33..0a3cbb630285f 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 0905d751b5fa1..2a01df283087a 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index b3fd83a428f3a..f46cdf9d62ee1 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_field_list.mdx b/api_docs/unified_field_list.mdx index 16370d522a392..f70e303ebe4d7 100644 --- a/api_docs/unified_field_list.mdx +++ b/api_docs/unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedFieldList title: "unifiedFieldList" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedFieldList plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedFieldList'] --- import unifiedFieldListObj from './unified_field_list.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index bdf37515d75f1..2e10e0a54e2cd 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 62acbd2c862fd..18b782fa7081b 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 245f43ae0e848..7a9ded502796d 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index f6a52d69a1e43..34bbb721a3728 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index 38b3afeff9e02..c3afd8d86827c 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 5454be9ab6cd1..271d79629a0b7 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index 58b5bd6f2338b..f28ab39c716fb 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index f90f2436dcc85..32a96558c72f8 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 0238df60ca4da..827eb1f6f0969 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index 03c32627ef241..d9fc5b663679c 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index af604e573f216..e8dfbf76d6ffa 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index 52000bc18ca5e..c962200fe1fdc 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index 1cff837940b2b..abe648760bf12 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 2a1f1ce82cb39..4260c1aaeb253 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.devdocs.json b/api_docs/vis_type_xy.devdocs.json index 5468fa97bdb7a..e9d569dcbde48 100644 --- a/api_docs/vis_type_xy.devdocs.json +++ b/api_docs/vis_type_xy.devdocs.json @@ -825,12 +825,20 @@ "Omit<", { "pluginId": "visualizations", - "scope": "public", + "scope": "common", "docId": "kibVisualizationsPluginApi", - "section": "def-public.SchemaConfig", + "section": "def-common.SchemaConfig", "text": "SchemaConfig" }, - ", \"params\"> & { params: {} | ", + "<", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.SupportedAggregation", + "text": "SupportedAggregation" + }, + ">, \"params\"> & { params: {} | ", { "pluginId": "visualizations", "scope": "common", diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index 2d2db30e66054..f03c9b37afbb4 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.devdocs.json b/api_docs/visualizations.devdocs.json index 086c698e01e8e..adc8f3022cb1a 100644 --- a/api_docs/visualizations.devdocs.json +++ b/api_docs/visualizations.devdocs.json @@ -97,21 +97,21 @@ "label": "navigateToLens", "description": [], "signature": [ - "((params?: ", + "((vis?: ", { "pluginId": "visualizations", - "scope": "common", + "scope": "public", "docId": "kibVisualizationsPluginApi", - "section": "def-common.VisParams", - "text": "VisParams" + "section": "def-public.Vis", + "text": "Vis" }, - " | undefined, timeRange?: ", + " | undefined, timeFilter?: ", { "pluginId": "data", - "scope": "common", + "scope": "public", "docId": "kibDataQueryPluginApi", - "section": "def-common.TimeRange", - "text": "TimeRange" + "section": "def-public.TimefilterContract", + "text": "TimefilterContract" }, " | undefined) => Promise<", { @@ -126,8 +126,8 @@ "pluginId": "visualizations", "scope": "common", "docId": "kibVisualizationsPluginApi", - "section": "def-common.XYConfiguration", - "text": "XYConfiguration" + "section": "def-common.Configuration", + "text": "Configuration" }, "> | null> | undefined) | undefined" ], @@ -135,6 +135,36 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "visualizations", + "id": "def-public.BaseVisType.getExpressionVariables", + "type": "Function", + "tags": [], + "label": "getExpressionVariables", + "description": [], + "signature": [ + "((vis?: ", + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.Vis", + "text": "Vis" + }, + " | undefined, timeFilter?: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterContract", + "text": "TimefilterContract" + }, + " | undefined) => Promise>) | undefined" + ], + "path": "src/plugins/visualizations/public/vis_types/base_vis_type.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "visualizations", "id": "def-public.BaseVisType.icon", @@ -1981,6 +2011,76 @@ } ], "functions": [ + { + "parentPluginId": "visualizations", + "id": "def-public.getDataViewByIndexPatternId", + "type": "Function", + "tags": [], + "label": "getDataViewByIndexPatternId", + "description": [], + "signature": [ + "(indexPatternId: string | undefined, dataViews: ", + { + "pluginId": "dataViews", + "scope": "public", + "docId": "kibDataViewsPluginApi", + "section": "def-public.DataViewsServicePublic", + "text": "DataViewsServicePublic" + }, + ") => Promise<", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + }, + " | null>" + ], + "path": "src/plugins/visualizations/public/convert_to_lens/datasource.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-public.getDataViewByIndexPatternId.$1", + "type": "string", + "tags": [], + "label": "indexPatternId", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/visualizations/public/convert_to_lens/datasource.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.getDataViewByIndexPatternId.$2", + "type": "Object", + "tags": [], + "label": "dataViews", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "public", + "docId": "kibDataViewsPluginApi", + "section": "def-public.DataViewsServicePublic", + "text": "DataViewsServicePublic" + } + ], + "path": "src/plugins/visualizations/public/convert_to_lens/datasource.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-public.getFullPath", @@ -2030,7 +2130,7 @@ "section": "def-public.Vis", "text": "Vis" }, - ", { timeRange, timefilter }: ", + ", params: ", { "pluginId": "visualizations", "scope": "public", @@ -2072,7 +2172,7 @@ "id": "def-public.getVisSchemas.$2", "type": "Object", "tags": [], - "label": "{ timeRange, timefilter }", + "label": "params", "description": [], "signature": [ { @@ -3219,83 +3319,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "visualizations", - "id": "def-public.SchemaConfig", - "type": "Interface", - "tags": [], - "label": "SchemaConfig", - "description": [], - "path": "src/plugins/visualizations/public/vis_schemas.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "visualizations", - "id": "def-public.SchemaConfig.accessor", - "type": "number", - "tags": [], - "label": "accessor", - "description": [], - "path": "src/plugins/visualizations/public/vis_schemas.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "visualizations", - "id": "def-public.SchemaConfig.label", - "type": "string", - "tags": [], - "label": "label", - "description": [], - "path": "src/plugins/visualizations/public/vis_schemas.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "visualizations", - "id": "def-public.SchemaConfig.format", - "type": "Object", - "tags": [], - "label": "format", - "description": [], - "signature": [ - "{ id?: string | undefined; params?: ", - "SerializableRecord", - " | undefined; }" - ], - "path": "src/plugins/visualizations/public/vis_schemas.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "visualizations", - "id": "def-public.SchemaConfig.params", - "type": "Object", - "tags": [], - "label": "params", - "description": [], - "signature": [ - "SchemaConfigParams" - ], - "path": "src/plugins/visualizations/public/vis_schemas.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "visualizations", - "id": "def-public.SchemaConfig.aggType", - "type": "string", - "tags": [], - "label": "aggType", - "description": [], - "path": "src/plugins/visualizations/public/vis_schemas.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "visualizations", "id": "def-public.SerializedVis", @@ -4538,21 +4561,21 @@ "\nIf given, it will navigateToLens with the given viz params.\nEvery visualization that wants to be edited also in Lens should have this function.\nIt receives the current visualization params as a parameter and should return the correct config\nin order to be displayed in the Lens editor." ], "signature": [ - "((params?: ", + "((vis?: ", { "pluginId": "visualizations", - "scope": "common", + "scope": "public", "docId": "kibVisualizationsPluginApi", - "section": "def-common.VisParams", - "text": "VisParams" + "section": "def-public.Vis", + "text": "Vis" }, - " | undefined, timeRange?: ", + " | undefined, timeFilter?: ", { "pluginId": "data", - "scope": "common", + "scope": "public", "docId": "kibDataQueryPluginApi", - "section": "def-common.TimeRange", - "text": "TimeRange" + "section": "def-public.TimefilterContract", + "text": "TimefilterContract" }, " | undefined) => Promise<", { @@ -4567,8 +4590,8 @@ "pluginId": "visualizations", "scope": "common", "docId": "kibVisualizationsPluginApi", - "section": "def-common.XYConfiguration", - "text": "XYConfiguration" + "section": "def-common.Configuration", + "text": "Configuration" }, "> | null> | undefined) | undefined" ], @@ -4581,17 +4604,17 @@ "id": "def-public.VisTypeDefinition.navigateToLens.$1", "type": "Object", "tags": [], - "label": "params", + "label": "vis", "description": [], "signature": [ { "pluginId": "visualizations", - "scope": "common", + "scope": "public", "docId": "kibVisualizationsPluginApi", - "section": "def-common.VisParams", - "text": "VisParams" + "section": "def-public.Vis", + "text": "Vis" }, - " | undefined" + " | undefined" ], "path": "src/plugins/visualizations/public/vis_types/types.ts", "deprecated": false, @@ -4603,15 +4626,94 @@ "id": "def-public.VisTypeDefinition.navigateToLens.$2", "type": "Object", "tags": [], - "label": "timeRange", + "label": "timeFilter", "description": [], "signature": [ { "pluginId": "data", - "scope": "common", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterContract", + "text": "TimefilterContract" + }, + " | undefined" + ], + "path": "src/plugins/visualizations/public/vis_types/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisTypeDefinition.getExpressionVariables", + "type": "Function", + "tags": [], + "label": "getExpressionVariables", + "description": [ + "\nIf given, it will provide variables for expression params.\nEvery visualization that wants to add variables for expression params should have this method." + ], + "signature": [ + "((vis?: ", + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.Vis", + "text": "Vis" + }, + " | undefined, timeFilter?: ", + { + "pluginId": "data", + "scope": "public", + "docId": "kibDataQueryPluginApi", + "section": "def-public.TimefilterContract", + "text": "TimefilterContract" + }, + " | undefined) => Promise>) | undefined" + ], + "path": "src/plugins/visualizations/public/vis_types/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-public.VisTypeDefinition.getExpressionVariables.$1", + "type": "Object", + "tags": [], + "label": "vis", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "public", + "docId": "kibVisualizationsPluginApi", + "section": "def-public.Vis", + "text": "Vis" + }, + " | undefined" + ], + "path": "src/plugins/visualizations/public/vis_types/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisTypeDefinition.getExpressionVariables.$2", + "type": "Object", + "tags": [], + "label": "timeFilter", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "public", "docId": "kibDataQueryPluginApi", - "section": "def-common.TimeRange", - "text": "TimeRange" + "section": "def-public.TimefilterContract", + "text": "TimefilterContract" }, " | undefined" ], @@ -5639,13 +5741,13 @@ "misc": [ { "parentPluginId": "visualizations", - "id": "def-public.ACTION_CONVERT_TO_LENS", + "id": "def-public.ACTION_CONVERT_AGG_BASED_TO_LENS", "type": "string", "tags": [], - "label": "ACTION_CONVERT_TO_LENS", + "label": "ACTION_CONVERT_AGG_BASED_TO_LENS", "description": [], "signature": [ - "\"ACTION_CONVERT_TO_LENS\"" + "\"ACTION_CONVERT_AGG_BASED_TO_LENS\"" ], "path": "src/plugins/visualizations/public/triggers/index.ts", "deprecated": false, @@ -5654,17 +5756,47 @@ }, { "parentPluginId": "visualizations", - "id": "def-public.DEFAULT_LEGEND_SIZE", + "id": "def-public.ACTION_CONVERT_TO_LENS", "type": "string", "tags": [], - "label": "DEFAULT_LEGEND_SIZE", + "label": "ACTION_CONVERT_TO_LENS", "description": [], "signature": [ - { - "pluginId": "visualizations", - "scope": "common", - "docId": "kibVisualizationsPluginApi", - "section": "def-common.LegendSize", + "\"ACTION_CONVERT_TO_LENS\"" + ], + "path": "src/plugins/visualizations/public/triggers/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.AGG_BASED_VISUALIZATION_TRIGGER", + "type": "string", + "tags": [], + "label": "AGG_BASED_VISUALIZATION_TRIGGER", + "description": [], + "signature": [ + "\"AGG_BASED_VISUALIZATION_TRIGGER\"" + ], + "path": "src/plugins/visualizations/public/triggers/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.DEFAULT_LEGEND_SIZE", + "type": "string", + "tags": [], + "label": "DEFAULT_LEGEND_SIZE", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.LegendSize", "text": "LegendSize" }, ".MEDIUM" @@ -5804,6 +5936,29 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-public.SchemaConfig", + "type": "Type", + "tags": [], + "label": "SchemaConfig", + "description": [], + "signature": [ + "{ [Agg in Aggs]: ", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.GenericSchemaConfig", + "text": "GenericSchemaConfig" + }, + "; }[Aggs]" + ], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-public.VisToExpressionAst", @@ -6383,6 +6538,23 @@ } ], "objects": [ + { + "parentPluginId": "visualizations", + "id": "def-public.convertToLensModule", + "type": "Object", + "tags": [], + "label": "convertToLensModule", + "description": [], + "signature": [ + "Promise" + ], + "path": "src/plugins/visualizations/public/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-public.LegendSizeToPixels", @@ -6679,6 +6851,69 @@ "common": { "classes": [], "functions": [ + { + "parentPluginId": "visualizations", + "id": "def-common.convertToSchemaConfig", + "type": "Function", + "tags": [], + "label": "convertToSchemaConfig", + "description": [], + "signature": [ + "(agg: ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + }, + ") => ", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.SchemaConfig", + "text": "SchemaConfig" + }, + "<", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.METRIC_TYPES", + "text": "METRIC_TYPES" + }, + ">" + ], + "path": "src/plugins/visualizations/common/vis_schemas.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-common.convertToSchemaConfig.$1", + "type": "Object", + "tags": [], + "label": "agg", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggConfig", + "text": "AggConfig" + } + ], + "path": "src/plugins/visualizations/common/vis_schemas.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.findAccessorOrFail", @@ -7080,6 +7315,54 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.getIndexPatternIds", + "type": "Function", + "tags": [], + "label": "getIndexPatternIds", + "description": [], + "signature": [ + "(layers: ", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.Layer", + "text": "Layer" + }, + "[]) => string[]" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-common.getIndexPatternIds.$1", + "type": "Array", + "tags": [], + "label": "layers", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.Layer", + "text": "Layer" + }, + "[]" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.isAnnotationsLayer", @@ -7136,6 +7419,78 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.isFieldValid", + "type": "Function", + "tags": [], + "label": "isFieldValid", + "description": [], + "signature": [ + "(field: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + }, + " | undefined, aggregation: ", + "SupportedMetric", + ") => field is ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + } + ], + "path": "src/plugins/visualizations/common/convert_to_lens/utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-common.isFieldValid.$1", + "type": "Object", + "tags": [], + "label": "field", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + }, + " | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.isFieldValid.$2", + "type": "CompoundType", + "tags": [], + "label": "aggregation", + "description": [], + "signature": [ + "SupportedMetric" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.isVisDimension", @@ -7884,6 +8239,73 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.ColumnState", + "type": "Interface", + "tags": [], + "label": "ColumnState", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-common.ColumnState.columnId", + "type": "string", + "tags": [], + "label": "columnId", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.ColumnState.summaryRow", + "type": "CompoundType", + "tags": [], + "label": "summaryRow", + "description": [], + "signature": [ + "\"min\" | \"none\" | \"max\" | \"count\" | \"sum\" | \"avg\" | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.ColumnState.alignment", + "type": "CompoundType", + "tags": [], + "label": "alignment", + "description": [], + "signature": [ + "\"left\" | \"right\" | \"center\" | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.ColumnState.collapseFn", + "type": "string", + "tags": [], + "label": "collapseFn", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.ColumnWithReferences", @@ -8227,6 +8649,9 @@ "tags": [], "label": "label", "description": [], + "signature": [ + "string | undefined" + ], "path": "src/plugins/visualizations/common/convert_to_lens/types/common.ts", "deprecated": false, "trackAdoption": false @@ -8402,6 +8827,131 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.GenericSchemaConfig", + "type": "Interface", + "tags": [], + "label": "GenericSchemaConfig", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.GenericSchemaConfig", + "text": "GenericSchemaConfig" + }, + "" + ], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-common.GenericSchemaConfig.accessor", + "type": "number", + "tags": [], + "label": "accessor", + "description": [], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.GenericSchemaConfig.label", + "type": "string", + "tags": [], + "label": "label", + "description": [], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.GenericSchemaConfig.format", + "type": "Object", + "tags": [], + "label": "format", + "description": [], + "signature": [ + "{ id?: string | undefined; params?: ", + "SerializableRecord", + " | undefined; }" + ], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.GenericSchemaConfig.params", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "SchemaConfigParams" + ], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.GenericSchemaConfig.aggType", + "type": "Uncategorized", + "tags": [], + "label": "aggType", + "description": [], + "signature": [ + "Agg" + ], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.GenericSchemaConfig.aggId", + "type": "string", + "tags": [], + "label": "aggId", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.GenericSchemaConfig.aggParams", + "type": "Uncategorized", + "tags": [], + "label": "aggParams", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.AggParamsMapping", + "text": "AggParamsMapping" + }, + "[Agg] | undefined" + ], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.LabelsOrientationConfig", @@ -8825,6 +9375,20 @@ "path": "src/plugins/visualizations/common/convert_to_lens/types/context.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.NavigateToLensContext.indexPatternIds", + "type": "Array", + "tags": [], + "label": "indexPatternIds", + "description": [], + "signature": [ + "string[]" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/context.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -8868,6 +9432,42 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.PagingState", + "type": "Interface", + "tags": [], + "label": "PagingState", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-common.PagingState.size", + "type": "number", + "tags": [], + "label": "size", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.PagingState.enabled", + "type": "boolean", + "tags": [], + "label": "enabled", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.PercentileParams", @@ -9333,21 +9933,63 @@ }, " | undefined; }" ], - "path": "src/plugins/visualizations/common/types.ts", + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.SerializedVisData.savedSearchId", + "type": "string", + "tags": [], + "label": "savedSearchId", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.SortingState", + "type": "Interface", + "tags": [], + "label": "SortingState", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-common.SortingState.columnId", + "type": "string", + "tags": [], + "label": "columnId", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "visualizations", - "id": "def-common.SerializedVisData.savedSearchId", - "type": "string", + "id": "def-common.SortingState.direction", + "type": "CompoundType", "tags": [], - "label": "savedSearchId", + "label": "direction", "description": [], "signature": [ - "string | undefined" + "\"none\" | \"asc\" | \"desc\"" ], - "path": "src/plugins/visualizations/common/types.ts", + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", "deprecated": false, "trackAdoption": false } @@ -9399,6 +10041,164 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.TableVisConfiguration", + "type": "Interface", + "tags": [], + "label": "TableVisConfiguration", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "visualizations", + "id": "def-common.TableVisConfiguration.columns", + "type": "Array", + "tags": [], + "label": "columns", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.ColumnState", + "text": "ColumnState" + }, + "[]" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.TableVisConfiguration.layerId", + "type": "string", + "tags": [], + "label": "layerId", + "description": [], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.TableVisConfiguration.layerType", + "type": "string", + "tags": [], + "label": "layerType", + "description": [], + "signature": [ + "\"data\"" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.TableVisConfiguration.sorting", + "type": "Object", + "tags": [], + "label": "sorting", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.SortingState", + "text": "SortingState" + }, + " | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.TableVisConfiguration.rowHeight", + "type": "CompoundType", + "tags": [], + "label": "rowHeight", + "description": [], + "signature": [ + "\"auto\" | \"custom\" | \"single\" | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.TableVisConfiguration.headerRowHeight", + "type": "CompoundType", + "tags": [], + "label": "headerRowHeight", + "description": [], + "signature": [ + "\"auto\" | \"custom\" | \"single\" | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.TableVisConfiguration.rowHeightLines", + "type": "number", + "tags": [], + "label": "rowHeightLines", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.TableVisConfiguration.headerRowHeightLines", + "type": "number", + "tags": [], + "label": "headerRowHeightLines", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-common.TableVisConfiguration.paging", + "type": "Object", + "tags": [], + "label": "paging", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.PagingState", + "text": "PagingState" + }, + " | undefined" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.TermsParams", @@ -10689,6 +11489,39 @@ } ], "misc": [ + { + "parentPluginId": "visualizations", + "id": "def-common.AggBasedColumn", + "type": "Type", + "tags": [], + "label": "AggBasedColumn", + "description": [], + "signature": [ + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.GenericColumnWithMeta", + "text": "GenericColumnWithMeta" + }, + "<", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.Column", + "text": "Column" + }, + ", ", + "Meta", + "> | ", + "BucketColumn" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/lib/convert/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.AnyColumnWithReferences", @@ -11022,7 +11855,14 @@ "label": "ColumnWithMeta", "description": [], "signature": [ - "Col & (Meta extends undefined ? undefined : { meta: Meta; })" + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.Column", + "text": "Column" + }, + " & { meta: unknown; }" ], "path": "src/plugins/visualizations/common/convert_to_lens/types/columns.ts", "deprecated": false, @@ -11043,6 +11883,14 @@ "docId": "kibVisualizationsPluginApi", "section": "def-common.XYConfiguration", "text": "XYConfiguration" + }, + " | ", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.TableVisConfiguration", + "text": "TableVisConfiguration" } ], "path": "src/plugins/visualizations/common/convert_to_lens/types/configurations.ts", @@ -11434,6 +12282,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.GenericColumnWithMeta", + "type": "Type", + "tags": [], + "label": "GenericColumnWithMeta", + "description": [], + "signature": [ + "Col & (Meta extends undefined ? undefined : { meta: Meta; })" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/columns.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.LastValueColumn", @@ -11782,6 +12645,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.RangeMode", + "type": "Type", + "tags": [], + "label": "RangeMode", + "description": [], + "signature": [ + "\"range\" | \"histogram\"" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/types/params.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.SavedVisState", @@ -11799,6 +12677,29 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.SchemaConfig", + "type": "Type", + "tags": [], + "label": "SchemaConfig", + "description": [], + "signature": [ + "{ [Agg in Aggs]: ", + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.GenericSchemaConfig", + "text": "GenericSchemaConfig" + }, + "; }[Aggs]" + ], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.SeriesType", @@ -11961,6 +12862,35 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.SupportedAggregation", + "type": "Type", + "tags": [], + "label": "SupportedAggregation", + "description": [], + "signature": [ + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.METRIC_TYPES", + "text": "METRIC_TYPES" + }, + " | ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.BUCKET_TYPES", + "text": "BUCKET_TYPES" + } + ], + "path": "src/plugins/visualizations/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.TermsColumn", @@ -12150,6 +13080,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "visualizations", + "id": "def-common.RANGE_MODES", + "type": "Object", + "tags": [], + "label": "RANGE_MODES", + "description": [], + "signature": [ + "{ readonly Range: \"range\"; readonly Histogram: \"histogram\"; }" + ], + "path": "src/plugins/visualizations/common/convert_to_lens/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "visualizations", "id": "def-common.SeriesTypes", diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 81c4149912c26..c4ea2e6c61e76 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2022-09-26 +date: 2022-09-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 631 | 12 | 602 | 14 | +| 679 | 12 | 649 | 18 | ## Client From 67a07e8b69d04e206ab1755045b2ca9fa95b6213 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Tue, 27 Sep 2022 08:54:44 +0200 Subject: [PATCH 44/51] Move client-side `CoreSystem` to packages (#141606) * create empty package * copy files to package * clean duplicate constant * add dependencies to bazel file * adapt usages * update readme * [CI] Auto-commit changed files from 'node scripts/generate codeowners' * uppdate README Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .github/CODEOWNERS | 1 + package.json | 2 + packages/BUILD.bazel | 2 + .../index.ts | 1 - .../core-root-browser-internal/BUILD.bazel | 172 ++++++++++++++++++ .../root/core-root-browser-internal/README.md | 5 + .../core-root-browser-internal/index.ts} | 4 +- .../core-root-browser-internal/jest.config.js | 13 ++ .../core-root-browser-internal/kibana.jsonc | 7 + .../core-root-browser-internal/package.json | 9 + .../src}/apm_resource_counter.ts | 0 .../src}/apm_system.test.ts | 0 .../src}/apm_system.ts | 0 .../src/core_system.scss | 0 .../src}/core_system.test.mocks.ts | 0 .../src}/core_system.test.ts | 0 .../src}/core_system.ts | 11 +- .../core-root-browser-internal/src}/events.ts | 3 - .../src}/fetch_optional_memory_info.test.ts | 0 .../src}/fetch_optional_memory_info.ts | 0 .../core-root-browser-internal/src/index.ts | 11 ++ .../src}/kbn_bootstrap.test.mocks.ts | 0 .../src}/kbn_bootstrap.test.ts | 0 .../src}/kbn_bootstrap.ts | 2 +- .../core-root-browser-internal/tsconfig.json | 18 ++ src/core/public/index.scss | 1 - src/core/public/index.ts | 4 +- yarn.lock | 8 + 28 files changed, 261 insertions(+), 13 deletions(-) create mode 100644 packages/core/root/core-root-browser-internal/BUILD.bazel create mode 100644 packages/core/root/core-root-browser-internal/README.md rename packages/core/{mount-utils/core-mount-utils-browser-internal/src/consts.ts => root/core-root-browser-internal/index.ts} (77%) create mode 100644 packages/core/root/core-root-browser-internal/jest.config.js create mode 100644 packages/core/root/core-root-browser-internal/kibana.jsonc create mode 100644 packages/core/root/core-root-browser-internal/package.json rename {src/core/public => packages/core/root/core-root-browser-internal/src}/apm_resource_counter.ts (100%) rename {src/core/public => packages/core/root/core-root-browser-internal/src}/apm_system.test.ts (100%) rename {src/core/public => packages/core/root/core-root-browser-internal/src}/apm_system.ts (100%) rename src/core/public/_core.scss => packages/core/root/core-root-browser-internal/src/core_system.scss (100%) rename {src/core/public => packages/core/root/core-root-browser-internal/src}/core_system.test.mocks.ts (100%) rename {src/core/public => packages/core/root/core-root-browser-internal/src}/core_system.test.ts (100%) rename {src/core/public => packages/core/root/core-root-browser-internal/src}/core_system.ts (98%) rename {src/core/public => packages/core/root/core-root-browser-internal/src}/events.ts (97%) rename {src/core/public => packages/core/root/core-root-browser-internal/src}/fetch_optional_memory_info.test.ts (100%) rename {src/core/public => packages/core/root/core-root-browser-internal/src}/fetch_optional_memory_info.ts (100%) create mode 100644 packages/core/root/core-root-browser-internal/src/index.ts rename {src/core/public => packages/core/root/core-root-browser-internal/src}/kbn_bootstrap.test.mocks.ts (100%) rename {src/core/public => packages/core/root/core-root-browser-internal/src}/kbn_bootstrap.test.ts (100%) rename {src/core/public => packages/core/root/core-root-browser-internal/src}/kbn_bootstrap.ts (95%) create mode 100644 packages/core/root/core-root-browser-internal/tsconfig.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 480acad008f00..63c5c8047c6b4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -786,6 +786,7 @@ packages/core/preboot/core-preboot-server-internal @elastic/kibana-core packages/core/preboot/core-preboot-server-mocks @elastic/kibana-core packages/core/rendering/core-rendering-browser-internal @elastic/kibana-core packages/core/rendering/core-rendering-browser-mocks @elastic/kibana-core +packages/core/root/core-root-browser-internal @elastic/kibana-core packages/core/saved-objects/core-saved-objects-api-browser @elastic/kibana-core packages/core/saved-objects/core-saved-objects-api-server @elastic/kibana-core packages/core/saved-objects/core-saved-objects-api-server-internal @elastic/kibana-core diff --git a/package.json b/package.json index 3c439a01a9b3d..02511a00b56c3 100644 --- a/package.json +++ b/package.json @@ -260,6 +260,7 @@ "@kbn/core-preboot-server-mocks": "link:bazel-bin/packages/core/preboot/core-preboot-server-mocks", "@kbn/core-rendering-browser-internal": "link:bazel-bin/packages/core/rendering/core-rendering-browser-internal", "@kbn/core-rendering-browser-mocks": "link:bazel-bin/packages/core/rendering/core-rendering-browser-mocks", + "@kbn/core-root-browser-internal": "link:bazel-bin/packages/core/root/core-root-browser-internal", "@kbn/core-saved-objects-api-browser": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-browser", "@kbn/core-saved-objects-api-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-server", "@kbn/core-saved-objects-api-server-internal": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-server-internal", @@ -981,6 +982,7 @@ "@types/kbn__core-public-internal-base": "link:bazel-bin/packages/core/public/internal-base/npm_module_types", "@types/kbn__core-rendering-browser-internal": "link:bazel-bin/packages/core/rendering/core-rendering-browser-internal/npm_module_types", "@types/kbn__core-rendering-browser-mocks": "link:bazel-bin/packages/core/rendering/core-rendering-browser-mocks/npm_module_types", + "@types/kbn__core-root-browser-internal": "link:bazel-bin/packages/core/root/core-root-browser-internal/npm_module_types", "@types/kbn__core-saved-objects-api-browser": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-browser/npm_module_types", "@types/kbn__core-saved-objects-api-server": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-server/npm_module_types", "@types/kbn__core-saved-objects-api-server-internal": "link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-server-internal/npm_module_types", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 48af6f87aef5d..62cc4b4ce9ad2 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -126,6 +126,7 @@ filegroup( "//packages/core/preboot/core-preboot-server-mocks:build", "//packages/core/rendering/core-rendering-browser-internal:build", "//packages/core/rendering/core-rendering-browser-mocks:build", + "//packages/core/root/core-root-browser-internal:build", "//packages/core/saved-objects/core-saved-objects-api-browser:build", "//packages/core/saved-objects/core-saved-objects-api-server:build", "//packages/core/saved-objects/core-saved-objects-api-server-internal:build", @@ -456,6 +457,7 @@ filegroup( "//packages/core/preboot/core-preboot-server-mocks:build_types", "//packages/core/rendering/core-rendering-browser-internal:build_types", "//packages/core/rendering/core-rendering-browser-mocks:build_types", + "//packages/core/root/core-root-browser-internal:build_types", "//packages/core/saved-objects/core-saved-objects-api-browser:build_types", "//packages/core/saved-objects/core-saved-objects-api-server:build_types", "//packages/core/saved-objects/core-saved-objects-api-server-internal:build_types", diff --git a/packages/core/mount-utils/core-mount-utils-browser-internal/index.ts b/packages/core/mount-utils/core-mount-utils-browser-internal/index.ts index 50a2868ddb711..192ca09f6e85b 100644 --- a/packages/core/mount-utils/core-mount-utils-browser-internal/index.ts +++ b/packages/core/mount-utils/core-mount-utils-browser-internal/index.ts @@ -7,4 +7,3 @@ */ export { MountWrapper, mountReactNode } from './src/mount'; -export { KBN_LOAD_MARKS } from './src/consts'; diff --git a/packages/core/root/core-root-browser-internal/BUILD.bazel b/packages/core/root/core-root-browser-internal/BUILD.bazel new file mode 100644 index 0000000000000..d0d5e786d7867 --- /dev/null +++ b/packages/core/root/core-root-browser-internal/BUILD.bazel @@ -0,0 +1,172 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-root-browser-internal" +PKG_REQUIRE_NAME = "@kbn/core-root-browser-internal" + +SOURCE_FILES = glob( + [ + "**/*.ts", + "**/*.tsx", + "**/*.scss", + ], + exclude = [ + "**/*.config.js", + "**/*.mock.*", + "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__/**", + "**/integration_tests/**", + "**/mocks/**", + "**/scripts/**", + "**/storybook/**", + "**/test_fixtures/**", + "**/test_helpers/**", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ + "@npm//rxjs", + "@npm//@elastic/apm-rum", + "//packages/kbn-std", + "//packages/kbn-i18n", + "//packages/kbn-ebt-tools", + "//packages/core/application/core-application-browser-internal", + "//packages/core/injected-metadata/core-injected-metadata-browser-internal", + "//packages/core/doc-links/core-doc-links-browser-internal", + "//packages/core/theme/core-theme-browser-internal", + "//packages/core/analytics/core-analytics-browser-internal", + "//packages/core/i18n/core-i18n-browser-internal", + "//packages/core/execution-context/core-execution-context-browser-internal", + "//packages/core/fatal-errors/core-fatal-errors-browser-internal", + "//packages/core/http/core-http-browser-internal", + "//packages/core/ui-settings/core-ui-settings-browser-internal", + "//packages/core/deprecations/core-deprecations-browser-internal", + "//packages/core/integrations/core-integrations-browser-internal", + "//packages/core/overlays/core-overlays-browser-internal", + "//packages/core/saved-objects/core-saved-objects-browser-internal", + "//packages/core/notifications/core-notifications-browser-internal", + "//packages/core/chrome/core-chrome-browser-internal", + "//packages/core/rendering/core-rendering-browser-internal", + "//packages/core/apps/core-apps-browser-internal", + "//packages/core/lifecycle/core-lifecycle-browser-internal", + "//packages/core/plugins/core-plugins-browser-internal", +] + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//rxjs", + "@npm//@elastic/apm-rum", + "//packages/kbn-std:npm_module_types", + "//packages/kbn-i18n:npm_module_types", + "//packages/kbn-ebt-tools:npm_module_types", + "//packages/core/execution-context/core-execution-context-browser:npm_module_types", + "//packages/core/application/core-application-browser-internal:npm_module_types", + "//packages/core/base/core-base-browser-internal:npm_module_types", + "//packages/core/injected-metadata/core-injected-metadata-browser-internal:npm_module_types", + "//packages/core/doc-links/core-doc-links-browser-internal:npm_module_types", + "//packages/core/theme/core-theme-browser-internal:npm_module_types", + "//packages/core/analytics/core-analytics-browser:npm_module_types", + "//packages/core/analytics/core-analytics-browser-internal:npm_module_types", + "//packages/core/i18n/core-i18n-browser-internal:npm_module_types", + "//packages/core/execution-context/core-execution-context-browser-internal:npm_module_types", + "//packages/core/fatal-errors/core-fatal-errors-browser:npm_module_types", + "//packages/core/fatal-errors/core-fatal-errors-browser-internal:npm_module_types", + "//packages/core/http/core-http-browser-internal:npm_module_types", + "//packages/core/ui-settings/core-ui-settings-browser-internal:npm_module_types", + "//packages/core/deprecations/core-deprecations-browser-internal:npm_module_types", + "//packages/core/integrations/core-integrations-browser-internal:npm_module_types", + "//packages/core/overlays/core-overlays-browser-internal:npm_module_types", + "//packages/core/saved-objects/core-saved-objects-browser-internal:npm_module_types", + "//packages/core/notifications/core-notifications-browser-internal:npm_module_types", + "//packages/core/chrome/core-chrome-browser-internal:npm_module_types", + "//packages/core/rendering/core-rendering-browser-internal:npm_module_types", + "//packages/core/apps/core-apps-browser-internal:npm_module_types", + "//packages/core/lifecycle/core-lifecycle-browser-internal:npm_module_types", + "//packages/core/plugins/core-plugins-browser-internal:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) + +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + web = True, + additional_args = [ + "--copy-files", + "--quiet" + ], +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node", ":target_web"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/root/core-root-browser-internal/README.md b/packages/core/root/core-root-browser-internal/README.md new file mode 100644 index 0000000000000..522df736da29c --- /dev/null +++ b/packages/core/root/core-root-browser-internal/README.md @@ -0,0 +1,5 @@ +# @kbn/core-root-browser-internal + +This package exposes the root components required to start the Core system on the browser side. +- `CoreSystem` +- `__kbnBootstrap__` diff --git a/packages/core/mount-utils/core-mount-utils-browser-internal/src/consts.ts b/packages/core/root/core-root-browser-internal/index.ts similarity index 77% rename from packages/core/mount-utils/core-mount-utils-browser-internal/src/consts.ts rename to packages/core/root/core-root-browser-internal/index.ts index 8372eafec8147..032a4bd1eb8b1 100644 --- a/packages/core/mount-utils/core-mount-utils-browser-internal/src/consts.ts +++ b/packages/core/root/core-root-browser-internal/index.ts @@ -6,5 +6,5 @@ * Side Public License, v 1. */ -/** @internal */ -export const KBN_LOAD_MARKS = 'kbnLoad'; +export { CoreSystem, __kbnBootstrap__ } from './src'; +export type { CoreSystemParams } from './src'; diff --git a/packages/core/root/core-root-browser-internal/jest.config.js b/packages/core/root/core-root-browser-internal/jest.config.js new file mode 100644 index 0000000000000..4f81bcdaaf118 --- /dev/null +++ b/packages/core/root/core-root-browser-internal/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + roots: ['/packages/core/root/core-root-browser-internal'], +}; diff --git a/packages/core/root/core-root-browser-internal/kibana.jsonc b/packages/core/root/core-root-browser-internal/kibana.jsonc new file mode 100644 index 0000000000000..0dd7d5ae6beb4 --- /dev/null +++ b/packages/core/root/core-root-browser-internal/kibana.jsonc @@ -0,0 +1,7 @@ +{ + "type": "shared-common", + "id": "@kbn/core-root-browser-internal", + "owner": "@elastic/kibana-core", + "runtimeDeps": [], + "typeDeps": [], +} diff --git a/packages/core/root/core-root-browser-internal/package.json b/packages/core/root/core-root-browser-internal/package.json new file mode 100644 index 0000000000000..30a34c02fc4eb --- /dev/null +++ b/packages/core/root/core-root-browser-internal/package.json @@ -0,0 +1,9 @@ +{ + "name": "@kbn/core-root-browser-internal", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "browser": "./target_web/index.js", + "author": "Kibana Core", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/src/core/public/apm_resource_counter.ts b/packages/core/root/core-root-browser-internal/src/apm_resource_counter.ts similarity index 100% rename from src/core/public/apm_resource_counter.ts rename to packages/core/root/core-root-browser-internal/src/apm_resource_counter.ts diff --git a/src/core/public/apm_system.test.ts b/packages/core/root/core-root-browser-internal/src/apm_system.test.ts similarity index 100% rename from src/core/public/apm_system.test.ts rename to packages/core/root/core-root-browser-internal/src/apm_system.test.ts diff --git a/src/core/public/apm_system.ts b/packages/core/root/core-root-browser-internal/src/apm_system.ts similarity index 100% rename from src/core/public/apm_system.ts rename to packages/core/root/core-root-browser-internal/src/apm_system.ts diff --git a/src/core/public/_core.scss b/packages/core/root/core-root-browser-internal/src/core_system.scss similarity index 100% rename from src/core/public/_core.scss rename to packages/core/root/core-root-browser-internal/src/core_system.scss diff --git a/src/core/public/core_system.test.mocks.ts b/packages/core/root/core-root-browser-internal/src/core_system.test.mocks.ts similarity index 100% rename from src/core/public/core_system.test.mocks.ts rename to packages/core/root/core-root-browser-internal/src/core_system.test.mocks.ts diff --git a/src/core/public/core_system.test.ts b/packages/core/root/core-root-browser-internal/src/core_system.test.ts similarity index 100% rename from src/core/public/core_system.test.ts rename to packages/core/root/core-root-browser-internal/src/core_system.test.ts diff --git a/src/core/public/core_system.ts b/packages/core/root/core-root-browser-internal/src/core_system.ts similarity index 98% rename from src/core/public/core_system.ts rename to packages/core/root/core-root-browser-internal/src/core_system.ts index 4381cfdd2abf9..b3eae041b785d 100644 --- a/src/core/public/core_system.ts +++ b/packages/core/root/core-root-browser-internal/src/core_system.ts @@ -26,7 +26,6 @@ import { DeprecationsService } from '@kbn/core-deprecations-browser-internal'; import { IntegrationsService } from '@kbn/core-integrations-browser-internal'; import { reportPerformanceMetricEvent } from '@kbn/ebt-tools'; import { OverlayService } from '@kbn/core-overlays-browser-internal'; -import { KBN_LOAD_MARKS } from '@kbn/core-mount-utils-browser-internal'; import { SavedObjectsService } from '@kbn/core-saved-objects-browser-internal'; import { NotificationsService } from '@kbn/core-notifications-browser-internal'; import { ChromeService } from '@kbn/core-chrome-browser-internal'; @@ -35,6 +34,7 @@ import { RenderingService } from '@kbn/core-rendering-browser-internal'; import { CoreAppsService } from '@kbn/core-apps-browser-internal'; import type { InternalCoreSetup, InternalCoreStart } from '@kbn/core-lifecycle-browser-internal'; import { PluginsService } from '@kbn/core-plugins-browser-internal'; +import { KBN_LOAD_MARKS } from './events'; import { fetchOptionalMemoryInfo } from './fetch_optional_memory_info'; import { @@ -47,7 +47,12 @@ import { LOAD_START, } from './events'; -interface Params { +import './core_system.scss'; + +/** + * @internal + */ +export interface CoreSystemParams { rootDomElement: HTMLElement; browserSupportsCsp: boolean; injectedMetadata: InjectedMetadataParams['injectedMetadata']; @@ -96,7 +101,7 @@ export class CoreSystem { private readonly executionContext: ExecutionContextService; private fatalErrorsSetup: FatalErrorsSetup | null = null; - constructor(params: Params) { + constructor(params: CoreSystemParams) { const { rootDomElement, browserSupportsCsp, injectedMetadata } = params; this.rootDomElement = rootDomElement; diff --git a/src/core/public/events.ts b/packages/core/root/core-root-browser-internal/src/events.ts similarity index 97% rename from src/core/public/events.ts rename to packages/core/root/core-root-browser-internal/src/events.ts index e2f5d48ddfe3d..50337778c8c3c 100644 --- a/src/core/public/events.ts +++ b/packages/core/root/core-root-browser-internal/src/events.ts @@ -6,11 +6,8 @@ * Side Public License, v 1. */ -/** @internal */ export const KBN_LOAD_MARKS = 'kbnLoad'; - export const KIBANA_LOADED_EVENT = 'kibana_loaded'; - export const LOAD_START = 'load_started'; export const LOAD_BOOTSTRAP_START = 'bootstrap_started'; export const LOAD_CORE_CREATED = 'core_created'; diff --git a/src/core/public/fetch_optional_memory_info.test.ts b/packages/core/root/core-root-browser-internal/src/fetch_optional_memory_info.test.ts similarity index 100% rename from src/core/public/fetch_optional_memory_info.test.ts rename to packages/core/root/core-root-browser-internal/src/fetch_optional_memory_info.test.ts diff --git a/src/core/public/fetch_optional_memory_info.ts b/packages/core/root/core-root-browser-internal/src/fetch_optional_memory_info.ts similarity index 100% rename from src/core/public/fetch_optional_memory_info.ts rename to packages/core/root/core-root-browser-internal/src/fetch_optional_memory_info.ts diff --git a/packages/core/root/core-root-browser-internal/src/index.ts b/packages/core/root/core-root-browser-internal/src/index.ts new file mode 100644 index 0000000000000..663af54e573eb --- /dev/null +++ b/packages/core/root/core-root-browser-internal/src/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { __kbnBootstrap__ } from './kbn_bootstrap'; +export { CoreSystem } from './core_system'; +export type { CoreSystemParams } from './core_system'; diff --git a/src/core/public/kbn_bootstrap.test.mocks.ts b/packages/core/root/core-root-browser-internal/src/kbn_bootstrap.test.mocks.ts similarity index 100% rename from src/core/public/kbn_bootstrap.test.mocks.ts rename to packages/core/root/core-root-browser-internal/src/kbn_bootstrap.test.mocks.ts diff --git a/src/core/public/kbn_bootstrap.test.ts b/packages/core/root/core-root-browser-internal/src/kbn_bootstrap.test.ts similarity index 100% rename from src/core/public/kbn_bootstrap.test.ts rename to packages/core/root/core-root-browser-internal/src/kbn_bootstrap.test.ts diff --git a/src/core/public/kbn_bootstrap.ts b/packages/core/root/core-root-browser-internal/src/kbn_bootstrap.ts similarity index 95% rename from src/core/public/kbn_bootstrap.ts rename to packages/core/root/core-root-browser-internal/src/kbn_bootstrap.ts index 0359f9e4d6520..c1ca8cb752d2d 100644 --- a/src/core/public/kbn_bootstrap.ts +++ b/packages/core/root/core-root-browser-internal/src/kbn_bootstrap.ts @@ -7,7 +7,7 @@ */ import { i18n } from '@kbn/i18n'; -import { KBN_LOAD_MARKS } from '@kbn/core-mount-utils-browser-internal'; +import { KBN_LOAD_MARKS } from './events'; import { CoreSystem } from './core_system'; import { ApmSystem } from './apm_system'; diff --git a/packages/core/root/core-root-browser-internal/tsconfig.json b/packages/core/root/core-root-browser-internal/tsconfig.json new file mode 100644 index 0000000000000..4283cbe1b760b --- /dev/null +++ b/packages/core/root/core-root-browser-internal/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "stripInternal": false, + "types": [ + "jest", + "node", + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ] +} diff --git a/src/core/public/index.scss b/src/core/public/index.scss index 4b034af74fa1b..c056b0f851801 100644 --- a/src/core/public/index.scss +++ b/src/core/public/index.scss @@ -1,4 +1,3 @@ @import './variables'; @import './mixins'; -@import './core'; @import './styles/index'; diff --git a/src/core/public/index.ts b/src/core/public/index.ts index ff666e0f3a187..643bc705814a0 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -226,6 +226,6 @@ export type { export type { CoreSetup, CoreStart, StartServicesAccessor } from '@kbn/core-lifecycle-browser'; -export type { CoreSystem } from './core_system'; +export type { CoreSystem } from '@kbn/core-root-browser-internal'; -export { __kbnBootstrap__ } from './kbn_bootstrap'; +export { __kbnBootstrap__ } from '@kbn/core-root-browser-internal'; diff --git a/yarn.lock b/yarn.lock index 23369504cad0a..0752e8a1611c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3142,6 +3142,10 @@ version "0.0.0" uid "" +"@kbn/core-root-browser-internal@link:bazel-bin/packages/core/root/core-root-browser-internal": + version "0.0.0" + uid "" + "@kbn/core-saved-objects-api-browser@link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-browser": version "0.0.0" uid "" @@ -7263,6 +7267,10 @@ version "0.0.0" uid "" +"@types/kbn__core-root-browser-internal@link:bazel-bin/packages/core/root/core-root-browser-internal/npm_module_types": + version "0.0.0" + uid "" + "@types/kbn__core-saved-objects-api-browser@link:bazel-bin/packages/core/saved-objects/core-saved-objects-api-browser/npm_module_types": version "0.0.0" uid "" From 76b26246100732f0d3f79aac461d037a06c41761 Mon Sep 17 00:00:00 2001 From: Julian Gernun Date: Tue, 27 Sep 2022 09:24:52 +0200 Subject: [PATCH 45/51] 141189 alerts table performance (#141385) * retrieve data without loops and work with columns instead of ids * not found column when category doesnt exist --- .../hooks/use_columns/toggle_column.ts | 44 +++++----- .../hooks/use_columns/use_columns.ts | 83 ++++++++++++------- 2 files changed, 74 insertions(+), 53 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/toggle_column.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/toggle_column.ts index f7f181c60b024..ae7bceed0ac80 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/toggle_column.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/toggle_column.ts @@ -7,57 +7,59 @@ import { EuiDataGridColumn } from '@elastic/eui'; -const remove = ({ columnIds, index }: { columnIds: string[]; index: number }) => { - return [...columnIds.slice(0, index), ...columnIds.slice(index + 1)]; +const remove = ({ columns, index }: { columns: EuiDataGridColumn[]; index: number }) => { + return [...columns.slice(0, index), ...columns.slice(index + 1)]; }; const insert = ({ - columnId, - columnIds, + column, + columns, defaultColumns, }: { - columnId: string; - columnIds: string[]; + column: EuiDataGridColumn; + columns: EuiDataGridColumn[]; defaultColumns: EuiDataGridColumn[]; }) => { const defaultIndex = defaultColumns.findIndex( - (column: EuiDataGridColumn) => column.id === columnId + (defaultColumn: EuiDataGridColumn) => defaultColumn.id === column.id ); const isInDefaultConfig = defaultIndex >= 0; // if the column isn't shown but it's part of the default config // insert into the same position as in the default config if (isInDefaultConfig) { - return [...columnIds.slice(0, defaultIndex), columnId, ...columnIds.slice(defaultIndex)]; + return [...columns.slice(0, defaultIndex), column, ...columns.slice(defaultIndex)]; } // if the column isn't shown and it's not part of the default config // push it into the second position. Behaviour copied by t_grid, security // does this to insert right after the timestamp column - return [columnIds[0], columnId, ...columnIds.slice(1)]; + return [columns[0], column, ...columns.slice(1)]; }; /** - * @param param.columnId id of the column to be removed/inserted - * @param param.columnIds Current array of columnIds in the grid - * @param param.defaultColumns Those initial columns set up in the configuration before being modified by the user - * @returns the new list of columns to be shown + * @param param.column column to be removed/inserted + * @param param.columns current array of columns in the grid + * @param param.defaultColumns Initial columns set up in the configuration before being modified by the user + * @returns the new list of columns */ export const toggleColumn = ({ - columnId, - columnIds, + column, + columns, defaultColumns, }: { - columnId: string; - columnIds: string[]; + column: EuiDataGridColumn; + columns: EuiDataGridColumn[]; defaultColumns: EuiDataGridColumn[]; -}): string[] => { - const currentIndex = columnIds.indexOf(columnId); +}): EuiDataGridColumn[] => { + const currentIndex = columns.findIndex( + (currentColumn: EuiDataGridColumn) => currentColumn.id === column.id + ); const isVisible = currentIndex >= 0; if (isVisible) { - return remove({ columnIds, index: currentIndex }); + return remove({ columns, index: currentIndex }); } - return insert({ defaultColumns, columnId, columnIds }); + return insert({ defaultColumns, column, columns }); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.ts index eb6f6adad1cc5..f10807824e8fc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_columns/use_columns.ts @@ -7,12 +7,12 @@ import { EuiDataGridColumn } from '@elastic/eui'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import { BrowserField, BrowserFields } from '@kbn/rule-registry-plugin/common'; import { useCallback, useEffect, useState } from 'react'; +import { AlertConsumers } from '@kbn/rule-data-utils'; import { AlertsTableStorage } from '../../alerts_table_state'; -import { useFetchBrowserFieldCapabilities } from '../use_fetch_browser_fields_capabilities'; import { toggleColumn } from './toggle_column'; +import { useFetchBrowserFieldCapabilities } from '../use_fetch_browser_fields_capabilities'; interface UseColumnsArgs { featureIds: AlertConsumers[]; @@ -29,43 +29,62 @@ const fieldTypeToDataGridColumnTypeMapper = (fieldType: string | undefined) => { return fieldType; }; +const getFieldCategoryFromColumnId = (columnId: string): string => { + const fieldName = columnId.split('.'); + + if (fieldName.length === 1) { + return 'base'; + } + + return fieldName[0]; +}; + /** * EUI Data Grid expects the columns to have a property 'schema' defined for proper sorting * this schema as its own types as can be check out in the docs so we add it here manually * https://eui.elastic.co/#/tabular-content/data-grid-schema-columns */ const euiColumnFactory = ( - column: EuiDataGridColumn, - browserFields: BrowserFields + columnId: string, + browserFields: BrowserFields, + defaultColumns: EuiDataGridColumn[] ): EuiDataGridColumn => { - const browserFieldsProps = getBrowserFieldProps(column.id, browserFields); + const defaultColumn = getColumnByColumnId(defaultColumns, columnId); + const column = defaultColumn ? defaultColumn : { id: columnId }; + + const browserFieldsProps = getBrowserFieldProps(columnId, browserFields); return { ...column, schema: fieldTypeToDataGridColumnTypeMapper(browserFieldsProps.type), }; }; -/** - * Searches in browser fields object for a specific field - */ const getBrowserFieldProps = ( columnId: string, browserFields: BrowserFields ): Partial => { - for (const [, categoryDescriptor] of Object.entries(browserFields)) { - if (!categoryDescriptor.fields) { - continue; - } - - for (const [fieldName, fieldDescriptor] of Object.entries(categoryDescriptor.fields)) { - if (fieldName === columnId) { - return fieldDescriptor; - } - } + const notFoundSpecs = { type: 'string' }; + + if (!browserFields || Object.keys(browserFields).length === 0) { + return notFoundSpecs; + } + + const category = getFieldCategoryFromColumnId(columnId); + if (!browserFields[category]) { + return notFoundSpecs; + } + + const categorySpecs = browserFields[category].fields; + if (!categorySpecs) { + return notFoundSpecs; } - return { type: 'string' }; + + const fieldSpecs = categorySpecs[columnId]; + return fieldSpecs ? fieldSpecs : notFoundSpecs; }; +const isPopulatedColumn = (column: EuiDataGridColumn) => Boolean(column.schema); + /** * @param columns Columns to be considered in the alerts table * @param browserFields constant object with all field capabilities @@ -73,10 +92,13 @@ const getBrowserFieldProps = ( */ const populateColumns = ( columns: EuiDataGridColumn[], - browserFields: BrowserFields + browserFields: BrowserFields, + defaultColumns: EuiDataGridColumn[] ): EuiDataGridColumn[] => { return columns.map((column: EuiDataGridColumn) => { - return euiColumnFactory(column, browserFields); + return isPopulatedColumn(column) + ? column + : euiColumnFactory(column.id, browserFields, defaultColumns); }); }; @@ -128,10 +150,10 @@ export const useColumns = ({ useEffect(() => { if (isBrowserFieldDataLoading !== false || isColumnsPopulated) return; - const populatedColumns = populateColumns(columns, browserFields); + const populatedColumns = populateColumns(columns, browserFields, defaultColumns); setColumnsPopulated(true); setColumns(populatedColumns); - }, [browserFields, columns, isBrowserFieldDataLoading, isColumnsPopulated]); + }, [browserFields, columns, defaultColumns, isBrowserFieldDataLoading, isColumnsPopulated]); const setColumnsAndSave = useCallback( (newColumns: EuiDataGridColumn[]) => { @@ -156,15 +178,12 @@ export const useColumns = ({ const onToggleColumn = useCallback( (columnId: string): void => { - const newColumnIds = toggleColumn({ - columnId, - columnIds: getColumnIds(columns), - defaultColumns, - }); + const column = euiColumnFactory(columnId, browserFields, defaultColumns); - const newColumns = newColumnIds.map((_columnId: string) => { - const column = getColumnByColumnId(defaultColumns, _columnId); - return euiColumnFactory(column ? column : { id: _columnId }, browserFields); + const newColumns = toggleColumn({ + column, + columns, + defaultColumns, }); setColumnsAndSave(newColumns); @@ -173,7 +192,7 @@ export const useColumns = ({ ); const onResetColumns = useCallback(() => { - const populatedDefaultColumns = populateColumns(defaultColumns, browserFields); + const populatedDefaultColumns = populateColumns(defaultColumns, browserFields, defaultColumns); setColumnsAndSave(populatedDefaultColumns); }, [browserFields, defaultColumns, setColumnsAndSave]); From 8ce172d25ca251097c67b5ef4e0193d69e55f3e6 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Tue, 27 Sep 2022 10:02:08 +0200 Subject: [PATCH 46/51] [Fleet] Updated bulk action api to return actionId instead of agents success for consistency (#141757) * bulk action api returns actionId instead of agents success * updated action modals * fixed tests * updated openapi * fix typo * removed unused translations --- .../plugins/fleet/common/openapi/bundled.json | 68 ++----------------- .../plugins/fleet/common/openapi/bundled.yaml | 40 ----------- .../openapi/paths/agents@bulk_reassign.yaml | 10 --- .../openapi/paths/agents@bulk_unenroll.yaml | 10 --- .../paths/agents@bulk_update_tags.yaml | 10 --- .../openapi/paths/agents@bulk_upgrade.yaml | 10 --- .../fleet/common/types/rest_spec/agent.ts | 10 +-- .../agent_reassign_policy_modal/index.tsx | 11 +-- .../components/agent_unenroll_modal/index.tsx | 13 +--- .../components/agent_upgrade_modal/index.tsx | 51 ++------------ .../fleet/server/routes/agent/handlers.ts | 22 +----- .../server/routes/agent/unenroll_handler.ts | 14 +--- .../server/routes/agent/upgrade_handler.ts | 17 +---- .../server/services/agents/action_runner.ts | 23 +++---- .../fleet/server/services/agents/crud.test.ts | 36 +--------- .../fleet/server/services/agents/crud.ts | 28 -------- .../fleet/server/services/agents/reassign.ts | 13 +--- .../services/agents/reassign_action_runner.ts | 28 +++----- .../server/services/agents/unenroll.test.ts | 31 +-------- .../fleet/server/services/agents/unenroll.ts | 4 +- .../services/agents/unenroll_action_runner.ts | 15 ++-- .../services/agents/update_agent_tags.ts | 16 ++--- .../agents/update_agent_tags_action_runner.ts | 18 ++--- .../fleet/server/services/agents/upgrade.ts | 4 +- .../services/agents/upgrade_action_runner.ts | 27 ++------ .../translations/translations/fr-FR.json | 3 - .../translations/translations/ja-JP.json | 3 - .../translations/translations/zh-CN.json | 3 - .../apis/agents/reassign.ts | 38 +---------- .../apis/agents/unenroll.ts | 21 +----- .../apis/agents/update_agent_tags.ts | 10 +-- .../apis/agents/upgrade.ts | 18 +---- 32 files changed, 87 insertions(+), 538 deletions(-) diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index 88f091ad98310..71b4ec04d4e98 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -1254,23 +1254,8 @@ "type": "object", "properties": { "actionId": { - "type": "string", - "description": "action id when running in async mode (>10k agents)" + "type": "string" } - }, - "additionalProperties": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - }, - "error": { - "type": "string" - } - }, - "required": [ - "success" - ] } } } @@ -1849,23 +1834,8 @@ "type": "object", "properties": { "actionId": { - "type": "string", - "description": "action id when running in async mode (>10k agents)" + "type": "string" } - }, - "additionalProperties": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - }, - "error": { - "type": "string" - } - }, - "required": [ - "success" - ] } } } @@ -1931,23 +1901,8 @@ "type": "object", "properties": { "actionId": { - "type": "string", - "description": "action id when running in async mode (>10k agents)" + "type": "string" } - }, - "additionalProperties": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - }, - "error": { - "type": "string" - } - }, - "required": [ - "success" - ] } } } @@ -2020,23 +1975,8 @@ "type": "object", "properties": { "actionId": { - "type": "string", - "description": "action id when running in async mode (>10k agents)" + "type": "string" } - }, - "additionalProperties": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - }, - "error": { - "type": "string" - } - }, - "required": [ - "success" - ] } } } diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index 86928fca0b2f4..92347809b0616 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -774,16 +774,6 @@ paths: properties: actionId: type: string - description: action id when running in async mode (>10k agents) - additionalProperties: - type: object - properties: - success: - type: boolean - error: - type: string - required: - - success '400': description: BAD REQUEST content: @@ -1145,16 +1135,6 @@ paths: properties: actionId: type: string - description: action id when running in async mode (>10k agents) - additionalProperties: - type: object - properties: - success: - type: boolean - error: - type: string - required: - - success operationId: bulk-reassign-agents parameters: - $ref: '#/components/parameters/kbn_xsrf' @@ -1195,16 +1175,6 @@ paths: properties: actionId: type: string - description: action id when running in async mode (>10k agents) - additionalProperties: - type: object - properties: - success: - type: boolean - error: - type: string - required: - - success operationId: bulk-unenroll-agents parameters: - $ref: '#/components/parameters/kbn_xsrf' @@ -1250,16 +1220,6 @@ paths: properties: actionId: type: string - description: action id when running in async mode (>10k agents) - additionalProperties: - type: object - properties: - success: - type: boolean - error: - type: string - required: - - success operationId: bulk-update-agent-tags parameters: - $ref: '#/components/parameters/kbn_xsrf' diff --git a/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_reassign.yaml b/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_reassign.yaml index cd333e94e4750..17c4365f01e32 100644 --- a/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_reassign.yaml +++ b/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_reassign.yaml @@ -11,16 +11,6 @@ post: properties: actionId: type: string - description: action id when running in async mode (>10k agents) - additionalProperties: - type: object - properties: - success: - type: boolean - error: - type: string - required: - - success operationId: bulk-reassign-agents parameters: - $ref: ../components/headers/kbn_xsrf.yaml diff --git a/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_unenroll.yaml b/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_unenroll.yaml index ff04eda0be8a8..f5e244f86f74b 100644 --- a/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_unenroll.yaml +++ b/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_unenroll.yaml @@ -11,16 +11,6 @@ post: properties: actionId: type: string - description: action id when running in async mode (>10k agents) - additionalProperties: - type: object - properties: - success: - type: boolean - error: - type: string - required: - - success operationId: bulk-unenroll-agents parameters: - $ref: ../components/headers/kbn_xsrf.yaml diff --git a/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_update_tags.yaml b/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_update_tags.yaml index 80643ebd3625e..2eb129e802179 100644 --- a/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_update_tags.yaml +++ b/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_update_tags.yaml @@ -11,16 +11,6 @@ post: properties: actionId: type: string - description: action id when running in async mode (>10k agents) - additionalProperties: - type: object - properties: - success: - type: boolean - error: - type: string - required: - - success operationId: bulk-update-agent-tags parameters: - $ref: ../components/headers/kbn_xsrf.yaml diff --git a/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_upgrade.yaml b/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_upgrade.yaml index 1d9136353f01b..9a74054f492a7 100644 --- a/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_upgrade.yaml +++ b/x-pack/plugins/fleet/common/openapi/paths/agents@bulk_upgrade.yaml @@ -11,16 +11,6 @@ post: properties: actionId: type: string - description: action id when running in async mode (>10k agents) - additionalProperties: - type: object - properties: - success: - type: boolean - error: - type: string - required: - - success '400': description: BAD REQUEST content: diff --git a/x-pack/plugins/fleet/common/types/rest_spec/agent.ts b/x-pack/plugins/fleet/common/types/rest_spec/agent.ts index f1fbe4469de44..9a18613d95834 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/agent.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/agent.ts @@ -72,13 +72,9 @@ export interface PostBulkAgentUnenrollRequest { }; } -export type BulkAgentAction = Record< - Agent['id'], - { - success: boolean; - error?: string; - } -> & { actionId?: string }; +export interface BulkAgentAction { + actionId: string; +} export type PostBulkAgentUnenrollResponse = BulkAgentAction; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx index cae8b00fb6d3d..cb3f0d77eed34 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx @@ -82,20 +82,13 @@ export const AgentReassignAgentPolicyModal: React.FunctionComponent = ({ throw res.error; } setIsSubmitting(false); - const hasCompleted = isSingleAgent || Object.keys(res.data ?? {}).length > 0; const successMessage = i18n.translate( 'xpack.fleet.agentReassignPolicy.successSingleNotificationTitle', { - defaultMessage: 'Agent policy reassigned', + defaultMessage: 'Reassigning agent policy', } ); - const submittedMessage = i18n.translate( - 'xpack.fleet.agentReassignPolicy.submittedNotificationTitle', - { - defaultMessage: 'Agent policy reassign submitted', - } - ); - notifications.toasts.addSuccess(hasCompleted ? successMessage : submittedMessage); + notifications.toasts.addSuccess(successMessage); onClose(); } catch (error) { setIsSubmitting(false); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_unenroll_modal/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_unenroll_modal/index.tsx index 7c0c0136c3d09..72b1e00c1ed02 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_unenroll_modal/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_unenroll_modal/index.tsx @@ -40,7 +40,7 @@ export const AgentUnenrollAgentModal: React.FunctionComponent = ({ async function onSubmit() { try { setIsSubmitting(true); - const { error, data } = isSingleAgent + const { error } = isSingleAgent ? await sendPostAgentUnenroll((agents[0] as Agent).id, { revoke: forceUnenroll, }) @@ -52,13 +52,6 @@ export const AgentUnenrollAgentModal: React.FunctionComponent = ({ throw error; } setIsSubmitting(false); - const hasCompleted = isSingleAgent || Object.keys(data ?? {}).length > 0; - const submittedMessage = i18n.translate( - 'xpack.fleet.unenrollAgents.submittedNotificationTitle', - { - defaultMessage: 'Agent(s) unenroll submitted', - } - ); if (forceUnenroll) { const successMessage = isSingleAgent ? i18n.translate('xpack.fleet.unenrollAgents.successForceSingleNotificationTitle', { @@ -67,7 +60,7 @@ export const AgentUnenrollAgentModal: React.FunctionComponent = ({ : i18n.translate('xpack.fleet.unenrollAgents.successForceMultiNotificationTitle', { defaultMessage: 'Agents unenrolled', }); - notifications.toasts.addSuccess(hasCompleted ? successMessage : submittedMessage); + notifications.toasts.addSuccess(successMessage); } else { const successMessage = isSingleAgent ? i18n.translate('xpack.fleet.unenrollAgents.successSingleNotificationTitle', { @@ -76,7 +69,7 @@ export const AgentUnenrollAgentModal: React.FunctionComponent = ({ : i18n.translate('xpack.fleet.unenrollAgents.successMultiNotificationTitle', { defaultMessage: 'Unenrolling agents', }); - notifications.toasts.addSuccess(hasCompleted ? successMessage : submittedMessage); + notifications.toasts.addSuccess(successMessage); } onClose(); } catch (error) { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx index c1c45f47ff02f..d7d376e83e316 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx @@ -162,7 +162,7 @@ export const AgentUpgradeAgentModal: React.FunctionComponent { - ++acc.total; - ++acc[result.success ? 'success' : 'error']; - return acc; - }, - { - total: 0, - success: 0, - error: 0, - } - ); setIsSubmitting(false); - const hasCompleted = isSingleAgent || Object.keys(data ?? {}).length > 0; - const submittedMessage = i18n.translate( - 'xpack.fleet.upgradeAgents.submittedNotificationTitle', - { - defaultMessage: 'Agent(s) upgrade submitted', - } + notifications.toasts.addSuccess( + i18n.translate('xpack.fleet.upgradeAgents.successNotificationTitle', { + defaultMessage: 'Upgrading agent(s)', + }) ); - - if (!hasCompleted) { - notifications.toasts.addSuccess(submittedMessage); - } else if (counts.success === counts.total) { - notifications.toasts.addSuccess( - i18n.translate('xpack.fleet.upgradeAgents.successSingleNotificationTitle', { - defaultMessage: 'Upgrading {count, plural, one {# agent} other {# agents}}', - values: { count: isSingleAgent ? 1 : counts.total }, - }) - ); - } else if (counts.error === counts.total) { - notifications.toasts.addDanger( - i18n.translate('xpack.fleet.upgradeAgents.bulkResultAllErrorsNotificationTitle', { - defaultMessage: - 'Error upgrading {count, plural, one {agent} other {{count} agents} =true {all selected agents}}', - values: { count: isAllAgents || agentCount }, - }) - ); - } else { - notifications.toasts.addWarning({ - text: i18n.translate('xpack.fleet.upgradeAgents.bulkResultErrorResultsSummary', { - defaultMessage: - '{count} {count, plural, one {agent was} other {agents were}} not successful', - values: { count: counts.error }, - }), - }); - } onClose(); } catch (error) { setIsSubmitting(false); diff --git a/x-pack/plugins/fleet/server/routes/agent/handlers.ts b/x-pack/plugins/fleet/server/routes/agent/handlers.ts index 1ae6fb81742d1..86f202381119f 100644 --- a/x-pack/plugins/fleet/server/routes/agent/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent/handlers.ts @@ -25,8 +25,6 @@ import type { GetOneAgentResponse, GetAgentStatusResponse, PutAgentReassignResponse, - PostBulkAgentReassignResponse, - PostBulkUpdateAgentTagsResponse, GetAgentTagsResponse, GetAvailableVersionsResponse, GetActionStatusResponse, @@ -151,15 +149,7 @@ export const bulkUpdateAgentTagsHandler: RequestHandler< request.body.tagsToRemove ?? [] ); - const body = results.items.reduce((acc: any, so: any) => { - acc[so.id] = { - success: !so.error, - error: so.error?.message, - }; - return acc; - }, {}); - - return response.ok({ body: { ...body, actionId: results.actionId } }); + return response.ok({ body: { actionId: results.actionId } }); } catch (error) { return defaultFleetErrorHandler({ error, response }); } @@ -267,15 +257,7 @@ export const postBulkAgentsReassignHandler: RequestHandler< request.body.policy_id ); - const body = results.items.reduce((acc, so) => { - acc[so.id] = { - success: !so.error, - error: so.error?.message, - }; - return acc; - }, {}); - - return response.ok({ body: { ...body, actionId: results.actionId } }); + return response.ok({ body: { actionId: results.actionId } }); } catch (error) { return defaultFleetErrorHandler({ error, response }); } diff --git a/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts b/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts index db5a497a30869..740cf3a7b716c 100644 --- a/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts +++ b/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts @@ -8,10 +8,7 @@ import type { RequestHandler } from '@kbn/core/server'; import type { TypeOf } from '@kbn/config-schema'; -import type { - PostAgentUnenrollResponse, - PostBulkAgentUnenrollResponse, -} from '../../../common/types'; +import type { PostAgentUnenrollResponse } from '../../../common/types'; import type { PostAgentUnenrollRequestSchema, PostBulkAgentUnenrollRequestSchema, @@ -59,15 +56,8 @@ export const postBulkAgentsUnenrollHandler: RequestHandler< force: request.body?.force, batchSize: request.body?.batchSize, }); - const body = results.items.reduce((acc, so) => { - acc[so.id] = { - success: !so.error, - error: so.error?.message, - }; - return acc; - }, {}); - return response.ok({ body: { ...body, actionId: results.actionId } }); + return response.ok({ body: { actionId: results.actionId } }); } catch (error) { return defaultFleetErrorHandler({ error, response }); } diff --git a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts index 43a3987f29f60..a79edbaa36856 100644 --- a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts +++ b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts @@ -11,11 +11,7 @@ import type { TypeOf } from '@kbn/config-schema'; import semverCoerce from 'semver/functions/coerce'; import semverGt from 'semver/functions/gt'; -import type { - PostAgentUpgradeResponse, - PostBulkAgentUpgradeResponse, - GetCurrentUpgradesResponse, -} from '../../../common/types'; +import type { PostAgentUpgradeResponse, GetCurrentUpgradesResponse } from '../../../common/types'; import type { PostAgentUpgradeRequestSchema, PostBulkAgentUpgradeRequestSchema } from '../../types'; import * as AgentService from '../../services/agents'; import { appContextService } from '../../services'; @@ -142,15 +138,8 @@ export const postBulkAgentsUpgradeHandler: RequestHandler< batchSize, }; const results = await AgentService.sendUpgradeAgentsActions(soClient, esClient, upgradeOptions); - const body = results.items.reduce((acc, so) => { - acc[so.id] = { - success: !so.error, - error: so.error?.message, - }; - return acc; - }, {}); - - return response.ok({ body: { ...body, actionId: results.actionId } }); + + return response.ok({ body: { actionId: results.actionId } }); } catch (error) { return defaultFleetErrorHandler({ error, response }); } diff --git a/x-pack/plugins/fleet/server/services/agents/action_runner.ts b/x-pack/plugins/fleet/server/services/agents/action_runner.ts index d46c88728e341..2d6e1cf9cbec4 100644 --- a/x-pack/plugins/fleet/server/services/agents/action_runner.ts +++ b/x-pack/plugins/fleet/server/services/agents/action_runner.ts @@ -14,7 +14,7 @@ import { isResponseError } from '@kbn/es-errors'; import moment from 'moment'; -import type { Agent, BulkActionResult } from '../../types'; +import type { Agent } from '../../types'; import { appContextService } from '..'; import { SO_SEARCH_LIMIT } from '../../../common/constants'; @@ -65,7 +65,7 @@ export abstract class ActionRunner { protected abstract getTaskType(): string; - protected abstract processAgents(agents: Agent[]): Promise<{ items: BulkActionResult[] }>; + protected abstract processAgents(agents: Agent[]): Promise<{ actionId: string }>; /** * Common runner logic accross all agent bulk actions @@ -73,7 +73,7 @@ export abstract class ActionRunner { * On errors, starts a task with Task Manager to retry max 3 times * If the last batch was stored in state, retry continues from there (searchAfter) */ - public async runActionAsyncWithRetry(): Promise<{ items: BulkActionResult[]; actionId: string }> { + public async runActionAsyncWithRetry(): Promise<{ actionId: string }> { appContextService .getLogger() .info( @@ -131,7 +131,7 @@ export abstract class ActionRunner { }) ); - return { items: [], actionId: this.actionParams.actionId! }; + return { actionId: this.actionParams.actionId! }; } private async createCheckResultTask() { @@ -146,7 +146,7 @@ export abstract class ActionRunner { ); } - private async processBatch(agents: Agent[]): Promise<{ items: BulkActionResult[] }> { + private async processBatch(agents: Agent[]): Promise<{ actionId: string }> { if (this.retryParams.retryCount) { try { const actions = await getAgentActions(this.esClient, this.actionParams!.actionId!); @@ -154,7 +154,7 @@ export abstract class ActionRunner { // skipping batch if there is already an action document present with last agent ids for (const action of actions) { if (action.agents?.[0] === agents[0].id) { - return { items: [] }; + return { actionId: this.actionParams.actionId! }; } } } catch (error) { @@ -165,7 +165,7 @@ export abstract class ActionRunner { return await this.processAgents(agents); } - async processAgentsInBatches(): Promise<{ items: BulkActionResult[] }> { + async processAgentsInBatches(): Promise<{ actionId: string }> { const start = Date.now(); const pitId = this.retryParams.pitId; @@ -188,10 +188,10 @@ export abstract class ActionRunner { appContextService .getLogger() .debug('currentAgents returned 0 hits, returning from bulk action query'); - return { items: [] }; // stop executing if there are no more results + return { actionId: this.actionParams.actionId! }; // stop executing if there are no more results } - let results = await this.processBatch(currentAgents); + await this.processBatch(currentAgents); let allAgentsProcessed = currentAgents.length; while (allAgentsProcessed < res.total) { @@ -205,8 +205,7 @@ export abstract class ActionRunner { .debug('currentAgents returned 0 hits, returning from bulk action query'); break; // stop executing if there are no more results } - const currentResults = await this.processBatch(currentAgents); - results = { items: results.items.concat(currentResults.items) }; + await this.processBatch(currentAgents); allAgentsProcessed += currentAgents.length; if (this.checkTaskId) { // updating check task with latest checkpoint (this.retryParams.searchAfter) @@ -220,6 +219,6 @@ export abstract class ActionRunner { appContextService .getLogger() .info(`processed ${allAgentsProcessed} agents, took ${Date.now() - start}ms`); - return { ...results }; + return { actionId: this.actionParams.actionId! }; } } diff --git a/x-pack/plugins/fleet/server/services/agents/crud.test.ts b/x-pack/plugins/fleet/server/services/agents/crud.test.ts index c6d63b35ac7be..bee3d9fef09fc 100644 --- a/x-pack/plugins/fleet/server/services/agents/crud.test.ts +++ b/x-pack/plugins/fleet/server/services/agents/crud.test.ts @@ -9,7 +9,7 @@ import type { ElasticsearchClient } from '@kbn/core/server'; import type { Agent } from '../../types'; -import { errorsToResults, getAgentsByKuery, getAgentTags } from './crud'; +import { getAgentsByKuery, getAgentTags } from './crud'; jest.mock('../../../common/services/is_agent_upgradeable', () => ({ isAgentUpgradeable: jest.fn().mockImplementation((agent: Agent) => agent.id.includes('up')), @@ -292,38 +292,4 @@ describe('Agents CRUD test', () => { ]); }); }); - - describe('errorsToResults', () => { - it('should transform errors to results', () => { - const results = errorsToResults([{ id: '1' } as Agent, { id: '2' } as Agent], { - '1': new Error('error'), - }); - expect(results).toEqual([ - { id: '1', success: false, error: new Error('error') }, - { id: '2', success: true }, - ]); - }); - - it('should transform errors to results with skip success', () => { - const results = errorsToResults( - [{ id: '1' } as Agent, { id: '2' } as Agent], - { '1': new Error('error') }, - undefined, - true - ); - expect(results).toEqual([{ id: '1', success: false, error: new Error('error') }]); - }); - - it('should transform errors to results preserve order', () => { - const results = errorsToResults( - [{ id: '1' } as Agent, { id: '2' } as Agent], - { '1': new Error('error') }, - ['2', '1'] - ); - expect(results).toEqual([ - { id: '2', success: true }, - { id: '1', success: false, error: new Error('error') }, - ]); - }); - }); }); diff --git a/x-pack/plugins/fleet/server/services/agents/crud.ts b/x-pack/plugins/fleet/server/services/agents/crud.ts index 7b3af0c77e626..305bf2b6bacb4 100644 --- a/x-pack/plugins/fleet/server/services/agents/crud.ts +++ b/x-pack/plugins/fleet/server/services/agents/crud.ts @@ -250,34 +250,6 @@ export async function getAgentsByKuery( }; } -export function errorsToResults( - agents: Agent[], - errors: Record, - agentIds?: string[], - skipSuccess?: boolean -): BulkActionResult[] { - if (!skipSuccess) { - const givenOrder = agentIds ? agentIds : agents.map((agent) => agent.id); - return givenOrder.map((agentId) => { - const hasError = agentId in errors; - const result: BulkActionResult = { - id: agentId, - success: !hasError, - }; - if (hasError) { - result.error = errors[agentId]; - } - return result; - }); - } else { - return Object.entries(errors).map(([agentId, error]) => ({ - id: agentId, - success: false, - error, - })); - } -} - export async function getAllAgentsByKuery( esClient: ElasticsearchClient, options: Omit & { diff --git a/x-pack/plugins/fleet/server/services/agents/reassign.ts b/x-pack/plugins/fleet/server/services/agents/reassign.ts index c04a5b3b9ad3e..6a81606697228 100644 --- a/x-pack/plugins/fleet/server/services/agents/reassign.ts +++ b/x-pack/plugins/fleet/server/services/agents/reassign.ts @@ -8,7 +8,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { SavedObjectsClientContract, ElasticsearchClient } from '@kbn/core/server'; import Boom from '@hapi/boom'; -import type { Agent, BulkActionResult } from '../../types'; +import type { Agent } from '../../types'; import { agentPolicyService } from '../agent_policy'; import { AgentReassignmentError, HostedAgentPolicyRestrictionRelatedError } from '../../errors'; @@ -89,7 +89,7 @@ export async function reassignAgents( batchSize?: number; }, newAgentPolicyId: string -): Promise<{ items: BulkActionResult[]; actionId?: string }> { +): Promise<{ actionId: string }> { const newAgentPolicy = await agentPolicyService.get(soClient, newAgentPolicyId); if (!newAgentPolicy) { throw Boom.notFound(`Agent policy not found: ${newAgentPolicyId}`); @@ -141,12 +141,5 @@ export async function reassignAgents( } } - return await reassignBatch( - soClient, - esClient, - { newAgentPolicyId }, - givenAgents, - outgoingErrors, - 'agentIds' in options ? options.agentIds : undefined - ); + return await reassignBatch(soClient, esClient, { newAgentPolicyId }, givenAgents, outgoingErrors); } diff --git a/x-pack/plugins/fleet/server/services/agents/reassign_action_runner.ts b/x-pack/plugins/fleet/server/services/agents/reassign_action_runner.ts index 8724a68d330e7..55c0e00728d16 100644 --- a/x-pack/plugins/fleet/server/services/agents/reassign_action_runner.ts +++ b/x-pack/plugins/fleet/server/services/agents/reassign_action_runner.ts @@ -7,7 +7,7 @@ import uuid from 'uuid'; import type { SavedObjectsClientContract, ElasticsearchClient } from '@kbn/core/server'; -import type { Agent, BulkActionResult } from '../../types'; +import type { Agent } from '../../types'; import { AgentReassignmentError, HostedAgentPolicyRestrictionRelatedError } from '../../errors'; @@ -15,22 +15,14 @@ import { appContextService } from '../app_context'; import { ActionRunner } from './action_runner'; -import { errorsToResults, bulkUpdateAgents } from './crud'; +import { bulkUpdateAgents } from './crud'; import { bulkCreateAgentActionResults, createAgentAction } from './actions'; import { getHostedPolicies, isHostedAgent } from './hosted_agent'; import { BulkActionTaskType } from './bulk_actions_resolver'; export class ReassignActionRunner extends ActionRunner { - protected async processAgents(agents: Agent[]): Promise<{ items: BulkActionResult[] }> { - return await reassignBatch( - this.soClient, - this.esClient, - this.actionParams! as any, - agents, - {}, - undefined, - true - ); + protected async processAgents(agents: Agent[]): Promise<{ actionId: string }> { + return await reassignBatch(this.soClient, this.esClient, this.actionParams! as any, agents, {}); } protected getTaskType() { @@ -51,10 +43,8 @@ export async function reassignBatch( total?: number; }, givenAgents: Agent[], - outgoingErrors: Record, - agentIds?: string[], - skipSuccess?: boolean -): Promise<{ items: BulkActionResult[] }> { + outgoingErrors: Record +): Promise<{ actionId: string }> { const errors: Record = { ...outgoingErrors }; const hostedPolicies = await getHostedPolicies(soClient, givenAgents); @@ -74,14 +64,12 @@ export async function reassignBatch( return agents; }, []); - const result = { items: errorsToResults(givenAgents, errors, agentIds, skipSuccess) }; - if (agentsToUpdate.length === 0) { // early return if all agents failed validation appContextService .getLogger() .debug('No agents to update, skipping agent update and action creation'); - return result; + throw new AgentReassignmentError('No agents to reassign, already assigned or hosted agents'); } await bulkUpdateAgents( @@ -129,5 +117,5 @@ export async function reassignBatch( ); } - return result; + return { actionId }; } diff --git a/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts b/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts index d96e8b89d2fc1..79612b0bcbf06 100644 --- a/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts +++ b/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts @@ -223,21 +223,7 @@ describe('unenrollAgents (plural)', () => { agentIds: idsToUnenroll, revoke: true, }); - - expect(unenrolledResponse.items).toMatchObject([ - { - id: 'agent-in-regular-policy', - success: true, - }, - { - id: 'agent-in-hosted-policy', - success: false, - }, - { - id: 'agent-in-regular-policy2', - success: true, - }, - ]); + expect(unenrolledResponse.actionId).toBeDefined(); // calls ES update with correct values const onlyRegular = [agentInRegularDoc._id, agentInRegularDoc2._id]; @@ -301,20 +287,7 @@ describe('unenrollAgents (plural)', () => { force: true, }); - expect(unenrolledResponse.items).toMatchObject([ - { - id: 'agent-in-regular-policy', - success: true, - }, - { - id: 'agent-in-hosted-policy', - success: true, - }, - { - id: 'agent-in-regular-policy2', - success: true, - }, - ]); + expect(unenrolledResponse.actionId).toBeDefined(); // calls ES update with correct values const calledWith = esClient.bulk.mock.calls[1][0]; diff --git a/x-pack/plugins/fleet/server/services/agents/unenroll.ts b/x-pack/plugins/fleet/server/services/agents/unenroll.ts index f7c49f3efcf1c..078b9ce3aef37 100644 --- a/x-pack/plugins/fleet/server/services/agents/unenroll.ts +++ b/x-pack/plugins/fleet/server/services/agents/unenroll.ts @@ -9,7 +9,7 @@ import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/ import uuid from 'uuid'; -import type { Agent, BulkActionResult } from '../../types'; +import type { Agent } from '../../types'; import { HostedAgentPolicyRestrictionRelatedError } from '../../errors'; import { SO_SEARCH_LIMIT } from '../../constants'; @@ -74,7 +74,7 @@ export async function unenrollAgents( revoke?: boolean; batchSize?: number; } -): Promise<{ items: BulkActionResult[]; actionId?: string }> { +): Promise<{ actionId: string }> { if ('agentIds' in options) { const givenAgents = await getAgents(esClient, options); return await unenrollBatch(soClient, esClient, givenAgents, options); diff --git a/x-pack/plugins/fleet/server/services/agents/unenroll_action_runner.ts b/x-pack/plugins/fleet/server/services/agents/unenroll_action_runner.ts index f9ba2e4be44a1..dd5b4e023c2a3 100644 --- a/x-pack/plugins/fleet/server/services/agents/unenroll_action_runner.ts +++ b/x-pack/plugins/fleet/server/services/agents/unenroll_action_runner.ts @@ -11,7 +11,7 @@ import { intersection } from 'lodash'; import { AGENT_ACTIONS_RESULTS_INDEX } from '../../../common'; -import type { Agent, BulkActionResult } from '../../types'; +import type { Agent } from '../../types'; import { FleetError, HostedAgentPolicyRestrictionRelatedError } from '../../errors'; @@ -21,7 +21,7 @@ import { appContextService } from '../app_context'; import { ActionRunner } from './action_runner'; -import { errorsToResults, bulkUpdateAgents } from './crud'; +import { bulkUpdateAgents } from './crud'; import { bulkCreateAgentActionResults, createAgentAction, @@ -31,8 +31,8 @@ import { getHostedPolicies, isHostedAgent } from './hosted_agent'; import { BulkActionTaskType } from './bulk_actions_resolver'; export class UnenrollActionRunner extends ActionRunner { - protected async processAgents(agents: Agent[]): Promise<{ items: BulkActionResult[] }> { - return await unenrollBatch(this.soClient, this.esClient, agents, this.actionParams!, true); + protected async processAgents(agents: Agent[]): Promise<{ actionId: string }> { + return await unenrollBatch(this.soClient, this.esClient, agents, this.actionParams!); } protected getTaskType() { @@ -60,9 +60,8 @@ export async function unenrollBatch( revoke?: boolean; actionId?: string; total?: number; - }, - skipSuccess?: boolean -): Promise<{ items: BulkActionResult[] }> { + } +): Promise<{ actionId: string }> { const hostedPolicies = await getHostedPolicies(soClient, givenAgents); const outgoingErrors: Record = {}; @@ -134,7 +133,7 @@ export async function unenrollBatch( ); return { - items: errorsToResults(givenAgents, outgoingErrors, undefined, skipSuccess), + actionId, }; } diff --git a/x-pack/plugins/fleet/server/services/agents/update_agent_tags.ts b/x-pack/plugins/fleet/server/services/agents/update_agent_tags.ts index 4496e16cbc476..a8c5496a6b028 100644 --- a/x-pack/plugins/fleet/server/services/agents/update_agent_tags.ts +++ b/x-pack/plugins/fleet/server/services/agents/update_agent_tags.ts @@ -8,7 +8,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; -import type { Agent, BulkActionResult } from '../../types'; +import type { Agent } from '../../types'; import { AgentReassignmentError } from '../../errors'; import { SO_SEARCH_LIMIT } from '../../constants'; @@ -28,7 +28,7 @@ export async function updateAgentTags( options: ({ agents: Agent[] } | GetAgentsOptions) & { batchSize?: number }, tagsToAdd: string[], tagsToRemove: string[] -): Promise<{ items: BulkActionResult[]; actionId?: string }> { +): Promise<{ actionId: string }> { const outgoingErrors: Record = {}; let givenAgents: Agent[] = []; @@ -69,12 +69,8 @@ export async function updateAgentTags( } } - return await updateTagsBatch( - soClient, - esClient, - givenAgents, - outgoingErrors, - { tagsToAdd, tagsToRemove }, - 'agentIds' in options ? options.agentIds : undefined - ); + return await updateTagsBatch(soClient, esClient, givenAgents, outgoingErrors, { + tagsToAdd, + tagsToRemove, + }); } diff --git a/x-pack/plugins/fleet/server/services/agents/update_agent_tags_action_runner.ts b/x-pack/plugins/fleet/server/services/agents/update_agent_tags_action_runner.ts index 807f2ab1cf073..48f7b455d36b7 100644 --- a/x-pack/plugins/fleet/server/services/agents/update_agent_tags_action_runner.ts +++ b/x-pack/plugins/fleet/server/services/agents/update_agent_tags_action_runner.ts @@ -9,19 +9,19 @@ import type { SavedObjectsClientContract, ElasticsearchClient } from '@kbn/core/ import uuid from 'uuid'; import { difference, uniq } from 'lodash'; -import type { Agent, BulkActionResult } from '../../types'; +import type { Agent } from '../../types'; import { appContextService } from '../app_context'; import { ActionRunner } from './action_runner'; -import { errorsToResults, bulkUpdateAgents } from './crud'; +import { bulkUpdateAgents } from './crud'; import { BulkActionTaskType } from './bulk_actions_resolver'; import { filterHostedPolicies } from './filter_hosted_agents'; import { bulkCreateAgentActionResults, createAgentAction } from './actions'; export class UpdateAgentTagsActionRunner extends ActionRunner { - protected async processAgents(agents: Agent[]): Promise<{ items: BulkActionResult[] }> { + protected async processAgents(agents: Agent[]): Promise<{ actionId: string }> { return await updateTagsBatch( this.soClient, this.esClient, @@ -32,9 +32,7 @@ export class UpdateAgentTagsActionRunner extends ActionRunner { tagsToRemove: this.actionParams?.tagsToRemove, actionId: this.actionParams.actionId, total: this.actionParams.total, - }, - undefined, - true + } ); } @@ -57,10 +55,8 @@ export async function updateTagsBatch( tagsToRemove: string[]; actionId?: string; total?: number; - }, - agentIds?: string[], - skipSuccess?: boolean -): Promise<{ items: BulkActionResult[] }> { + } +): Promise<{ actionId: string }> { const errors: Record = { ...outgoingErrors }; const filteredAgents = await filterHostedPolicies( @@ -135,5 +131,5 @@ export async function updateTagsBatch( ); } - return { items: errorsToResults(filteredAgents, errors, agentIds, skipSuccess) }; + return { actionId }; } diff --git a/x-pack/plugins/fleet/server/services/agents/upgrade.ts b/x-pack/plugins/fleet/server/services/agents/upgrade.ts index b6c50a3b5dc3c..cf298ecb5997d 100644 --- a/x-pack/plugins/fleet/server/services/agents/upgrade.ts +++ b/x-pack/plugins/fleet/server/services/agents/upgrade.ts @@ -7,7 +7,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; -import type { Agent, BulkActionResult } from '../../types'; +import type { Agent } from '../../types'; import { AgentReassignmentError, HostedAgentPolicyRestrictionRelatedError } from '../../errors'; import { SO_SEARCH_LIMIT } from '../../constants'; @@ -73,7 +73,7 @@ export async function sendUpgradeAgentsActions( startTime?: string; batchSize?: number; } -): Promise<{ items: BulkActionResult[]; actionId?: string }> { +): Promise<{ actionId: string }> { // Full set of agents const outgoingErrors: Record = {}; let givenAgents: Agent[] = []; diff --git a/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts b/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts index 28c1ec3d26007..c757a9f1b5482 100644 --- a/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts +++ b/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts @@ -12,7 +12,7 @@ import uuid from 'uuid'; import { isAgentUpgradeable } from '../../../common/services'; -import type { Agent, BulkActionResult } from '../../types'; +import type { Agent } from '../../types'; import { HostedAgentPolicyRestrictionRelatedError, FleetError } from '../../errors'; @@ -21,21 +21,14 @@ import { appContextService } from '../app_context'; import { ActionRunner } from './action_runner'; import type { GetAgentsOptions } from './crud'; -import { errorsToResults, bulkUpdateAgents } from './crud'; +import { bulkUpdateAgents } from './crud'; import { bulkCreateAgentActionResults, createAgentAction } from './actions'; import { getHostedPolicies, isHostedAgent } from './hosted_agent'; import { BulkActionTaskType } from './bulk_actions_resolver'; export class UpgradeActionRunner extends ActionRunner { - protected async processAgents(agents: Agent[]): Promise<{ items: BulkActionResult[] }> { - return await upgradeBatch( - this.soClient, - this.esClient, - agents, - {}, - this.actionParams! as any, - true - ); + protected async processAgents(agents: Agent[]): Promise<{ actionId: string }> { + return await upgradeBatch(this.soClient, this.esClient, agents, {}, this.actionParams! as any); } protected getTaskType() { @@ -60,9 +53,8 @@ export async function upgradeBatch( upgradeDurationSeconds?: number; startTime?: string; total?: number; - }, - skipSuccess?: boolean -): Promise<{ items: BulkActionResult[] }> { + } +): Promise<{ actionId: string }> { const errors: Record = { ...outgoingErrors }; const hostedPolicies = await getHostedPolicies(soClient, givenAgents); @@ -161,12 +153,7 @@ export async function upgradeBatch( ); return { - items: errorsToResults( - givenAgents, - errors, - 'agentIds' in options ? options.agentIds : undefined, - skipSuccess - ), + actionId, }; } diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 1066277da776f..1e9bf2a737964 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -12510,9 +12510,7 @@ "xpack.fleet.unenrollAgents.forceDeleteMultipleTitle": "Désenregistrer {count} agents", "xpack.fleet.unenrollAgents.forceUnenrollCheckboxLabel": "Supprimer {count, plural, one {l'agent} other {les agents}} immédiatement. N'attendez pas que l'agent envoie les dernières données.", "xpack.fleet.unenrollAgents.forceUnenrollLegendText": "Forcer le désenregistrement {count, plural, one {de l'agent} other {des agents}}", - "xpack.fleet.upgradeAgents.bulkResultErrorResultsSummary": "Échec de {count} {count, plural, one {agent} other {agents}}", "xpack.fleet.upgradeAgents.hourLabel": "{option} {count, plural, one {heure} other {heures}}", - "xpack.fleet.upgradeAgents.successSingleNotificationTitle": "Mise à niveau de l'agent {count}", "xpack.fleet.upgradeAgents.upgradeMultipleDescription": "Cette action met à niveau plusieurs agents vers la version {version}. Impossible d'annuler cette action. Voulez-vous vraiment continuer ?", "xpack.fleet.upgradeAgents.upgradeSingleDescription": "Cette action met à niveau l'agent qui s'exécute sur \"{hostName}\" vers la version {version}. Impossible d'annuler cette action. Voulez-vous vraiment continuer ?", "xpack.fleet.upgradeAgents.warningCallout": "Les mises à niveau propagées sont uniquement disponible pour Elastic Agent à partir de la version {version}.", @@ -13415,7 +13413,6 @@ "xpack.fleet.unenrollAgents.unenrollFleetServerTitle": "Cet agent exécute le serveur Fleet", "xpack.fleet.updateAgentTags.errorNotificationTitle": "Échec de la mise à jour des balises", "xpack.fleet.updateAgentTags.successNotificationTitle": "Balises mises à jour", - "xpack.fleet.upgradeAgents.bulkResultAllErrorsNotificationTitle": "Erreur lors de la mise à niveau de {count, plural, one {l'agent} other {{count} agents} =true {tous les agents sélectionnés}}", "xpack.fleet.upgradeAgents.cancelButtonLabel": "Annuler", "xpack.fleet.upgradeAgents.chooseVersionLabel": "Mettre à niveau la version", "xpack.fleet.upgradeAgents.confirmMultipleButtonLabel": "Mettre à niveau {count, plural, one {l'agent} other {{count} agents} =true {tous les agents sélectionnés}}", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index e077421392645..493f2b2e7a885 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -12496,9 +12496,7 @@ "xpack.fleet.unenrollAgents.forceDeleteMultipleTitle": "{count}個のエージェントを登録解除", "xpack.fleet.unenrollAgents.forceUnenrollCheckboxLabel": "{count, plural, other {エージェント}}を直ちに削除します。エージェントが最後のデータを送信するまで待機しない。", "xpack.fleet.unenrollAgents.forceUnenrollLegendText": "{count, plural, other {エージェント}}を強制的に登録解除", - "xpack.fleet.upgradeAgents.bulkResultErrorResultsSummary": "{count} {count, plural, other {個のエージェント}}が成功しませんでした", "xpack.fleet.upgradeAgents.hourLabel": "{option} {count, plural, other {時間}}", - "xpack.fleet.upgradeAgents.successSingleNotificationTitle": "{count}個のエージェントをアップグレードしています", "xpack.fleet.upgradeAgents.upgradeMultipleDescription": "このアクションにより、複数のエージェントがバージョン{version}にアップグレードされます。このアクションは元に戻せません。続行していいですか?", "xpack.fleet.upgradeAgents.upgradeSingleDescription": "このアクションにより、「{hostName}」で実行中のエージェントがバージョン{version}にアップグレードされます。このアクションは元に戻せません。続行していいですか?", "xpack.fleet.upgradeAgents.warningCallout": "ローリングアップグレードは、Elasticエージェントバージョン{version}以降でのみ使用できます", @@ -13401,7 +13399,6 @@ "xpack.fleet.unenrollAgents.unenrollFleetServerTitle": "このエージェントはFleetサーバーを実行しています", "xpack.fleet.updateAgentTags.errorNotificationTitle": "タグの更新が失敗しました", "xpack.fleet.updateAgentTags.successNotificationTitle": "タグが更新されました", - "xpack.fleet.upgradeAgents.bulkResultAllErrorsNotificationTitle": "{count, plural, other {{count}個のエージェント} =true {すべての選択されたエージェント}}のアップグレードエラー", "xpack.fleet.upgradeAgents.cancelButtonLabel": "キャンセル", "xpack.fleet.upgradeAgents.chooseVersionLabel": "バージョンのアップグレード", "xpack.fleet.upgradeAgents.confirmMultipleButtonLabel": "{count, plural, other {{count}個のエージェント} =true {すべての選択されたエージェント}}をアップグレード", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 41c4320dae010..45552726be4e8 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -12513,9 +12513,7 @@ "xpack.fleet.unenrollAgents.forceDeleteMultipleTitle": "取消注册 {count} 个代理", "xpack.fleet.unenrollAgents.forceUnenrollCheckboxLabel": "立即移除{count, plural, other {代理}}。不用等待代理发送任何最终数据。", "xpack.fleet.unenrollAgents.forceUnenrollLegendText": "强制取消注册{count, plural, other {代理}}", - "xpack.fleet.upgradeAgents.bulkResultErrorResultsSummary": "{count} 个{count, plural, other {代理}}未成功", "xpack.fleet.upgradeAgents.hourLabel": "{option} {count, plural, other {小时}}", - "xpack.fleet.upgradeAgents.successSingleNotificationTitle": "正在升级 {count} 个代理", "xpack.fleet.upgradeAgents.upgradeMultipleDescription": "此操作会将多个代理升级到版本 {version}。此操作无法撤消。是否确定要继续?", "xpack.fleet.upgradeAgents.upgradeSingleDescription": "此操作会将“{hostName}”上运行的代理升级到版本 {version}。此操作无法撤消。是否确定要继续?", "xpack.fleet.upgradeAgents.warningCallout": "滚动升级仅适用于 Elastic 代理版本 {version} 及更高版本", @@ -13418,7 +13416,6 @@ "xpack.fleet.unenrollAgents.unenrollFleetServerTitle": "此代理正在运行 Fleet 服务器", "xpack.fleet.updateAgentTags.errorNotificationTitle": "标签更新失败", "xpack.fleet.updateAgentTags.successNotificationTitle": "标签已更新", - "xpack.fleet.upgradeAgents.bulkResultAllErrorsNotificationTitle": "升级{count, plural, one {代理} other { {count} 个代理} =true {所有选定代理}}时出错", "xpack.fleet.upgradeAgents.cancelButtonLabel": "取消", "xpack.fleet.upgradeAgents.chooseVersionLabel": "升级版本", "xpack.fleet.upgradeAgents.confirmMultipleButtonLabel": "升级{count, plural, one {代理} other { {count} 个代理} =true {所有选定代理}}", diff --git a/x-pack/test/fleet_api_integration/apis/agents/reassign.ts b/x-pack/test/fleet_api_integration/apis/agents/reassign.ts index 746a2fcda1ba1..1283c9433ebba 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/reassign.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/reassign.ts @@ -107,7 +107,7 @@ export default function (providerContext: FtrProviderContext) { }); it('should allow to reassign multiple agents by id -- mix valid & invalid', async () => { - const { body } = await supertest + await supertest .post(`/api/fleet/agents/bulk_reassign`) .set('kbn-xsrf', 'xxx') .send({ @@ -115,23 +115,6 @@ export default function (providerContext: FtrProviderContext) { policy_id: 'policy2', }); - expect(body).to.eql({ - agent2: { success: true }, - INVALID_ID: { - success: false, - error: 'Cannot find agent INVALID_ID', - }, - agent3: { success: true }, - MISSING_ID: { - success: false, - error: 'Cannot find agent MISSING_ID', - }, - etc: { - success: false, - error: 'Cannot find agent etc', - }, - }); - const [agent2data, agent3data] = await Promise.all([ supertest.get(`/api/fleet/agents/agent2`), supertest.get(`/api/fleet/agents/agent3`), @@ -148,7 +131,7 @@ export default function (providerContext: FtrProviderContext) { .send({ name: 'Test policy', namespace: 'default', is_managed: true }) .expect(200); - const { body } = await supertest + await supertest .post(`/api/fleet/agents/bulk_reassign`) .set('kbn-xsrf', 'xxx') .send({ @@ -156,23 +139,6 @@ export default function (providerContext: FtrProviderContext) { policy_id: 'policy2', }); - expect(body).to.eql({ - agent2: { - success: false, - error: - 'Cannot reassign an agent from hosted agent policy policy1 in Fleet because the agent policy is managed by an external orchestration solution, such as Elastic Cloud, Kubernetes, etc. Please make changes using your orchestration solution.', - }, - INVALID_ID: { - success: false, - error: 'Cannot find agent INVALID_ID', - }, - agent3: { - success: false, - error: - 'Cannot reassign an agent from hosted agent policy policy1 in Fleet because the agent policy is managed by an external orchestration solution, such as Elastic Cloud, Kubernetes, etc. Please make changes using your orchestration solution.', - }, - }); - const [agent2data, agent3data] = await Promise.all([ supertest.get(`/api/fleet/agents/agent2`), supertest.get(`/api/fleet/agents/agent3`), diff --git a/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts b/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts index 058fccfb376d8..fe31806038a5c 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts @@ -120,7 +120,7 @@ export default function (providerContext: FtrProviderContext) { .expect(200); // try to unenroll - const { body: unenrolledBody } = await supertest + await supertest .post(`/api/fleet/agents/bulk_unenroll`) .set('kbn-xsrf', 'xxx') .send({ @@ -129,18 +129,6 @@ export default function (providerContext: FtrProviderContext) { // http request succeeds .expect(200); - expect(unenrolledBody).to.eql({ - agent2: { - success: false, - error: - 'Cannot unenroll agent2 from a hosted agent policy policy1 in Fleet because the agent policy is managed by an external orchestration solution, such as Elastic Cloud, Kubernetes, etc. Please make changes using your orchestration solution.', - }, - agent3: { - success: false, - error: - 'Cannot unenroll agent3 from a hosted agent policy policy1 in Fleet because the agent policy is managed by an external orchestration solution, such as Elastic Cloud, Kubernetes, etc. Please make changes using your orchestration solution.', - }, - }); // but agents are still enrolled const [agent2data, agent3data] = await Promise.all([ supertest.get(`/api/fleet/agents/agent2`), @@ -161,18 +149,13 @@ export default function (providerContext: FtrProviderContext) { .set('kbn-xsrf', 'xxx') .send({ name: 'Test policy', namespace: 'default', is_managed: false }) .expect(200); - const { body: unenrolledBody } = await supertest + await supertest .post(`/api/fleet/agents/bulk_unenroll`) .set('kbn-xsrf', 'xxx') .send({ agents: ['agent2', 'agent3'], }); - expect(unenrolledBody).to.eql({ - agent2: { success: true }, - agent3: { success: true }, - }); - const [agent2data, agent3data] = await Promise.all([ supertest.get(`/api/fleet/agents/agent2`), supertest.get(`/api/fleet/agents/agent3`), diff --git a/x-pack/test/fleet_api_integration/apis/agents/update_agent_tags.ts b/x-pack/test/fleet_api_integration/apis/agents/update_agent_tags.ts index afe9f8d677d35..88079ae5e1aff 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/update_agent_tags.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/update_agent_tags.ts @@ -140,7 +140,7 @@ export default function (providerContext: FtrProviderContext) { }); // attempt to update tags of agent in hosted agent policy - const { body } = await supertest + await supertest .post(`/api/fleet/agents/bulk_update_agent_tags`) .set('kbn-xsrf', 'xxx') .send({ @@ -149,14 +149,6 @@ export default function (providerContext: FtrProviderContext) { }) .expect(200); - expect(body).to.eql({ - agent1: { - success: false, - error: `Cannot modify tags on a hosted agent in Fleet because the agent policy is managed by an external orchestration solution, such as Elastic Cloud, Kubernetes, etc. Please make changes using your orchestration solution.`, - }, - agent2: { success: true }, - }); - const [agent1data, agent2data] = await Promise.all([ supertest.get(`/api/fleet/agents/agent1`), supertest.get(`/api/fleet/agents/agent2`), diff --git a/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts b/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts index e941752f5f1b6..e2762e21f33ad 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts @@ -1016,7 +1016,7 @@ export default function (providerContext: FtrProviderContext) { }, }); // attempt to upgrade agent in hosted agent policy - const { body } = await supertest + await supertest .post(`/api/fleet/agents/bulk_upgrade`) .set('kbn-xsrf', 'xxx') .send({ @@ -1025,15 +1025,6 @@ export default function (providerContext: FtrProviderContext) { }) .expect(200); - expect(body).to.eql({ - agent1: { - success: false, - error: - 'Cannot upgrade agent in hosted agent policy policy1 in Fleet because the agent policy is managed by an external orchestration solution, such as Elastic Cloud, Kubernetes, etc. Please make changes using your orchestration solution.', - }, - agent2: { success: true }, - }); - const [agent1data, agent2data] = await Promise.all([ supertest.get(`/api/fleet/agents/agent1`), supertest.get(`/api/fleet/agents/agent2`), @@ -1076,7 +1067,7 @@ export default function (providerContext: FtrProviderContext) { }, }); // attempt to upgrade agent in hosted agent policy - const { body } = await supertest + await supertest .post(`/api/fleet/agents/bulk_upgrade`) .set('kbn-xsrf', 'xxx') .send({ @@ -1085,11 +1076,6 @@ export default function (providerContext: FtrProviderContext) { force: true, }); - expect(body).to.eql({ - agent1: { success: true }, - agent2: { success: true }, - }); - const [agent1data, agent2data] = await Promise.all([ supertest.get(`/api/fleet/agents/agent1`), supertest.get(`/api/fleet/agents/agent2`), From 5f8f1e55638d2d68ad41469619506159139dac82 Mon Sep 17 00:00:00 2001 From: Ashokaditya <1849116+ashokaditya@users.noreply.github.com> Date: Tue, 27 Sep 2022 10:50:27 +0200 Subject: [PATCH 47/51] [Security Solution][Endpoint][Response Actions] Update table pagination header colour (#141847) fixes elastic/security-team/issues/5042 --- .../endpoint_response_actions_list/response_actions_log.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx index d7b923dec5058..bea5a3eb07aaf 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx @@ -597,7 +597,7 @@ export const ResponseActionsLog = memo< // create range label to display const recordRangeLabel = useMemo( () => ( - + Date: Tue, 27 Sep 2022 10:27:10 +0100 Subject: [PATCH 48/51] skip failing test (#141901) --- .../tests/services/sorted_and_filtered_services.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/apm_api_integration/tests/services/sorted_and_filtered_services.spec.ts b/x-pack/test/apm_api_integration/tests/services/sorted_and_filtered_services.spec.ts index fdc1e84cddfc3..f084f8cdca187 100644 --- a/x-pack/test/apm_api_integration/tests/services/sorted_and_filtered_services.spec.ts +++ b/x-pack/test/apm_api_integration/tests/services/sorted_and_filtered_services.spec.ts @@ -50,7 +50,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { type ServiceListItem = ValuesType>>; - registry.when('Sorted and filtered services', { config: 'trial', archives: [] }, () => { + registry.when.skip('Sorted and filtered services', { config: 'trial', archives: [] }, () => { before(async () => { const serviceA = apm .service({ name: SERVICE_NAME_PREFIX + 'a', environment: 'production', agentName: 'java' }) From 405997e47ffb56b4df034bbd8cbbbacdc918409c Mon Sep 17 00:00:00 2001 From: Klim Markelov Date: Tue, 27 Sep 2022 11:30:34 +0200 Subject: [PATCH 49/51] Fix analytics js file path on integration screen (#141892) --- .../analytics_collection_integrate.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.tsx b/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.tsx index 36b527097a304..47f0f161263af 100644 --- a/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/analytics/components/analytics_collection_view/analytics_collection_integrate.tsx @@ -49,7 +49,7 @@ export const AnalyticsCollectionIntegrate: React.FC From ead1cf386d75c75cabc5470c02ad7cd86e9403d5 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Tue, 27 Sep 2022 12:45:06 +0200 Subject: [PATCH 50/51] [Files] Update the download method on the files client (#141904) * update the download method on the files client * rather link to FileJSON --- x-pack/plugins/files/public/types.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/files/public/types.ts b/x-pack/plugins/files/public/types.ts index ac5ec40c2c252..25aab6e787b6b 100644 --- a/x-pack/plugins/files/public/types.ts +++ b/x-pack/plugins/files/public/types.ts @@ -117,8 +117,10 @@ export interface FilesClient extends GlobalEndpoints { /** * Get a string for downloading a file that can be passed to a button element's * href for download. + * + * @param args - get download URL args */ - getDownloadHref: (file: FileJSON) => string; + getDownloadHref: (args: Pick) => string; /** * Share a file by creating a new file share instance. * From 3edba25c2dacc0a80d712cbe4334d3c65eb090a6 Mon Sep 17 00:00:00 2001 From: Tre Date: Tue, 27 Sep 2022 12:03:01 +0100 Subject: [PATCH 51/51] [Archive Migration] x-pack-banners/multispace (#135783) * [Archive Migration] x-pack-banners/multispace I've the before() fn loading the new kbn archive containing one config, for the default space. Then, the fn creates a new space and changes the ui settings of this new space, w/o using an archive. * Move to enabled per: https://github.com/elastic/kibana/pull/135783#issuecomment-1237228021 * Just run my stuff this go-round. * Fixup. * Drop new archive, re-enable all tests, skip the last test, and add the filed bugs. * Whoops * Drop redundant test. * Not sure what's what yet, but I think perhaps an override is occuring. * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * Change value in test and config. * Drop double quotes, seems to have caused parsing issue. * One more try before asking in kibana-core * try snake case * back to space case but without quotes in the config * Just to see what happens I guess. * Merge fixups. * Change refs of "global_banner_text" to "global banner text" * Stop the shell expansion * Drop duplicate. Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- scripts/archive_migration_functions.sh | 22 +- src/dev/build/tasks/bin/scripts/kibana | 2 +- .../banners/server/ui_settings.test.ts | 6 +- x-pack/test/banners_functional/config.ts | 2 +- .../test/banners_functional/tests/global.ts | 2 +- .../test/banners_functional/tests/spaces.ts | 23 +- .../es_archives/banners/multispace/data.json | 62 ----- .../banners/multispace/mappings.json | 248 ------------------ 8 files changed, 23 insertions(+), 344 deletions(-) delete mode 100644 x-pack/test/functional/es_archives/banners/multispace/data.json delete mode 100644 x-pack/test/functional/es_archives/banners/multispace/mappings.json diff --git a/scripts/archive_migration_functions.sh b/scripts/archive_migration_functions.sh index a37d52a1417c7..7dcba01175731 100755 --- a/scripts/archive_migration_functions.sh +++ b/scripts/archive_migration_functions.sh @@ -1,27 +1,13 @@ -#!/bin/bash - -# ??? Should we migrate -# x-pack/test/functional/es_archives/logstash/example_pipelines -# !!! No, we've found 0 saved objects that are listed in the standard_list -# !!! It contains the following saved object(s) -# config -# space - standard_list="url,index-pattern,query,graph-workspace,tag,visualization,canvas-element,canvas-workpad,dashboard,search,lens,map,cases,uptime-dynamic-settings,osquery-saved-query,osquery-pack,infrastructure-ui-source,metrics-explorer-view,inventory-view,infrastructure-monitoring-log-view,apm-indices" -orig_archive="x-pack/test/functional/es_archives/spaces/multi_space" -new_archive="x-pack/test/functional/fixtures/kbn_archiver/spaces/multi_space" +orig_archive="x-pack/test/functional/es_archives/banners/multispace" +new_archive="x-pack/test/functional/fixtures/kbn_archiver/banners/multi_space" # newArchives=("x-pack/test/functional/fixtures/kbn_archiver/dashboard/session_in_space") -# newArchives+=("x-pack/test/functional/fixtures/kbn_archiver/dashboard/session_in_another_space") -testFiles=("x-pack/test/functional/apps/discover/preserve_url.ts") -testFiles+=("x-pack/test/functional/apps/visualize/preserve_url.ts") -testFiles+=("x-pack/test/functional/apps/dashboard/group1/preserve_url.ts") +# testFiles=("x-pack/test/functional/apps/discover/preserve_url.ts") -test_config="x-pack/test/functional/apps/dashboard/group1/config.ts" -# test_config="x-pack/test/functional/apps/discover/config.ts" -# test_config="x-pack/test/functional/apps/visualize/config.ts" +test_config="x-pack/test/banners_functional/config.ts" list_stragglers() { diff --git a/src/dev/build/tasks/bin/scripts/kibana b/src/dev/build/tasks/bin/scripts/kibana index a4fc5385500b5..f96fac236b55c 100755 --- a/src/dev/build/tasks/bin/scripts/kibana +++ b/src/dev/build/tasks/bin/scripts/kibana @@ -26,4 +26,4 @@ if [ -f "${CONFIG_DIR}/node.options" ]; then KBN_NODE_OPTS="$(grep -v ^# < ${CONFIG_DIR}/node.options | xargs)" fi -NODE_OPTIONS="--no-warnings --max-http-header-size=65536 $KBN_NODE_OPTS $NODE_OPTIONS" NODE_ENV=production exec "${NODE}" "${DIR}/src/cli/dist" ${@} +NODE_OPTIONS="--no-warnings --max-http-header-size=65536 $KBN_NODE_OPTS $NODE_OPTIONS" NODE_ENV=production exec "${NODE}" "${DIR}/src/cli/dist" "${@}" diff --git a/x-pack/plugins/banners/server/ui_settings.test.ts b/x-pack/plugins/banners/server/ui_settings.test.ts index f83ef6f4bba59..10cf250cc7468 100644 --- a/x-pack/plugins/banners/server/ui_settings.test.ts +++ b/x-pack/plugins/banners/server/ui_settings.test.ts @@ -13,7 +13,7 @@ const createConfig = (parts: Partial = {}): BannersConfigType placement: 'disabled', backgroundColor: '#0000', textColor: '#FFFFFF', - textContent: 'Hello from the banner', + textContent: 'some global banner text', disableSpaceBanners: false, ...parts, }); @@ -31,7 +31,9 @@ describe('registerSettings', () => { expect(uiSettings.register).toHaveBeenCalledTimes(1); expect(uiSettings.register).toHaveBeenCalledWith({ 'banners:placement': expect.any(Object), - 'banners:textContent': expect.any(Object), + 'banners:textContent': expect.objectContaining({ + value: 'some global banner text', + }), 'banners:textColor': expect.any(Object), 'banners:backgroundColor': expect.any(Object), }); diff --git a/x-pack/test/banners_functional/config.ts b/x-pack/test/banners_functional/config.ts index 2280cf11cfbf2..83d0c4656572c 100644 --- a/x-pack/test/banners_functional/config.ts +++ b/x-pack/test/banners_functional/config.ts @@ -35,7 +35,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { serverArgs: [ ...kibanaFunctionalConfig.get('kbnTestServer.serverArgs'), '--xpack.banners.placement=top', - '--xpack.banners.textContent=global_banner_text', + '--xpack.banners.textContent="global banner text"', ], }, }; diff --git a/x-pack/test/banners_functional/tests/global.ts b/x-pack/test/banners_functional/tests/global.ts index a36d98589163a..cef404d7ed132 100644 --- a/x-pack/test/banners_functional/tests/global.ts +++ b/x-pack/test/banners_functional/tests/global.ts @@ -16,7 +16,7 @@ export default function ({ getPageObjects }: FtrProviderContext) { await PageObjects.common.navigateToApp('login'); expect(await PageObjects.banners.isTopBannerVisible()).to.eql(true); - expect(await PageObjects.banners.getTopBannerText()).to.eql('global_banner_text'); + expect(await PageObjects.banners.getTopBannerText()).to.eql('global banner text'); }); }); } diff --git a/x-pack/test/banners_functional/tests/spaces.ts b/x-pack/test/banners_functional/tests/spaces.ts index 43c9612fa5696..2ec7d0939b100 100644 --- a/x-pack/test/banners_functional/tests/spaces.ts +++ b/x-pack/test/banners_functional/tests/spaces.ts @@ -9,7 +9,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../ftr_provider_context'; export default function ({ getPageObjects, getService }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); + const spacesService = getService('spaces'); const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects([ 'common', @@ -21,14 +21,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { describe('per-spaces banners', () => { before(async () => { - await esArchiver.load('x-pack/test/functional/es_archives/banners/multispace'); - }); - - after(async () => { - await esArchiver.unload('x-pack/test/functional/es_archives/banners/multispace'); - }); - - before(async () => { + await spacesService.create({ + id: 'another-space', + name: 'Another Space', + disabledFeatures: [], + }); await kibanaServer.uiSettings.replace( { 'banners:textContent': 'default space banner text', @@ -39,6 +36,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expectSpaceSelector: true, }); }); + after(async () => { + await spacesService.delete('another-space'); + await kibanaServer.savedObjects.cleanStandardList(); + }); it('displays the space-specific banner within the space', async () => { await PageObjects.common.navigateToApp('home'); @@ -51,7 +52,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await PageObjects.common.navigateToApp('home', { basePath: '/s/another-space' }); expect(await PageObjects.banners.isTopBannerVisible()).to.eql(true); - expect(await PageObjects.banners.getTopBannerText()).to.eql('global_banner_text'); + expect(await PageObjects.banners.getTopBannerText()).to.eql('global banner text'); }); it('displays the global banner on the login page', async () => { @@ -59,7 +60,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await PageObjects.common.navigateToApp('login'); expect(await PageObjects.banners.isTopBannerVisible()).to.eql(true); - expect(await PageObjects.banners.getTopBannerText()).to.eql('global_banner_text'); + expect(await PageObjects.banners.getTopBannerText()).to.eql('global banner text'); }); }); } diff --git a/x-pack/test/functional/es_archives/banners/multispace/data.json b/x-pack/test/functional/es_archives/banners/multispace/data.json deleted file mode 100644 index fc0e0dc7b7eee..0000000000000 --- a/x-pack/test/functional/es_archives/banners/multispace/data.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "type": "doc", - "value": { - "id": "config:6.0.0", - "index": ".kibana", - "source": { - "config": { - "buildNum": 8467, - "dateFormat:tz": "UTC", - "defaultRoute": "http://example.com/evil" - }, - "type": "config" - } - } -} - -{ - "type": "doc", - "value": { - "id": "another-space:config:6.0.0", - "index": ".kibana", - "source": { - "namespace": "another-space", - "config": { - "buildNum": 8467, - "dateFormat:tz": "UTC", - "defaultRoute": "/app/canvas" - }, - "type": "config" - } - } -} - -{ - "type": "doc", - "value": { - "id": "space:default", - "index": ".kibana", - "source": { - "space": { - "description": "This is the default space!", - "name": "Default" - }, - "type": "space" - } - } -} - -{ - "type": "doc", - "value": { - "id": "space:another-space", - "index": ".kibana", - "source": { - "space": { - "description": "This is another space", - "name": "Another Space" - }, - "type": "space" - } - } -} diff --git a/x-pack/test/functional/es_archives/banners/multispace/mappings.json b/x-pack/test/functional/es_archives/banners/multispace/mappings.json deleted file mode 100644 index f813fca64c328..0000000000000 --- a/x-pack/test/functional/es_archives/banners/multispace/mappings.json +++ /dev/null @@ -1,248 +0,0 @@ -{ - "type": "index", - "value": { - "aliases": { - ".kibana": {} - }, - "index": ".kibana_1", - "mappings": { - "properties": { - "config": { - "dynamic": "true", - "properties": { - "buildNum": { - "type": "keyword" - }, - "dateFormat:tz": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "defaultRoute": { - "type": "keyword" - } - } - }, - "dashboard": { - "dynamic": "strict", - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } - } - }, - "optionsJSON": { - "type": "text" - }, - "panelsJSON": { - "type": "text" - }, - "refreshInterval": { - "properties": { - "display": { - "type": "keyword" - }, - "pause": { - "type": "boolean" - }, - "section": { - "type": "integer" - }, - "value": { - "type": "integer" - } - } - }, - "timeFrom": { - "type": "keyword" - }, - "timeRestore": { - "type": "boolean" - }, - "timeTo": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "index-pattern": { - "dynamic": "strict", - "properties": { - "fieldFormatMap": { - "type": "text" - }, - "fields": { - "type": "text" - }, - "intervalName": { - "type": "keyword" - }, - "notExpandable": { - "type": "boolean" - }, - "sourceFilters": { - "type": "text" - }, - "timeFieldName": { - "type": "keyword" - }, - "title": { - "type": "text" - } - } - }, - "search": { - "dynamic": "strict", - "properties": { - "columns": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } - } - }, - "sort": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "server": { - "dynamic": "strict", - "properties": { - "uuid": { - "type": "keyword" - } - } - }, - "space": { - "properties": { - "_reserved": { - "type": "boolean" - }, - "color": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "disabledFeatures": { - "type": "keyword" - }, - "initials": { - "type": "keyword" - }, - "name": { - "fields": { - "keyword": { - "ignore_above": 2048, - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "spaceId": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "url": { - "dynamic": "strict", - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "fields": { - "keyword": { - "ignore_above": 2048, - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "visualization": { - "dynamic": "strict", - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } - } - }, - "savedSearchId": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "type": "text" - } - } - } - } - }, - "settings": { - "index": { - "number_of_replicas": "1", - "number_of_shards": "1" - } - } - } -}